@geoffcox/sterling-svelte 0.0.12 → 0.0.14
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.
- package/{lists → containers}/List.svelte +34 -39
- package/{lists → containers}/List.svelte.d.ts +21 -12
- package/containers/ListItem.svelte +48 -0
- package/containers/ListItem.svelte.d.ts +26 -0
- package/containers/Tree.constants.d.ts +2 -0
- package/containers/Tree.constants.js +2 -0
- package/containers/Tree.svelte +222 -0
- package/containers/Tree.svelte.d.ts +50 -0
- package/containers/Tree.types.d.ts +47 -0
- package/containers/Tree.types.js +1 -0
- package/containers/TreeChevron.svelte +109 -0
- package/containers/TreeChevron.svelte.d.ts +17 -0
- package/containers/TreeItem.svelte +96 -0
- package/containers/TreeItem.svelte.d.ts +60 -0
- package/containers/TreeNode.svelte +267 -0
- package/containers/TreeNode.svelte.d.ts +43 -0
- package/display/Progress.svelte +9 -7
- package/index.d.ts +10 -4
- package/index.js +6 -4
- package/inputs/Input.svelte +10 -8
- package/inputs/Select.svelte +21 -19
- package/inputs/Select.svelte.d.ts +16 -12
- package/inputs/Slider.svelte +4 -6
- package/inputs/TextArea.svelte +154 -0
- package/inputs/TextArea.svelte.d.ts +50 -0
- package/inputs/TextArea.types.d.ts +1 -0
- package/inputs/TextArea.types.js +1 -0
- package/package.json +11 -2
- package/surfaces/Dialog.svelte +0 -2
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<script>import { onMount } from "svelte";
|
|
2
|
+
export let expanded = false;
|
|
3
|
+
export let hasChildren = false;
|
|
4
|
+
let lastValue = expanded;
|
|
5
|
+
let mounted = false;
|
|
6
|
+
onMount(() => {
|
|
7
|
+
setTimeout(() => {
|
|
8
|
+
mounted = true;
|
|
9
|
+
}, 10);
|
|
10
|
+
});
|
|
11
|
+
let animate = false;
|
|
12
|
+
$: {
|
|
13
|
+
if (expanded !== lastValue && mounted) {
|
|
14
|
+
animate = true;
|
|
15
|
+
}
|
|
16
|
+
lastValue = expanded;
|
|
17
|
+
}
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<div class="tree-chevron" class:leaf={!hasChildren} class:animate class:expanded />
|
|
21
|
+
|
|
22
|
+
<style>
|
|
23
|
+
.tree-chevron {
|
|
24
|
+
position: relative;
|
|
25
|
+
border: none;
|
|
26
|
+
background: none;
|
|
27
|
+
height: 1em;
|
|
28
|
+
width: 1em;
|
|
29
|
+
transform-origin: 50% 50%;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.tree-chevron::after {
|
|
33
|
+
position: absolute;
|
|
34
|
+
content: '';
|
|
35
|
+
top: 50%;
|
|
36
|
+
left: 50%;
|
|
37
|
+
width: 7px;
|
|
38
|
+
height: 7px;
|
|
39
|
+
border-right: 3px solid currentColor;
|
|
40
|
+
border-top: 3px solid currentColor;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
:not(.expanded):not(.animate)::after {
|
|
44
|
+
transform: translate(-50%, -50%) rotate(45deg);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.expanded:not(.animate)::after {
|
|
48
|
+
transform: translate(-50%, -70%) rotate(135deg);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@keyframes rotate-collapse {
|
|
52
|
+
from {
|
|
53
|
+
transform: translate(-50%, -70%) rotate(135deg);
|
|
54
|
+
}
|
|
55
|
+
to {
|
|
56
|
+
transform: translate(-50%, -50%) rotate(45deg);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@keyframes rotate-expand {
|
|
61
|
+
from {
|
|
62
|
+
transform: translate(-50%, -50%) rotate(45deg);
|
|
63
|
+
}
|
|
64
|
+
to {
|
|
65
|
+
transform: translate(-50%, -70%) rotate(135deg);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
:not(.expanded).animate::after {
|
|
70
|
+
animation-name: rotate-collapse;
|
|
71
|
+
animation-duration: 100ms;
|
|
72
|
+
animation-iteration-count: 1;
|
|
73
|
+
animation-timing-function: linear;
|
|
74
|
+
animation-fill-mode: forwards;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.expanded.animate::after {
|
|
78
|
+
animation-name: rotate-expand;
|
|
79
|
+
animation-duration: 100ms;
|
|
80
|
+
animation-iteration-count: 1;
|
|
81
|
+
animation-timing-function: linear;
|
|
82
|
+
animation-fill-mode: forwards;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.tree-chevron.leaf::after {
|
|
86
|
+
animation: none;
|
|
87
|
+
content: '';
|
|
88
|
+
position: absolute;
|
|
89
|
+
font: inherit;
|
|
90
|
+
left: 50%;
|
|
91
|
+
top: 50%;
|
|
92
|
+
width: 0.35em;
|
|
93
|
+
height: 0.35em;
|
|
94
|
+
background: currentColor;
|
|
95
|
+
border-radius: 50%;
|
|
96
|
+
transform: translate(-50%, -50%);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@media (prefers-reduced-motion) {
|
|
100
|
+
:not(.expanded).animate::after {
|
|
101
|
+
animation: none;
|
|
102
|
+
transform: translate(-50%, -50%) rotate(45deg);
|
|
103
|
+
}
|
|
104
|
+
.expanded.animate::after {
|
|
105
|
+
animation: none;
|
|
106
|
+
transform: translate(-50%, -70%) rotate(135deg);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
</style>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
expanded?: boolean | undefined;
|
|
5
|
+
hasChildren?: boolean | undefined;
|
|
6
|
+
};
|
|
7
|
+
events: {
|
|
8
|
+
[evt: string]: CustomEvent<any>;
|
|
9
|
+
};
|
|
10
|
+
slots: {};
|
|
11
|
+
};
|
|
12
|
+
export type TreeChevronProps = typeof __propDef.props;
|
|
13
|
+
export type TreeChevronEvents = typeof __propDef.events;
|
|
14
|
+
export type TreeChevronSlots = typeof __propDef.slots;
|
|
15
|
+
export default class TreeChevron extends SvelteComponentTyped<TreeChevronProps, TreeChevronEvents, TreeChevronSlots> {
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<script>import TreeChevron from "./TreeChevron.svelte";
|
|
2
|
+
export let depth = 0;
|
|
3
|
+
export let disabled = false;
|
|
4
|
+
export let expanded = false;
|
|
5
|
+
export let hasChildren = false;
|
|
6
|
+
export let selected = false;
|
|
7
|
+
export let nodeId;
|
|
8
|
+
export let node = void 0;
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<div
|
|
12
|
+
class="sterling-tree-node-item"
|
|
13
|
+
class:disabled
|
|
14
|
+
class:expanded
|
|
15
|
+
class:selected
|
|
16
|
+
style={`--sterling-tree-node-depth: ${depth}`}
|
|
17
|
+
on:blur
|
|
18
|
+
on:click
|
|
19
|
+
on:dblclick
|
|
20
|
+
on:focus
|
|
21
|
+
on:focusin
|
|
22
|
+
on:focusout
|
|
23
|
+
on:keydown
|
|
24
|
+
on:keypress
|
|
25
|
+
on:keyup
|
|
26
|
+
on:mousedown
|
|
27
|
+
on:mouseenter
|
|
28
|
+
on:mouseleave
|
|
29
|
+
on:mousemove
|
|
30
|
+
on:mouseover
|
|
31
|
+
on:mouseout
|
|
32
|
+
on:mouseup
|
|
33
|
+
on:pointercancel
|
|
34
|
+
on:pointerdown
|
|
35
|
+
on:pointerenter
|
|
36
|
+
on:pointerleave
|
|
37
|
+
on:pointermove
|
|
38
|
+
on:pointerover
|
|
39
|
+
on:pointerout
|
|
40
|
+
on:pointerup
|
|
41
|
+
on:wheel
|
|
42
|
+
{...$$restProps}
|
|
43
|
+
>
|
|
44
|
+
<TreeChevron {expanded} {hasChildren} />
|
|
45
|
+
<slot {depth} {disabled} {expanded} {hasChildren} {selected} {node} {nodeId} />
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<style>
|
|
49
|
+
.sterling-tree-node-item {
|
|
50
|
+
align-content: center;
|
|
51
|
+
align-items: center;
|
|
52
|
+
background-color: transparent;
|
|
53
|
+
box-sizing: border-box;
|
|
54
|
+
color: var(--Input__color);
|
|
55
|
+
display: grid;
|
|
56
|
+
grid-template-columns: auto 1fr;
|
|
57
|
+
column-gap: 0.25em;
|
|
58
|
+
margin: 0;
|
|
59
|
+
outline: none;
|
|
60
|
+
padding: 0.5em;
|
|
61
|
+
padding-left: calc(0.5em * var(--sterling-tree-node-depth));
|
|
62
|
+
text-overflow: ellipsis;
|
|
63
|
+
transition: background-color 250ms, color 250ms, border-color 250ms;
|
|
64
|
+
white-space: nowrap;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.sterling-tree-node-item:hover {
|
|
68
|
+
background-color: var(--Button__background-color--hover);
|
|
69
|
+
color: var(--Button__color--hover);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.sterling-tree-node-item.selected {
|
|
73
|
+
background-color: var(--Input__background-color--selected);
|
|
74
|
+
color: var(--Input__color--selected);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.sterling-tree-node-item.disabled {
|
|
78
|
+
color: var(--Input__color--disabled);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.sterling-tree-node-item.leaf {
|
|
82
|
+
border: none;
|
|
83
|
+
background: currentColor;
|
|
84
|
+
border-radius: 50%;
|
|
85
|
+
height: 0.5em;
|
|
86
|
+
width: 0.5em;
|
|
87
|
+
margin: 0.5;
|
|
88
|
+
transform-origin: 50% 50%;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@media (prefers-reduced-motion) {
|
|
92
|
+
.sterling-tree-node-item {
|
|
93
|
+
transition: none;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
</style>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import type { TreeNodeData } from './Tree.types';
|
|
3
|
+
declare class __sveltets_Render<T> {
|
|
4
|
+
props(): {
|
|
5
|
+
[x: string]: any;
|
|
6
|
+
depth?: number | undefined;
|
|
7
|
+
disabled?: boolean | undefined;
|
|
8
|
+
expanded?: boolean | undefined;
|
|
9
|
+
hasChildren?: boolean | undefined;
|
|
10
|
+
selected?: boolean | undefined;
|
|
11
|
+
nodeId: string;
|
|
12
|
+
node?: TreeNodeData<T> | undefined;
|
|
13
|
+
};
|
|
14
|
+
events(): {
|
|
15
|
+
blur: FocusEvent;
|
|
16
|
+
click: MouseEvent;
|
|
17
|
+
dblclick: MouseEvent;
|
|
18
|
+
focus: FocusEvent;
|
|
19
|
+
focusin: FocusEvent;
|
|
20
|
+
focusout: FocusEvent;
|
|
21
|
+
keydown: KeyboardEvent;
|
|
22
|
+
keypress: KeyboardEvent;
|
|
23
|
+
keyup: KeyboardEvent;
|
|
24
|
+
mousedown: MouseEvent;
|
|
25
|
+
mouseenter: MouseEvent;
|
|
26
|
+
mouseleave: MouseEvent;
|
|
27
|
+
mousemove: MouseEvent;
|
|
28
|
+
mouseover: MouseEvent;
|
|
29
|
+
mouseout: MouseEvent;
|
|
30
|
+
mouseup: MouseEvent;
|
|
31
|
+
pointercancel: PointerEvent;
|
|
32
|
+
pointerdown: PointerEvent;
|
|
33
|
+
pointerenter: PointerEvent;
|
|
34
|
+
pointerleave: PointerEvent;
|
|
35
|
+
pointermove: PointerEvent;
|
|
36
|
+
pointerover: PointerEvent;
|
|
37
|
+
pointerout: PointerEvent;
|
|
38
|
+
pointerup: PointerEvent;
|
|
39
|
+
wheel: WheelEvent;
|
|
40
|
+
} & {
|
|
41
|
+
[evt: string]: CustomEvent<any>;
|
|
42
|
+
};
|
|
43
|
+
slots(): {
|
|
44
|
+
default: {
|
|
45
|
+
depth: number;
|
|
46
|
+
disabled: boolean;
|
|
47
|
+
expanded: boolean;
|
|
48
|
+
hasChildren: boolean;
|
|
49
|
+
selected: boolean;
|
|
50
|
+
node: TreeNodeData<T> | undefined;
|
|
51
|
+
nodeId: string;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export type TreeItemProps<T> = ReturnType<__sveltets_Render<T>['props']>;
|
|
56
|
+
export type TreeItemEvents<T> = ReturnType<__sveltets_Render<T>['events']>;
|
|
57
|
+
export type TreeItemSlots<T> = ReturnType<__sveltets_Render<T>['slots']>;
|
|
58
|
+
export default class TreeItem<T> extends SvelteComponentTyped<TreeItemProps<T>, TreeItemEvents<T>, TreeItemSlots<T>> {
|
|
59
|
+
}
|
|
60
|
+
export {};
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
<script>import { getContext, setContext } from "svelte";
|
|
2
|
+
import { slide } from "svelte/transition";
|
|
3
|
+
import { treeContextKey, treeNodeContextKey } from "./Tree.constants";
|
|
4
|
+
import TreeItem from "./TreeItem.svelte";
|
|
5
|
+
export let disabled = false;
|
|
6
|
+
export let nodeId;
|
|
7
|
+
export let node = void 0;
|
|
8
|
+
const { getNodeId, expandedNodeIds, selectedNodeId, selectedNodeEventHandlers } = getContext(treeContextKey);
|
|
9
|
+
const { parentNodeId, depth } = getContext(treeNodeContextKey);
|
|
10
|
+
if (nodeId && node) {
|
|
11
|
+
if (nodeId !== getNodeId(node)) {
|
|
12
|
+
throw new Error("The nodeId does not match node.nodeId.");
|
|
13
|
+
}
|
|
14
|
+
} else if (node) {
|
|
15
|
+
nodeId = getNodeId(node);
|
|
16
|
+
} else if (!nodeId) {
|
|
17
|
+
throw new Error("Both nodeId and node are missing.");
|
|
18
|
+
}
|
|
19
|
+
setContext("sterlingTreeNode", { parentNodeId: nodeId, depth: depth + 1 });
|
|
20
|
+
let treeNodeRef;
|
|
21
|
+
let itemRef;
|
|
22
|
+
$:
|
|
23
|
+
hasChildren = (node?.children?.length || 0) > 0 || $$slots.children || $$slots.default;
|
|
24
|
+
$:
|
|
25
|
+
expanded = $expandedNodeIds.includes(nodeId);
|
|
26
|
+
$:
|
|
27
|
+
selected = $selectedNodeId === nodeId;
|
|
28
|
+
const collapseNode = (index) => {
|
|
29
|
+
if (!disabled) {
|
|
30
|
+
index = index ?? $expandedNodeIds.findIndex((id) => id === nodeId);
|
|
31
|
+
if (index !== -1) {
|
|
32
|
+
expandedNodeIds.set([
|
|
33
|
+
...$expandedNodeIds.slice(0, index),
|
|
34
|
+
...$expandedNodeIds.slice(index + 1)
|
|
35
|
+
]);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const expandNode = (index) => {
|
|
40
|
+
if (!disabled) {
|
|
41
|
+
index = index ?? $expandedNodeIds.findIndex((id) => id === nodeId);
|
|
42
|
+
if (index === -1) {
|
|
43
|
+
expandedNodeIds.set([...$expandedNodeIds, nodeId]);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const toggleExpanded = () => {
|
|
48
|
+
if (!disabled) {
|
|
49
|
+
const index = $expandedNodeIds.findIndex((id) => id === nodeId);
|
|
50
|
+
index !== -1 ? collapseNode(index) : expandNode(index);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const selectNodeById = (nodeId2) => {
|
|
54
|
+
if (!disabled) {
|
|
55
|
+
selectedNodeId.set(nodeId2);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
export const selectNode = () => {
|
|
59
|
+
if (!disabled) {
|
|
60
|
+
selectNodeById(nodeId);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const selectParentNode = () => {
|
|
64
|
+
if (!disabled && parentNodeId) {
|
|
65
|
+
selectNodeById(parentNodeId);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const selectNextNode = () => {
|
|
69
|
+
if (!disabled) {
|
|
70
|
+
let nextNodeId = void 0;
|
|
71
|
+
const decendants = treeNodeRef.getElementsByClassName("sterling-tree-node");
|
|
72
|
+
const last = decendants.length > 0 ? decendants.item(0) : void 0;
|
|
73
|
+
nextNodeId = last?.getAttribute("data-node-id");
|
|
74
|
+
if (!nextNodeId) {
|
|
75
|
+
nextNodeId = treeNodeRef.nextElementSibling?.getAttribute("data-node-id");
|
|
76
|
+
}
|
|
77
|
+
if (!nextNodeId) {
|
|
78
|
+
let ancestor = treeNodeRef.closest(".sterling-tree-node");
|
|
79
|
+
while (ancestor && !nextNodeId) {
|
|
80
|
+
nextNodeId = ancestor?.nextElementSibling?.getAttribute("data-node-id");
|
|
81
|
+
ancestor = ancestor.parentElement?.closest(".sterling-tree-node");
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (nextNodeId) {
|
|
85
|
+
selectNodeById(nextNodeId);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const selectPreviousNode = () => {
|
|
90
|
+
if (!disabled) {
|
|
91
|
+
let prevNodeId = void 0;
|
|
92
|
+
const previousSibling = treeNodeRef?.previousElementSibling;
|
|
93
|
+
if (previousSibling) {
|
|
94
|
+
const decendants = previousSibling.getElementsByClassName("sterling-tree-node");
|
|
95
|
+
const last = decendants.length > 0 ? decendants.item(decendants.length - 1) : previousSibling;
|
|
96
|
+
prevNodeId = last?.getAttribute("data-node-id");
|
|
97
|
+
}
|
|
98
|
+
if (!prevNodeId) {
|
|
99
|
+
prevNodeId = parentNodeId;
|
|
100
|
+
}
|
|
101
|
+
if (prevNodeId) {
|
|
102
|
+
selectNodeById(prevNodeId);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
const onItemClick = () => {
|
|
107
|
+
console.log("onItemClick");
|
|
108
|
+
toggleExpanded();
|
|
109
|
+
selectNode();
|
|
110
|
+
};
|
|
111
|
+
const onKeydown = (event) => {
|
|
112
|
+
if (!event.altKey && !event.ctrlKey && !event.shiftKey) {
|
|
113
|
+
switch (event.key) {
|
|
114
|
+
case "Enter":
|
|
115
|
+
case " ":
|
|
116
|
+
toggleExpanded();
|
|
117
|
+
event.preventDefault();
|
|
118
|
+
return false;
|
|
119
|
+
case "ArrowRight":
|
|
120
|
+
if (!expanded && hasChildren) {
|
|
121
|
+
expandNode();
|
|
122
|
+
} else {
|
|
123
|
+
selectNextNode();
|
|
124
|
+
}
|
|
125
|
+
event.preventDefault();
|
|
126
|
+
return false;
|
|
127
|
+
case "ArrowLeft":
|
|
128
|
+
if (expanded && hasChildren) {
|
|
129
|
+
collapseNode();
|
|
130
|
+
} else if (parentNodeId) {
|
|
131
|
+
selectParentNode();
|
|
132
|
+
} else {
|
|
133
|
+
selectPreviousNode();
|
|
134
|
+
}
|
|
135
|
+
event.preventDefault();
|
|
136
|
+
return false;
|
|
137
|
+
case "ArrowUp":
|
|
138
|
+
selectPreviousNode();
|
|
139
|
+
event.preventDefault();
|
|
140
|
+
return false;
|
|
141
|
+
case "ArrowDown":
|
|
142
|
+
selectNextNode();
|
|
143
|
+
event.preventDefault();
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
$: {
|
|
149
|
+
if (selected) {
|
|
150
|
+
selectedNodeEventHandlers.set({ onKeydown });
|
|
151
|
+
treeNodeRef?.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "nearest" });
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
</script>
|
|
155
|
+
|
|
156
|
+
<!--
|
|
157
|
+
@component
|
|
158
|
+
A node in a Tree displaying the item and children.
|
|
159
|
+
-->
|
|
160
|
+
<div
|
|
161
|
+
aria-selected={selected ? true : undefined}
|
|
162
|
+
aria-expanded={expanded}
|
|
163
|
+
class="sterling-tree-node"
|
|
164
|
+
class:disabled
|
|
165
|
+
bind:this={treeNodeRef}
|
|
166
|
+
data-node-id={nodeId}
|
|
167
|
+
role="treeitem"
|
|
168
|
+
>
|
|
169
|
+
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
170
|
+
<div bind:this={itemRef} class="item" class:selected on:click={onItemClick}>
|
|
171
|
+
<slot name="item" {disabled} {expanded} {hasChildren} {depth} {node} {nodeId} {selected}>
|
|
172
|
+
<TreeItem {disabled} {expanded} {hasChildren} {depth} {node} {nodeId} {selected}>
|
|
173
|
+
<svelte:fragment
|
|
174
|
+
let:disabled
|
|
175
|
+
let:expanded
|
|
176
|
+
let:hasChildren
|
|
177
|
+
let:depth
|
|
178
|
+
let:node
|
|
179
|
+
let:nodeId
|
|
180
|
+
let:selected
|
|
181
|
+
>
|
|
182
|
+
<slot name="label" {disabled} {expanded} {hasChildren} {depth} {node} {nodeId} {selected}
|
|
183
|
+
>{nodeId}</slot
|
|
184
|
+
>
|
|
185
|
+
</svelte:fragment>
|
|
186
|
+
</TreeItem>
|
|
187
|
+
</slot>
|
|
188
|
+
</div>
|
|
189
|
+
{#if expanded && hasChildren}
|
|
190
|
+
<div class="children" transition:slide={{ duration: 200 }} role="group">
|
|
191
|
+
<slot name="children">
|
|
192
|
+
{#if node?.children}
|
|
193
|
+
{#each node.children as child}
|
|
194
|
+
<svelte:self {disabled} node={child} nodeId={child.nodeId}>
|
|
195
|
+
<!--
|
|
196
|
+
Forward the item slot into each tree node.
|
|
197
|
+
It is cleanest to have a fragment for the TreeNode item slot to
|
|
198
|
+
capture the let params, then apply them to the Tree item slot.
|
|
199
|
+
-->
|
|
200
|
+
<svelte:fragment
|
|
201
|
+
slot="item"
|
|
202
|
+
let:disabled
|
|
203
|
+
let:expanded
|
|
204
|
+
let:hasChildren
|
|
205
|
+
let:depth
|
|
206
|
+
let:node
|
|
207
|
+
let:nodeId
|
|
208
|
+
let:selected
|
|
209
|
+
>
|
|
210
|
+
<slot
|
|
211
|
+
name="item"
|
|
212
|
+
{disabled}
|
|
213
|
+
{expanded}
|
|
214
|
+
{hasChildren}
|
|
215
|
+
{depth}
|
|
216
|
+
{node}
|
|
217
|
+
{nodeId}
|
|
218
|
+
{selected}
|
|
219
|
+
>
|
|
220
|
+
<!--
|
|
221
|
+
Svelte prevents conditionally applying slots.
|
|
222
|
+
This repeats exact same item slot default for this child
|
|
223
|
+
so the item slot is passed down the tree.
|
|
224
|
+
-->
|
|
225
|
+
<TreeItem {disabled} {expanded} {hasChildren} {depth} {node} {nodeId} {selected}>
|
|
226
|
+
<svelte:fragment
|
|
227
|
+
let:disabled
|
|
228
|
+
let:expanded
|
|
229
|
+
let:hasChildren
|
|
230
|
+
let:depth
|
|
231
|
+
let:node
|
|
232
|
+
let:nodeId
|
|
233
|
+
let:selected
|
|
234
|
+
>
|
|
235
|
+
<!-- This uses the label slot for the TreeItem default slot. -->
|
|
236
|
+
<slot
|
|
237
|
+
name="label"
|
|
238
|
+
{disabled}
|
|
239
|
+
{expanded}
|
|
240
|
+
{hasChildren}
|
|
241
|
+
{depth}
|
|
242
|
+
{node}
|
|
243
|
+
{nodeId}
|
|
244
|
+
{selected}>{nodeId}</slot
|
|
245
|
+
>
|
|
246
|
+
</svelte:fragment>
|
|
247
|
+
</TreeItem>
|
|
248
|
+
</slot>
|
|
249
|
+
</svelte:fragment>
|
|
250
|
+
</svelte:self>
|
|
251
|
+
{/each}
|
|
252
|
+
{/if}
|
|
253
|
+
</slot>
|
|
254
|
+
<slot />
|
|
255
|
+
</div>
|
|
256
|
+
{/if}
|
|
257
|
+
</div>
|
|
258
|
+
|
|
259
|
+
<style>
|
|
260
|
+
.item {
|
|
261
|
+
outline: none;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.item:focus-visible {
|
|
265
|
+
border: 1px solid blue;
|
|
266
|
+
}
|
|
267
|
+
</style>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import type { TreeNodeData } from './Tree.types';
|
|
3
|
+
declare class __sveltets_Render<T> {
|
|
4
|
+
props(): {
|
|
5
|
+
disabled?: boolean | undefined;
|
|
6
|
+
nodeId: string;
|
|
7
|
+
node?: TreeNodeData<T> | undefined;
|
|
8
|
+
selectNode?: (() => void) | undefined;
|
|
9
|
+
};
|
|
10
|
+
events(): {} & {
|
|
11
|
+
[evt: string]: CustomEvent<any>;
|
|
12
|
+
};
|
|
13
|
+
slots(): {
|
|
14
|
+
item: {
|
|
15
|
+
disabled: any;
|
|
16
|
+
expanded: any;
|
|
17
|
+
hasChildren: any;
|
|
18
|
+
depth: any;
|
|
19
|
+
node: any;
|
|
20
|
+
nodeId: any;
|
|
21
|
+
selected: any;
|
|
22
|
+
};
|
|
23
|
+
label: {
|
|
24
|
+
disabled: any;
|
|
25
|
+
expanded: any;
|
|
26
|
+
hasChildren: any;
|
|
27
|
+
depth: any;
|
|
28
|
+
node: any;
|
|
29
|
+
nodeId: any;
|
|
30
|
+
selected: any;
|
|
31
|
+
};
|
|
32
|
+
children: {};
|
|
33
|
+
default: {};
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export type TreeNodeProps<T> = ReturnType<__sveltets_Render<T>['props']>;
|
|
37
|
+
export type TreeNodeEvents<T> = ReturnType<__sveltets_Render<T>['events']>;
|
|
38
|
+
export type TreeNodeSlots<T> = ReturnType<__sveltets_Render<T>['slots']>;
|
|
39
|
+
/** A node in a Tree displaying the item and children. */
|
|
40
|
+
export default class TreeNode<T> extends SvelteComponentTyped<TreeNodeProps<T>, TreeNodeEvents<T>, TreeNodeSlots<T>> {
|
|
41
|
+
get selectNode(): () => void;
|
|
42
|
+
}
|
|
43
|
+
export {};
|
package/display/Progress.svelte
CHANGED
|
@@ -54,11 +54,9 @@ $:
|
|
|
54
54
|
{...$$restProps}
|
|
55
55
|
>
|
|
56
56
|
{#if $$slots.label}
|
|
57
|
-
<
|
|
58
|
-
<
|
|
59
|
-
|
|
60
|
-
</Label>
|
|
61
|
-
</div>
|
|
57
|
+
<Label {disabled} for={inputId}>
|
|
58
|
+
<slot name="label" />
|
|
59
|
+
</Label>
|
|
62
60
|
{/if}
|
|
63
61
|
<div class="progress-bar" id={inputId}>
|
|
64
62
|
<div class="container" bind:clientWidth bind:clientHeight>
|
|
@@ -82,9 +80,13 @@ $:
|
|
|
82
80
|
align-items: flex-start;
|
|
83
81
|
}
|
|
84
82
|
|
|
85
|
-
.label {
|
|
83
|
+
.sterling-progress > :global(label) {
|
|
86
84
|
font-size: 0.7em;
|
|
87
|
-
margin: 0.5em 0;
|
|
85
|
+
margin: 0.5em 0.7em;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.sterling-progress > :global(label):empty {
|
|
89
|
+
margin: 0;
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
.progress-bar {
|
package/index.d.ts
CHANGED
|
@@ -6,18 +6,24 @@ export { darkTheme } from './theme/darkTheme';
|
|
|
6
6
|
export { lightTheme } from './theme/lightTheme';
|
|
7
7
|
export { neutrals } from './theme/colors';
|
|
8
8
|
export { toggleDarkTheme } from './theme/toggleDarkTheme';
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
9
|
+
export type { ButtonVariant, ButtonShape } from './buttons/Button.types';
|
|
10
|
+
export type { ProgressColorful } from './display/Progress.types';
|
|
11
|
+
export type { TextAreaResize } from './inputs/TextArea.types';
|
|
12
|
+
export type { TreeNodeData } from './containers/Tree.types';
|
|
11
13
|
export { clickOutside } from './clickOutside';
|
|
12
14
|
import Button from './buttons/Button.svelte';
|
|
13
15
|
import Checkbox from './inputs/Checkbox.svelte';
|
|
14
16
|
import Dialog from './surfaces/Dialog.svelte';
|
|
15
17
|
import Input from './inputs/Input.svelte';
|
|
16
18
|
import Label from './display/Label.svelte';
|
|
17
|
-
import List from './
|
|
19
|
+
import List from './containers/List.svelte';
|
|
18
20
|
import Progress from './display/Progress.svelte';
|
|
19
21
|
import Radio from './inputs/Radio.svelte';
|
|
20
22
|
import Select from './inputs/Select.svelte';
|
|
21
23
|
import Slider from './inputs/Slider.svelte';
|
|
22
24
|
import Switch from './inputs/Switch.svelte';
|
|
23
|
-
|
|
25
|
+
import TextArea from './inputs/TextArea.svelte';
|
|
26
|
+
import Tree from './containers/Tree.svelte';
|
|
27
|
+
import TreeChevron from './containers/TreeChevron.svelte';
|
|
28
|
+
import TreeItem from './containers/TreeItem.svelte';
|
|
29
|
+
export { Button, Checkbox, Dialog, Input, Label, List, Progress, Radio, Select, Slider, Switch, TextArea, Tree, TreeChevron, TreeItem };
|
package/index.js
CHANGED
|
@@ -6,18 +6,20 @@ export { darkTheme } from './theme/darkTheme';
|
|
|
6
6
|
export { lightTheme } from './theme/lightTheme';
|
|
7
7
|
export { neutrals } from './theme/colors';
|
|
8
8
|
export { toggleDarkTheme } from './theme/toggleDarkTheme';
|
|
9
|
-
export {} from './buttons/Button.types';
|
|
10
|
-
export {} from './display/Progress.types';
|
|
11
9
|
export { clickOutside } from './clickOutside';
|
|
12
10
|
import Button from './buttons/Button.svelte';
|
|
13
11
|
import Checkbox from './inputs/Checkbox.svelte';
|
|
14
12
|
import Dialog from './surfaces/Dialog.svelte';
|
|
15
13
|
import Input from './inputs/Input.svelte';
|
|
16
14
|
import Label from './display/Label.svelte';
|
|
17
|
-
import List from './
|
|
15
|
+
import List from './containers/List.svelte';
|
|
18
16
|
import Progress from './display/Progress.svelte';
|
|
19
17
|
import Radio from './inputs/Radio.svelte';
|
|
20
18
|
import Select from './inputs/Select.svelte';
|
|
21
19
|
import Slider from './inputs/Slider.svelte';
|
|
22
20
|
import Switch from './inputs/Switch.svelte';
|
|
23
|
-
|
|
21
|
+
import TextArea from './inputs/TextArea.svelte';
|
|
22
|
+
import Tree from './containers/Tree.svelte';
|
|
23
|
+
import TreeChevron from './containers/TreeChevron.svelte';
|
|
24
|
+
import TreeItem from './containers/TreeItem.svelte';
|
|
25
|
+
export { Button, Checkbox, Dialog, Input, Label, List, Progress, Radio, Select, Slider, Switch, TextArea, Tree, TreeChevron, TreeItem };
|