@threadlabs/looma 0.6.3 → 0.6.4
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/components/ui-tree-item/ui-tree-item.html +68 -12
- package/components/ui-tree-item/ui-tree-item.js +9 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/styles/ui-tree-item.css +74 -11
- package/vanilla/UiTreeItem.js +1 -1
- package/vue/UiTreeItem.vue +72 -12
- package/vue/chunks/UiTreeItem.js +10 -3
- package/vue/components.css +108 -56
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
</button>
|
|
64
64
|
<span class="leading"><slot name="leading"></slot></span>
|
|
65
65
|
<span class="label"><slot name="label"><template $value="label"></template></slot></span>
|
|
66
|
-
<span class="actions"><slot name="actions"></slot></span>
|
|
66
|
+
<span class="actions" $ref="actions"><slot name="actions"></slot></span>
|
|
67
67
|
<span class="drop-indicator row-drop-indicator" aria-hidden="true"></span>
|
|
68
68
|
</div>
|
|
69
69
|
<div class="children" $ref="children" role="group" :hidden="not (isContainer and internalExpanded)"><slot></slot></div>
|
|
@@ -72,6 +72,7 @@
|
|
|
72
72
|
<style>
|
|
73
73
|
:host {
|
|
74
74
|
--_tree-row-min-height: 32px;
|
|
75
|
+
--_tree-disclosure-size: 16px;
|
|
75
76
|
|
|
76
77
|
position: relative;
|
|
77
78
|
display: block;
|
|
@@ -82,7 +83,7 @@
|
|
|
82
83
|
.row {
|
|
83
84
|
position: relative;
|
|
84
85
|
display: grid;
|
|
85
|
-
grid-template-columns:
|
|
86
|
+
grid-template-columns: var(--_tree-disclosure-size) auto minmax(0, 1fr);
|
|
86
87
|
align-items: center;
|
|
87
88
|
min-block-size: var(--ui-tree-item-min-block-size, var(--_tree-row-min-height));
|
|
88
89
|
min-inline-size: 0;
|
|
@@ -130,13 +131,14 @@
|
|
|
130
131
|
.disclosure-spacer {
|
|
131
132
|
grid-column: 1;
|
|
132
133
|
grid-row: 1;
|
|
133
|
-
inline-size:
|
|
134
|
+
inline-size: var(--_tree-disclosure-size);
|
|
134
135
|
block-size: 28px;
|
|
135
136
|
}
|
|
136
137
|
|
|
137
138
|
.disclosure {
|
|
138
139
|
display: grid;
|
|
139
|
-
|
|
140
|
+
/* Start-aligned: the chevron's ink, not its hit area, aligns with the content above it. */
|
|
141
|
+
place-items: center start;
|
|
140
142
|
padding: 0;
|
|
141
143
|
color: var(--ui-text-muted);
|
|
142
144
|
background: transparent;
|
|
@@ -157,18 +159,18 @@
|
|
|
157
159
|
.disclosure-icon {
|
|
158
160
|
display: grid;
|
|
159
161
|
place-items: center;
|
|
160
|
-
inline-size:
|
|
161
|
-
block-size:
|
|
162
|
+
inline-size: 12px;
|
|
163
|
+
block-size: 12px;
|
|
162
164
|
transform: rotate(-90deg);
|
|
163
165
|
transition: transform var(--ui-motion-fast) var(--ui-motion-ease);
|
|
164
166
|
}
|
|
165
167
|
|
|
166
168
|
.disclosure-icon::before {
|
|
167
169
|
display: block;
|
|
168
|
-
inline-size: 0.
|
|
169
|
-
block-size: 0.
|
|
170
|
-
border-inline-end:
|
|
171
|
-
border-block-end:
|
|
170
|
+
inline-size: 0.375rem;
|
|
171
|
+
block-size: 0.375rem;
|
|
172
|
+
border-inline-end: 1.5px solid currentColor;
|
|
173
|
+
border-block-end: 1.5px solid currentColor;
|
|
172
174
|
content: "";
|
|
173
175
|
/* A chevron's ink sits below its box centre; lift it so it centres optically (in either rotation). */
|
|
174
176
|
transform: translateY(-20%) rotate(45deg);
|
|
@@ -229,12 +231,66 @@
|
|
|
229
231
|
min-inline-size: 0;
|
|
230
232
|
}
|
|
231
233
|
|
|
234
|
+
/* The controls sit over the label's end, so the text fades out where they begin. The fade is
|
|
235
|
+
the truncation mark while it shows: an ellipsis under it would read as a second one. */
|
|
236
|
+
.row:hover > .label,
|
|
237
|
+
.row:focus-within > .label {
|
|
238
|
+
text-overflow: clip;
|
|
239
|
+
mask-image: linear-gradient(
|
|
240
|
+
to right,
|
|
241
|
+
#000 calc(100% - var(--_tree-actions-width, 1.75rem) - var(--ui-space-3)),
|
|
242
|
+
transparent calc(100% - var(--_tree-actions-width, 1.75rem))
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.row:hover > .label:dir(rtl),
|
|
247
|
+
.row:focus-within > .label:dir(rtl) {
|
|
248
|
+
mask-image: linear-gradient(
|
|
249
|
+
to left,
|
|
250
|
+
#000 calc(100% - var(--_tree-actions-width, 1.75rem) - var(--ui-space-3)),
|
|
251
|
+
transparent calc(100% - var(--_tree-actions-width, 1.75rem))
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.row:hover > .label > :slotted(*),
|
|
256
|
+
.row:focus-within > .label > :slotted(*) {
|
|
257
|
+
text-overflow: clip;
|
|
258
|
+
}
|
|
259
|
+
|
|
232
260
|
.actions {
|
|
233
|
-
|
|
234
|
-
|
|
261
|
+
position: absolute;
|
|
262
|
+
z-index: 1;
|
|
263
|
+
inset-block: 0;
|
|
264
|
+
inset-inline-end: 0;
|
|
235
265
|
display: inline-flex;
|
|
236
266
|
align-items: center;
|
|
237
267
|
min-inline-size: 0;
|
|
268
|
+
opacity: 0;
|
|
269
|
+
pointer-events: none;
|
|
270
|
+
transition: opacity var(--ui-motion-fast) var(--ui-motion-ease);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.row:hover > .actions,
|
|
274
|
+
.row:focus-within > .actions {
|
|
275
|
+
opacity: 1;
|
|
276
|
+
pointer-events: auto;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/* Without hover there is no reveal, so the controls keep their own column. */
|
|
280
|
+
@media (hover: none) {
|
|
281
|
+
.row {
|
|
282
|
+
grid-template-columns: var(--_tree-disclosure-size) auto minmax(0, 1fr) auto;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.actions {
|
|
286
|
+
position: static;
|
|
287
|
+
grid-column: 4;
|
|
288
|
+
grid-row: 1;
|
|
289
|
+
padding-inline-start: 0;
|
|
290
|
+
background: none;
|
|
291
|
+
opacity: 1;
|
|
292
|
+
pointer-events: auto;
|
|
293
|
+
}
|
|
238
294
|
}
|
|
239
295
|
|
|
240
296
|
.drag-handle {
|
|
@@ -11,7 +11,7 @@ function parentItem(element) {
|
|
|
11
11
|
/** Synchronizes an inferred tree hierarchy after nested component lowering. */
|
|
12
12
|
export default function controller(host) {
|
|
13
13
|
const element = host.element;
|
|
14
|
-
const { row, disclosure, children } = host.refs;
|
|
14
|
+
const { row, disclosure, children, actions } = host.refs;
|
|
15
15
|
// Touch use enlarges rows and hides drag handles (see the template's styles).
|
|
16
16
|
trackInputModality(element.ownerDocument);
|
|
17
17
|
const childItems = () => Array.from(children?.children ?? [])
|
|
@@ -81,9 +81,17 @@ export default function controller(host) {
|
|
|
81
81
|
updateLevel();
|
|
82
82
|
const stop = host.effect(apply);
|
|
83
83
|
apply();
|
|
84
|
+
// The label's fade has to end where the controls begin, and only the controls know their width.
|
|
85
|
+
const actionsSize = new ResizeObserver(([entry]) => {
|
|
86
|
+
const width = entry.borderBoxSize?.[0]?.inlineSize ?? entry.contentRect.width;
|
|
87
|
+
element.style.setProperty("--_tree-actions-width", `${width}px`);
|
|
88
|
+
});
|
|
89
|
+
if (actions) actionsSize.observe(actions);
|
|
90
|
+
|
|
84
91
|
return () => {
|
|
85
92
|
stop?.();
|
|
86
93
|
observer.disconnect();
|
|
94
|
+
actionsSize.disconnect();
|
|
87
95
|
element.removeEventListener("ui-tree-auto-expand", onAutoExpand);
|
|
88
96
|
element.removeEventListener("ui-tree-structure-sync", onStructure);
|
|
89
97
|
element.removeEventListener("ui-tree-roving-tab-stop", onRoving);
|