@deepfuture/dui-components 1.2.1 → 1.3.0
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/all.d.ts +4 -0
- package/all.js +3 -0
- package/package.json +6 -2
- package/tree/index.d.ts +6 -0
- package/tree/index.js +5 -0
- package/tree/tree-item.d.ts +5 -0
- package/tree/tree-item.js +144 -0
- package/tree/tree.d.ts +5 -0
- package/tree/tree.js +51 -0
package/all.d.ts
CHANGED
|
@@ -44,6 +44,7 @@ import "./textarea/index.js";
|
|
|
44
44
|
import "./toggle/index.js";
|
|
45
45
|
import "./toolbar/index.js";
|
|
46
46
|
import "./tooltip/index.js";
|
|
47
|
+
import "./tree/index.js";
|
|
47
48
|
import "./trunc/index.js";
|
|
48
49
|
export { DuiAccordion } from "./accordion/index.js";
|
|
49
50
|
export { DuiAccordionItem } from "./accordion/index.js";
|
|
@@ -133,6 +134,8 @@ export { DuiToolbar } from "./toolbar/index.js";
|
|
|
133
134
|
export { DuiTooltip } from "./tooltip/index.js";
|
|
134
135
|
export { DuiTooltipPopup } from "./tooltip/index.js";
|
|
135
136
|
export { DuiTooltipTrigger } from "./tooltip/index.js";
|
|
137
|
+
export { DuiTree } from "./tree/index.js";
|
|
138
|
+
export { DuiTreeItem } from "./tree/index.js";
|
|
136
139
|
export { DuiTrunc } from "./trunc/index.js";
|
|
137
140
|
export type { AccordionContext } from "@deepfuture/dui-primitives/accordion";
|
|
138
141
|
export type { AlertDialogOpenChangeDetail } from "@deepfuture/dui-primitives/alert-dialog";
|
|
@@ -159,3 +162,4 @@ export type { TextareaResize } from "@deepfuture/dui-primitives/textarea";
|
|
|
159
162
|
export type { ToggleGroupContext } from "@deepfuture/dui-primitives/toggle";
|
|
160
163
|
export type { TooltipOpenChangeDetail } from "@deepfuture/dui-primitives/tooltip";
|
|
161
164
|
export type { TooltipContext, TooltipSide } from "@deepfuture/dui-primitives/tooltip";
|
|
165
|
+
export type { SelectionMode, TreeContext } from "@deepfuture/dui-primitives/tree";
|
package/all.js
CHANGED
|
@@ -44,6 +44,7 @@ import "./textarea/index.js";
|
|
|
44
44
|
import "./toggle/index.js";
|
|
45
45
|
import "./toolbar/index.js";
|
|
46
46
|
import "./tooltip/index.js";
|
|
47
|
+
import "./tree/index.js";
|
|
47
48
|
import "./trunc/index.js";
|
|
48
49
|
export { DuiAccordion } from "./accordion/index.js";
|
|
49
50
|
export { DuiAccordionItem } from "./accordion/index.js";
|
|
@@ -133,4 +134,6 @@ export { DuiToolbar } from "./toolbar/index.js";
|
|
|
133
134
|
export { DuiTooltip } from "./tooltip/index.js";
|
|
134
135
|
export { DuiTooltipPopup } from "./tooltip/index.js";
|
|
135
136
|
export { DuiTooltipTrigger } from "./tooltip/index.js";
|
|
137
|
+
export { DuiTree } from "./tree/index.js";
|
|
138
|
+
export { DuiTreeItem } from "./tree/index.js";
|
|
136
139
|
export { DuiTrunc } from "./trunc/index.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepfuture/dui-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "DUI styled web components — extends dui-primitives with design tokens and variant CSS",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -186,6 +186,10 @@
|
|
|
186
186
|
"import": "./tooltip/index.js",
|
|
187
187
|
"types": "./tooltip/index.d.ts"
|
|
188
188
|
},
|
|
189
|
+
"./tree": {
|
|
190
|
+
"import": "./tree/index.js",
|
|
191
|
+
"types": "./tree/index.d.ts"
|
|
192
|
+
},
|
|
189
193
|
"./tokens": {
|
|
190
194
|
"import": "./tokens/tokens.js",
|
|
191
195
|
"types": "./tokens/tokens.d.ts"
|
|
@@ -210,7 +214,7 @@
|
|
|
210
214
|
"README.md"
|
|
211
215
|
],
|
|
212
216
|
"dependencies": {
|
|
213
|
-
"@deepfuture/dui-primitives": "1.
|
|
217
|
+
"@deepfuture/dui-primitives": "1.3.0",
|
|
214
218
|
"lit": "^3.3.2",
|
|
215
219
|
"@lit/context": "^1.1.3"
|
|
216
220
|
},
|
package/tree/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import "./tree.js";
|
|
2
|
+
import "./tree-item.js";
|
|
3
|
+
export { DuiTree } from "./tree.js";
|
|
4
|
+
export { DuiTreeItem } from "./tree-item.js";
|
|
5
|
+
export type { SelectionMode, TreeContext } from "@deepfuture/dui-primitives/tree";
|
|
6
|
+
export { actionEvent, expandedChangeEvent, loadChildrenEvent, selectionChangeEvent, } from "@deepfuture/dui-primitives/tree";
|
package/tree/index.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { css, unsafeCSS } from "lit";
|
|
2
|
+
import { DuiTreeItemPrimitive } from "@deepfuture/dui-primitives/tree";
|
|
3
|
+
import "../_install.js";
|
|
4
|
+
// Lucide chevron-right, encoded for use as a CSS mask
|
|
5
|
+
const chevronMask = unsafeCSS(`url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E")`);
|
|
6
|
+
// Lucide loader-2 (rotating arc), used as a spinner mask while loading
|
|
7
|
+
const spinnerMask = unsafeCSS(`url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 12a9 9 0 1 1-6.219-8.56'/%3E%3C/svg%3E")`);
|
|
8
|
+
const styles = css `
|
|
9
|
+
/* ── Row container ─────────────────────────────────────────────────── */
|
|
10
|
+
|
|
11
|
+
/*
|
|
12
|
+
* IMPORTANT: All visual styling lives on [part="content"], NOT [part="root"].
|
|
13
|
+
* [part="root"] wraps both the row and the children group, so :hover on it
|
|
14
|
+
* would bleed onto descendant rows. See the hover-bleed regression demo.
|
|
15
|
+
*/
|
|
16
|
+
[part="content"] {
|
|
17
|
+
height: var(--dui-tree-row-height);
|
|
18
|
+
padding-inline-start: calc(
|
|
19
|
+
var(--_tree-row-px) +
|
|
20
|
+
(var(--dui-tree-level, 1) - 1) * var(--dui-tree-indent)
|
|
21
|
+
);
|
|
22
|
+
padding-inline-end: var(--_tree-row-px);
|
|
23
|
+
margin-block: calc(var(--dui-tree-row-spacing) / 2);
|
|
24
|
+
margin-inline: var(--space-1);
|
|
25
|
+
border-radius: var(--dui-tree-row-radius);
|
|
26
|
+
gap: var(--_tree-inline-gap);
|
|
27
|
+
color: var(--text-1);
|
|
28
|
+
font-family: var(--font-sans);
|
|
29
|
+
font-size: var(--_tree-label-font-size);
|
|
30
|
+
line-height: var(--_tree-label-line-height);
|
|
31
|
+
cursor: pointer;
|
|
32
|
+
transition-property: background, box-shadow, color;
|
|
33
|
+
transition-duration: var(--duration-faster);
|
|
34
|
+
transition-timing-function: var(--ease-out-3);
|
|
35
|
+
/* Allow children to truncate */
|
|
36
|
+
min-width: 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@media (hover: hover) {
|
|
40
|
+
[part="content"]:hover {
|
|
41
|
+
background: var(--dui-tree-hover-bg);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
:host([data-selected]) [part="content"] {
|
|
46
|
+
background: var(--dui-tree-selected-bg);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
:host([data-disabled]) [part="content"] {
|
|
50
|
+
opacity: 0.4;
|
|
51
|
+
cursor: not-allowed;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* ── Focus ring ─────────────────────────────────────────────────────── */
|
|
55
|
+
|
|
56
|
+
[part="root"]:focus-visible {
|
|
57
|
+
outline: none;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
[part="root"]:focus-visible [part="content"] {
|
|
61
|
+
box-shadow:
|
|
62
|
+
0 0 0 var(--focus-ring-offset) var(--background),
|
|
63
|
+
0 0 0 calc(var(--focus-ring-offset) + var(--focus-ring-width))
|
|
64
|
+
var(--focus-ring-color);
|
|
65
|
+
/* Keep the highlighted row above siblings so the ring isn't clipped. */
|
|
66
|
+
position: relative;
|
|
67
|
+
z-index: 1;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* ── Indicator (chevron / spinner / leaf placeholder) ─────────────── */
|
|
71
|
+
|
|
72
|
+
[part="indicator"] {
|
|
73
|
+
width: var(--_tree-indicator-size);
|
|
74
|
+
height: var(--_tree-indicator-size);
|
|
75
|
+
color: var(--text-2);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* Branch chevron */
|
|
79
|
+
:host([data-branch]) [part="indicator"]::before {
|
|
80
|
+
content: "";
|
|
81
|
+
display: block;
|
|
82
|
+
width: 100%;
|
|
83
|
+
height: 100%;
|
|
84
|
+
background: currentColor;
|
|
85
|
+
-webkit-mask: ${chevronMask} center / contain no-repeat;
|
|
86
|
+
mask: ${chevronMask} center / contain no-repeat;
|
|
87
|
+
transition-property: transform;
|
|
88
|
+
transition-duration: var(--duration-fast);
|
|
89
|
+
transition-timing-function: var(--ease-out-3);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
:host([data-expanded]) [part="indicator"]::before {
|
|
93
|
+
transform: rotate(90deg);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/* Loading spinner replaces the chevron in-place */
|
|
97
|
+
:host([data-loading]) [part="indicator"]::before {
|
|
98
|
+
-webkit-mask: ${spinnerMask} center / contain no-repeat;
|
|
99
|
+
mask: ${spinnerMask} center / contain no-repeat;
|
|
100
|
+
transform: none;
|
|
101
|
+
animation: dui-tree-spin 0.9s linear infinite;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@keyframes dui-tree-spin {
|
|
105
|
+
from {
|
|
106
|
+
transform: rotate(0deg);
|
|
107
|
+
}
|
|
108
|
+
to {
|
|
109
|
+
transform: rotate(360deg);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* ── Slotted content ────────────────────────────────────────────────── */
|
|
114
|
+
|
|
115
|
+
::slotted([slot="label"]) {
|
|
116
|
+
min-width: 0;
|
|
117
|
+
overflow: hidden;
|
|
118
|
+
text-overflow: ellipsis;
|
|
119
|
+
white-space: nowrap;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
::slotted([slot="end"]) {
|
|
123
|
+
flex-shrink: 0;
|
|
124
|
+
color: var(--text-2);
|
|
125
|
+
font-size: var(--_tree-end-font-size);
|
|
126
|
+
line-height: var(--_tree-end-line-height);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* ── Reduced motion ────────────────────────────────────────────────── */
|
|
130
|
+
|
|
131
|
+
@media (prefers-reduced-motion: reduce) {
|
|
132
|
+
[part="content"],
|
|
133
|
+
:host([data-branch]) [part="indicator"]::before {
|
|
134
|
+
transition-duration: 0s;
|
|
135
|
+
}
|
|
136
|
+
:host([data-loading]) [part="indicator"]::before {
|
|
137
|
+
animation: none;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
`;
|
|
141
|
+
export class DuiTreeItem extends DuiTreeItemPrimitive {
|
|
142
|
+
static styles = [...DuiTreeItemPrimitive.styles, styles];
|
|
143
|
+
}
|
|
144
|
+
customElements.define(DuiTreeItem.tagName, DuiTreeItem);
|
package/tree/tree.d.ts
ADDED
package/tree/tree.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { css } from "lit";
|
|
2
|
+
import { DuiTreePrimitive } from "@deepfuture/dui-primitives/tree";
|
|
3
|
+
import "../_install.js";
|
|
4
|
+
const styles = css `
|
|
5
|
+
/* ── Sizes — write to public tokens on :host so consumer overrides win ── */
|
|
6
|
+
|
|
7
|
+
:host {
|
|
8
|
+
/* Default = sm */
|
|
9
|
+
--dui-tree-row-height: var(--component-height-sm);
|
|
10
|
+
--dui-tree-indent: var(--space-4);
|
|
11
|
+
--dui-tree-row-spacing: 0;
|
|
12
|
+
--dui-tree-row-radius: var(--radius-sm);
|
|
13
|
+
--dui-tree-hover-bg: oklch(from var(--foreground) l c h / 0.05);
|
|
14
|
+
--dui-tree-selected-bg: oklch(from var(--foreground) l c h / 0.10);
|
|
15
|
+
|
|
16
|
+
/* Internal-only (not part of public token surface) */
|
|
17
|
+
--_tree-label-font-size: var(--text-xs);
|
|
18
|
+
--_tree-label-line-height: var(--text-xs--line-height);
|
|
19
|
+
--_tree-end-font-size: var(--text-2xs);
|
|
20
|
+
--_tree-end-line-height: var(--text-2xs--line-height);
|
|
21
|
+
--_tree-indicator-size: 14px;
|
|
22
|
+
--_tree-row-px: var(--space-2);
|
|
23
|
+
--_tree-inline-gap: var(--space-2);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
:host([size="md"]) {
|
|
27
|
+
--dui-tree-row-height: var(--component-height-md);
|
|
28
|
+
--dui-tree-indent: var(--space-5);
|
|
29
|
+
--_tree-label-font-size: var(--text-sm);
|
|
30
|
+
--_tree-label-line-height: var(--text-sm--line-height);
|
|
31
|
+
--_tree-end-font-size: var(--text-xs);
|
|
32
|
+
--_tree-end-line-height: var(--text-xs--line-height);
|
|
33
|
+
--_tree-indicator-size: var(--space-4);
|
|
34
|
+
--_tree-inline-gap: var(--space-2);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
:host([size="lg"]) {
|
|
38
|
+
--dui-tree-row-height: var(--component-height-lg);
|
|
39
|
+
--dui-tree-indent: var(--space-6);
|
|
40
|
+
--_tree-label-font-size: var(--text-sm);
|
|
41
|
+
--_tree-label-line-height: var(--text-sm--line-height);
|
|
42
|
+
--_tree-end-font-size: var(--text-xs);
|
|
43
|
+
--_tree-end-line-height: var(--text-xs--line-height);
|
|
44
|
+
--_tree-indicator-size: var(--space-4);
|
|
45
|
+
--_tree-inline-gap: var(--space-2_5);
|
|
46
|
+
}
|
|
47
|
+
`;
|
|
48
|
+
export class DuiTree extends DuiTreePrimitive {
|
|
49
|
+
static styles = [...DuiTreePrimitive.styles, styles];
|
|
50
|
+
}
|
|
51
|
+
customElements.define(DuiTree.tagName, DuiTree);
|