openproject-primer_view_components 0.66.1 → 0.67.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/app/assets/javascripts/components/primer/open_project/tree_view/tree_view.d.ts +2 -0
- data/app/assets/javascripts/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.d.ts +4 -2
- data/app/assets/javascripts/primer_view_components.js +1 -1
- data/app/assets/javascripts/primer_view_components.js.map +1 -1
- data/app/assets/styles/primer_view_components.css +1 -1
- data/app/assets/styles/primer_view_components.css.map +1 -1
- data/app/components/primer/open_project/border_box/collapsible_header.rb +3 -0
- data/app/components/primer/open_project/collapsible_section.rb +7 -1
- data/app/components/primer/open_project/tree_view/node.html.erb +2 -2
- data/app/components/primer/open_project/tree_view/node.rb +49 -26
- data/app/components/primer/open_project/tree_view/skeleton_loader.html.erb +1 -1
- data/app/components/primer/open_project/tree_view/spinner_loader.html.erb +2 -2
- data/app/components/primer/open_project/tree_view/sub_tree.html.erb +1 -1
- data/app/components/primer/open_project/tree_view/sub_tree.rb +8 -1
- data/app/components/primer/open_project/tree_view/sub_tree_node.rb +9 -3
- data/app/components/primer/open_project/tree_view/tree_view.d.ts +2 -0
- data/app/components/primer/open_project/tree_view/tree_view.js +29 -9
- data/app/components/primer/open_project/tree_view/tree_view.ts +31 -10
- data/app/components/primer/open_project/tree_view/tree_view_roving_tab_index.js +11 -7
- data/app/components/primer/open_project/tree_view/tree_view_roving_tab_index.ts +13 -8
- data/app/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.d.ts +4 -2
- data/app/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.js +60 -30
- data/app/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.ts +66 -33
- data/app/components/primer/open_project/tree_view.css +1 -1
- data/app/components/primer/open_project/tree_view.css.json +9 -6
- data/app/components/primer/open_project/tree_view.css.map +1 -1
- data/app/components/primer/open_project/tree_view.pcss +53 -38
- data/app/components/primer/open_project/tree_view.rb +88 -24
- data/lib/primer/view_components/version.rb +2 -2
- data/previews/primer/open_project/border_box/collapsible_header_preview/playground.html.erb +1 -1
- data/previews/primer/open_project/tree_view_preview/buttons.html.erb +10 -0
- data/previews/primer/open_project/tree_view_preview/links.html.erb +17 -0
- data/previews/primer/open_project/tree_view_preview.rb +29 -3
- data/static/arguments.json +38 -2
- data/static/constants.json +17 -0
- data/static/info_arch.json +95 -3
- data/static/previews.json +26 -0
- metadata +4 -2
@@ -15,19 +15,19 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
15
15
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
16
16
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
17
17
|
};
|
18
|
-
var _TreeViewSubTreeNodeElement_instances, _TreeViewSubTreeNodeElement_abortController, _TreeViewSubTreeNodeElement_activeElementIsLoader, _TreeViewSubTreeNodeElement_handleToggleEvent, _TreeViewSubTreeNodeElement_handleIncludeFragmentEvent, _TreeViewSubTreeNodeElement_handleRetryButtonEvent, _TreeViewSubTreeNodeElement_handleKeyboardEvent, _TreeViewSubTreeNodeElement_handleCheckboxEvent, _TreeViewSubTreeNodeElement_update, _TreeViewSubTreeNodeElement_checkboxElement_get;
|
18
|
+
var _TreeViewSubTreeNodeElement_instances, _TreeViewSubTreeNodeElement_expanded, _TreeViewSubTreeNodeElement_loadingState, _TreeViewSubTreeNodeElement_abortController, _TreeViewSubTreeNodeElement_activeElementIsLoader, _TreeViewSubTreeNodeElement_handleToggleEvent, _TreeViewSubTreeNodeElement_handleIncludeFragmentEvent, _TreeViewSubTreeNodeElement_handleRetryButtonEvent, _TreeViewSubTreeNodeElement_handleKeyboardEvent, _TreeViewSubTreeNodeElement_handleCheckboxEvent, _TreeViewSubTreeNodeElement_update, _TreeViewSubTreeNodeElement_checkboxElement_get;
|
19
19
|
import { controller, target } from '@github/catalyst';
|
20
20
|
import { observeMutationsUntilConditionMet } from '../../utils';
|
21
21
|
let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLElement {
|
22
22
|
constructor() {
|
23
23
|
super(...arguments);
|
24
24
|
_TreeViewSubTreeNodeElement_instances.add(this);
|
25
|
+
_TreeViewSubTreeNodeElement_expanded.set(this, null);
|
26
|
+
_TreeViewSubTreeNodeElement_loadingState.set(this, 'success');
|
25
27
|
_TreeViewSubTreeNodeElement_abortController.set(this, void 0);
|
26
28
|
_TreeViewSubTreeNodeElement_activeElementIsLoader.set(this, false);
|
27
29
|
}
|
28
30
|
connectedCallback() {
|
29
|
-
this.expanded = this.node.getAttribute('aria-expanded') === 'true';
|
30
|
-
this.loadingState = 'success';
|
31
31
|
observeMutationsUntilConditionMet(this, () => Boolean(this.node) && Boolean(this.subTree), () => {
|
32
32
|
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_update).call(this);
|
33
33
|
});
|
@@ -77,6 +77,23 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
|
|
77
77
|
attributeFilter: ['aria-checked'],
|
78
78
|
});
|
79
79
|
}
|
80
|
+
get expanded() {
|
81
|
+
if (__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_expanded, "f") === null) {
|
82
|
+
__classPrivateFieldSet(this, _TreeViewSubTreeNodeElement_expanded, this.node.getAttribute('aria-expanded') === 'true', "f");
|
83
|
+
}
|
84
|
+
return __classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_expanded, "f");
|
85
|
+
}
|
86
|
+
set expanded(newValue) {
|
87
|
+
__classPrivateFieldSet(this, _TreeViewSubTreeNodeElement_expanded, newValue, "f");
|
88
|
+
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_update).call(this);
|
89
|
+
}
|
90
|
+
get loadingState() {
|
91
|
+
return __classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_loadingState, "f");
|
92
|
+
}
|
93
|
+
set loadingState(newState) {
|
94
|
+
__classPrivateFieldSet(this, _TreeViewSubTreeNodeElement_loadingState, newState, "f");
|
95
|
+
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_update).call(this);
|
96
|
+
}
|
80
97
|
get selectStrategy() {
|
81
98
|
return this.node.getAttribute('data-select-strategy') || 'descendants';
|
82
99
|
}
|
@@ -84,11 +101,7 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
|
|
84
101
|
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_abortController, "f").abort();
|
85
102
|
}
|
86
103
|
handleEvent(event) {
|
87
|
-
|
88
|
-
if (checkbox && checkbox === __classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "a", _TreeViewSubTreeNodeElement_checkboxElement_get)) {
|
89
|
-
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_handleCheckboxEvent).call(this, event);
|
90
|
-
}
|
91
|
-
else if (event.target === this.toggleButton) {
|
104
|
+
if (event.target === this.toggleButton) {
|
92
105
|
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_handleToggleEvent).call(this, event);
|
93
106
|
}
|
94
107
|
else if (event.target === this.includeFragment) {
|
@@ -97,11 +110,15 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
|
|
97
110
|
else if (event instanceof KeyboardEvent) {
|
98
111
|
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_handleKeyboardEvent).call(this, event);
|
99
112
|
}
|
113
|
+
else if (event.target.closest('[role=treeitem]') === this.node &&
|
114
|
+
event.type === 'click' &&
|
115
|
+
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "a", _TreeViewSubTreeNodeElement_checkboxElement_get)) {
|
116
|
+
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_handleCheckboxEvent).call(this, event);
|
117
|
+
}
|
100
118
|
}
|
101
119
|
expand() {
|
102
120
|
const alreadyExpanded = this.expanded;
|
103
121
|
this.expanded = true;
|
104
|
-
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_update).call(this);
|
105
122
|
if (!alreadyExpanded && this.treeView) {
|
106
123
|
this.treeView.dispatchEvent(new CustomEvent('treeViewNodeExpanded', {
|
107
124
|
bubbles: true,
|
@@ -112,7 +129,6 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
|
|
112
129
|
collapse() {
|
113
130
|
const alreadyCollapsed = !this.expanded;
|
114
131
|
this.expanded = false;
|
115
|
-
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_update).call(this);
|
116
132
|
if (!alreadyCollapsed && this.treeView) {
|
117
133
|
// Prevent issue where currently focusable node is stuck inside a collapsed
|
118
134
|
// sub-tree and no node in the entire tree can be focused
|
@@ -137,10 +153,10 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
|
|
137
153
|
return this.querySelectorAll(':scope > [role=treeitem]');
|
138
154
|
}
|
139
155
|
*eachDirectDescendantNode() {
|
140
|
-
for (const leaf of this.subTree.querySelectorAll(':scope > [role=treeitem]')) {
|
156
|
+
for (const leaf of this.subTree.querySelectorAll(':scope > li > .TreeViewItemContainer > [role=treeitem]')) {
|
141
157
|
yield leaf;
|
142
158
|
}
|
143
|
-
for (const subTree of this.subTree.querySelectorAll(':scope > tree-view-sub-tree-node > [role=treeitem]')) {
|
159
|
+
for (const subTree of this.subTree.querySelectorAll(':scope > tree-view-sub-tree-node > li > .TreeViewItemContainer > [role=treeitem]')) {
|
144
160
|
yield subTree;
|
145
161
|
}
|
146
162
|
}
|
@@ -186,12 +202,16 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
|
|
186
202
|
}));
|
187
203
|
}
|
188
204
|
};
|
205
|
+
_TreeViewSubTreeNodeElement_expanded = new WeakMap();
|
206
|
+
_TreeViewSubTreeNodeElement_loadingState = new WeakMap();
|
189
207
|
_TreeViewSubTreeNodeElement_abortController = new WeakMap();
|
190
208
|
_TreeViewSubTreeNodeElement_activeElementIsLoader = new WeakMap();
|
191
209
|
_TreeViewSubTreeNodeElement_instances = new WeakSet();
|
192
210
|
_TreeViewSubTreeNodeElement_handleToggleEvent = function _TreeViewSubTreeNodeElement_handleToggleEvent(event) {
|
193
211
|
if (event.type === 'click') {
|
194
212
|
this.toggle();
|
213
|
+
// eslint-disable-next-line no-restricted-syntax
|
214
|
+
event.stopPropagation();
|
195
215
|
}
|
196
216
|
};
|
197
217
|
_TreeViewSubTreeNodeElement_handleIncludeFragmentEvent = function _TreeViewSubTreeNodeElement_handleIncludeFragmentEvent(event) {
|
@@ -199,31 +219,25 @@ _TreeViewSubTreeNodeElement_handleIncludeFragmentEvent = function _TreeViewSubTr
|
|
199
219
|
// the request has started
|
200
220
|
case 'loadstart':
|
201
221
|
this.loadingState = 'loading';
|
202
|
-
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_update).call(this);
|
203
222
|
break;
|
204
223
|
// the request failed
|
205
224
|
case 'error':
|
206
225
|
this.loadingState = 'error';
|
207
|
-
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_update).call(this);
|
208
226
|
break;
|
209
227
|
// request succeeded but element has not yet been replaced
|
210
228
|
case 'include-fragment-replace':
|
229
|
+
__classPrivateFieldSet(this, _TreeViewSubTreeNodeElement_activeElementIsLoader, document.activeElement === this.loadingIndicator.closest('[role=treeitem]'), "f");
|
211
230
|
this.loadingState = 'success';
|
212
|
-
__classPrivateFieldSet(this, _TreeViewSubTreeNodeElement_activeElementIsLoader, document.activeElement === this.loadingIndicator.closest('li'), "f");
|
213
|
-
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_update).call(this);
|
214
231
|
break;
|
215
232
|
case 'include-fragment-replaced':
|
216
233
|
if (__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_activeElementIsLoader, "f")) {
|
217
|
-
const firstItem = this.querySelector('[role=
|
234
|
+
const firstItem = this.querySelector('[role=group] > :first-child');
|
218
235
|
if (!firstItem)
|
219
236
|
return;
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
else {
|
225
|
-
firstItem?.focus();
|
226
|
-
}
|
237
|
+
const content = firstItem.querySelector('[role=treeitem]');
|
238
|
+
if (!content)
|
239
|
+
return;
|
240
|
+
content.focus();
|
227
241
|
}
|
228
242
|
__classPrivateFieldSet(this, _TreeViewSubTreeNodeElement_activeElementIsLoader, false, "f");
|
229
243
|
break;
|
@@ -232,7 +246,6 @@ _TreeViewSubTreeNodeElement_handleIncludeFragmentEvent = function _TreeViewSubTr
|
|
232
246
|
_TreeViewSubTreeNodeElement_handleRetryButtonEvent = function _TreeViewSubTreeNodeElement_handleRetryButtonEvent(event) {
|
233
247
|
if (event.type === 'click') {
|
234
248
|
this.loadingState = 'loading';
|
235
|
-
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_update).call(this);
|
236
249
|
this.includeFragment.refetch();
|
237
250
|
}
|
238
251
|
};
|
@@ -245,7 +258,13 @@ _TreeViewSubTreeNodeElement_handleKeyboardEvent = function _TreeViewSubTreeNodeE
|
|
245
258
|
case 'Enter':
|
246
259
|
// eslint-disable-next-line no-restricted-syntax
|
247
260
|
event.stopPropagation();
|
248
|
-
this
|
261
|
+
if (__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "a", _TreeViewSubTreeNodeElement_checkboxElement_get)) {
|
262
|
+
this.toggleChecked();
|
263
|
+
}
|
264
|
+
else if (!this.treeView?.nodeHasNativeAction(node)) {
|
265
|
+
// toggle only if this node isn't eg. an anchor or button
|
266
|
+
this.toggle();
|
267
|
+
}
|
249
268
|
break;
|
250
269
|
case 'ArrowRight':
|
251
270
|
// eslint-disable-next-line no-restricted-syntax
|
@@ -258,10 +277,21 @@ _TreeViewSubTreeNodeElement_handleKeyboardEvent = function _TreeViewSubTreeNodeE
|
|
258
277
|
this.collapse();
|
259
278
|
break;
|
260
279
|
case ' ':
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
280
|
+
if (__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "a", _TreeViewSubTreeNodeElement_checkboxElement_get)) {
|
281
|
+
// eslint-disable-next-line no-restricted-syntax
|
282
|
+
event.stopPropagation();
|
283
|
+
event.preventDefault();
|
284
|
+
this.toggleChecked();
|
285
|
+
}
|
286
|
+
else {
|
287
|
+
if (node instanceof HTMLAnchorElement) {
|
288
|
+
// simulate click on space for anchors (buttons already handle this natively)
|
289
|
+
node.click();
|
290
|
+
}
|
291
|
+
else if (!this.treeView?.nodeHasNativeAction(node)) {
|
292
|
+
this.toggle();
|
293
|
+
}
|
294
|
+
}
|
265
295
|
break;
|
266
296
|
}
|
267
297
|
};
|
@@ -20,16 +20,12 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
|
|
20
20
|
@target loadingFailureMessage: HTMLElement
|
21
21
|
@target retryButton: HTMLButtonElement
|
22
22
|
|
23
|
-
expanded: boolean
|
24
|
-
loadingState: LoadingState
|
25
|
-
|
23
|
+
#expanded: boolean | null = null
|
24
|
+
#loadingState: LoadingState = 'success'
|
26
25
|
#abortController: AbortController
|
27
26
|
#activeElementIsLoader: boolean = false
|
28
27
|
|
29
28
|
connectedCallback() {
|
30
|
-
this.expanded = this.node.getAttribute('aria-expanded') === 'true'
|
31
|
-
this.loadingState = 'success'
|
32
|
-
|
33
29
|
observeMutationsUntilConditionMet(
|
34
30
|
this,
|
35
31
|
() => Boolean(this.node) && Boolean(this.subTree),
|
@@ -109,6 +105,28 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
|
|
109
105
|
})
|
110
106
|
}
|
111
107
|
|
108
|
+
get expanded(): boolean {
|
109
|
+
if (this.#expanded === null) {
|
110
|
+
this.#expanded = this.node.getAttribute('aria-expanded') === 'true'
|
111
|
+
}
|
112
|
+
|
113
|
+
return this.#expanded
|
114
|
+
}
|
115
|
+
|
116
|
+
set expanded(newValue: boolean) {
|
117
|
+
this.#expanded = newValue
|
118
|
+
this.#update()
|
119
|
+
}
|
120
|
+
|
121
|
+
get loadingState(): LoadingState {
|
122
|
+
return this.#loadingState
|
123
|
+
}
|
124
|
+
|
125
|
+
set loadingState(newState: LoadingState) {
|
126
|
+
this.#loadingState = newState
|
127
|
+
this.#update()
|
128
|
+
}
|
129
|
+
|
112
130
|
get selectStrategy(): string {
|
113
131
|
return this.node.getAttribute('data-select-strategy') || 'descendants'
|
114
132
|
}
|
@@ -118,16 +136,18 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
|
|
118
136
|
}
|
119
137
|
|
120
138
|
handleEvent(event: Event) {
|
121
|
-
|
122
|
-
|
123
|
-
if (checkbox && checkbox === this.#checkboxElement) {
|
124
|
-
this.#handleCheckboxEvent(event)
|
125
|
-
} else if (event.target === this.toggleButton) {
|
139
|
+
if (event.target === this.toggleButton) {
|
126
140
|
this.#handleToggleEvent(event)
|
127
141
|
} else if (event.target === this.includeFragment) {
|
128
142
|
this.#handleIncludeFragmentEvent(event)
|
129
143
|
} else if (event instanceof KeyboardEvent) {
|
130
144
|
this.#handleKeyboardEvent(event)
|
145
|
+
} else if (
|
146
|
+
(event.target as Element).closest('[role=treeitem]') === this.node &&
|
147
|
+
event.type === 'click' &&
|
148
|
+
this.#checkboxElement
|
149
|
+
) {
|
150
|
+
this.#handleCheckboxEvent(event)
|
131
151
|
}
|
132
152
|
}
|
133
153
|
|
@@ -135,7 +155,6 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
|
|
135
155
|
const alreadyExpanded = this.expanded
|
136
156
|
|
137
157
|
this.expanded = true
|
138
|
-
this.#update()
|
139
158
|
|
140
159
|
if (!alreadyExpanded && this.treeView) {
|
141
160
|
this.treeView.dispatchEvent(
|
@@ -151,7 +170,6 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
|
|
151
170
|
const alreadyCollapsed = !this.expanded
|
152
171
|
|
153
172
|
this.expanded = false
|
154
|
-
this.#update()
|
155
173
|
|
156
174
|
if (!alreadyCollapsed && this.treeView) {
|
157
175
|
// Prevent issue where currently focusable node is stuck inside a collapsed
|
@@ -182,11 +200,13 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
|
|
182
200
|
}
|
183
201
|
|
184
202
|
*eachDirectDescendantNode(): Generator<Element> {
|
185
|
-
for (const leaf of this.subTree.querySelectorAll(':scope > [role=treeitem]')) {
|
203
|
+
for (const leaf of this.subTree.querySelectorAll(':scope > li > .TreeViewItemContainer > [role=treeitem]')) {
|
186
204
|
yield leaf
|
187
205
|
}
|
188
206
|
|
189
|
-
for (const subTree of this.subTree.querySelectorAll(
|
207
|
+
for (const subTree of this.subTree.querySelectorAll(
|
208
|
+
':scope > tree-view-sub-tree-node > li > .TreeViewItemContainer > [role=treeitem]',
|
209
|
+
)) {
|
190
210
|
yield subTree
|
191
211
|
}
|
192
212
|
}
|
@@ -208,6 +228,8 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
|
|
208
228
|
#handleToggleEvent(event: Event) {
|
209
229
|
if (event.type === 'click') {
|
210
230
|
this.toggle()
|
231
|
+
// eslint-disable-next-line no-restricted-syntax
|
232
|
+
event.stopPropagation()
|
211
233
|
}
|
212
234
|
}
|
213
235
|
|
@@ -216,33 +238,28 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
|
|
216
238
|
// the request has started
|
217
239
|
case 'loadstart':
|
218
240
|
this.loadingState = 'loading'
|
219
|
-
this.#update()
|
220
241
|
break
|
221
242
|
|
222
243
|
// the request failed
|
223
244
|
case 'error':
|
224
245
|
this.loadingState = 'error'
|
225
|
-
this.#update()
|
226
246
|
break
|
227
247
|
|
228
248
|
// request succeeded but element has not yet been replaced
|
229
249
|
case 'include-fragment-replace':
|
250
|
+
this.#activeElementIsLoader = document.activeElement === this.loadingIndicator.closest('[role=treeitem]')
|
230
251
|
this.loadingState = 'success'
|
231
|
-
this.#activeElementIsLoader = document.activeElement === this.loadingIndicator.closest('li')
|
232
|
-
this.#update()
|
233
252
|
break
|
234
253
|
|
235
254
|
case 'include-fragment-replaced':
|
236
255
|
if (this.#activeElementIsLoader) {
|
237
|
-
const firstItem = this.querySelector('[role=
|
256
|
+
const firstItem = this.querySelector('[role=group] > :first-child') as HTMLElement | null
|
238
257
|
if (!firstItem) return
|
239
258
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
firstItem?.focus()
|
245
|
-
}
|
259
|
+
const content = firstItem.querySelector('[role=treeitem]') as HTMLElement | null
|
260
|
+
if (!content) return
|
261
|
+
|
262
|
+
content.focus()
|
246
263
|
}
|
247
264
|
|
248
265
|
this.#activeElementIsLoader = false
|
@@ -253,8 +270,6 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
|
|
253
270
|
#handleRetryButtonEvent(event: Event) {
|
254
271
|
if (event.type === 'click') {
|
255
272
|
this.loadingState = 'loading'
|
256
|
-
this.#update()
|
257
|
-
|
258
273
|
this.includeFragment.refetch()
|
259
274
|
}
|
260
275
|
}
|
@@ -269,7 +284,14 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
|
|
269
284
|
case 'Enter':
|
270
285
|
// eslint-disable-next-line no-restricted-syntax
|
271
286
|
event.stopPropagation()
|
272
|
-
|
287
|
+
|
288
|
+
if (this.#checkboxElement) {
|
289
|
+
this.toggleChecked()
|
290
|
+
} else if (!this.treeView?.nodeHasNativeAction(node)) {
|
291
|
+
// toggle only if this node isn't eg. an anchor or button
|
292
|
+
this.toggle()
|
293
|
+
}
|
294
|
+
|
273
295
|
break
|
274
296
|
|
275
297
|
case 'ArrowRight':
|
@@ -285,10 +307,21 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
|
|
285
307
|
break
|
286
308
|
|
287
309
|
case ' ':
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
310
|
+
if (this.#checkboxElement) {
|
311
|
+
// eslint-disable-next-line no-restricted-syntax
|
312
|
+
event.stopPropagation()
|
313
|
+
event.preventDefault()
|
314
|
+
|
315
|
+
this.toggleChecked()
|
316
|
+
} else {
|
317
|
+
if (node instanceof HTMLAnchorElement) {
|
318
|
+
// simulate click on space for anchors (buttons already handle this natively)
|
319
|
+
node.click()
|
320
|
+
} else if (!this.treeView?.nodeHasNativeAction(node)) {
|
321
|
+
this.toggle()
|
322
|
+
}
|
323
|
+
}
|
324
|
+
|
292
325
|
break
|
293
326
|
}
|
294
327
|
}
|
@@ -1 +1 @@
|
|
1
|
-
.TreeViewRootUlStyles{list-style:none;margin:0;padding:0}.TreeViewRootUlStyles .TreeViewItem{outline:none}:is(.TreeViewRootUlStyles .TreeViewItem):focus-visible>div{box-shadow:var(--boxShadow-thick) var(--fgColor-accent)}@media (forced-colors:active){:is(.TreeViewRootUlStyles .TreeViewItem):focus-visible>div{outline:2px solid HighlightText;outline-offset:-2}}[data-has-leading-action]:is(.TreeViewRootUlStyles .TreeViewItem){--has-leading-action:1}.TreeViewRootUlStyles .TreeViewItemContainer{--level:1;--toggle-width:1rem;--min-item-height:2rem;border-radius:var(--borderRadius-medium);color:var(--fgColor-default);
|
1
|
+
.TreeViewRootUlStyles{list-style:none;margin:0;padding:0}.TreeViewRootUlStyles .TreeViewItem{outline:none}:is(.TreeViewRootUlStyles .TreeViewItem):focus-visible>div{box-shadow:var(--boxShadow-thick) var(--fgColor-accent)}@media (forced-colors:active){:is(.TreeViewRootUlStyles .TreeViewItem):focus-visible>div{outline:2px solid HighlightText;outline-offset:-2}}[data-has-leading-action]:is(.TreeViewRootUlStyles .TreeViewItem){--has-leading-action:1}.TreeViewRootUlStyles .TreeViewItemContainer{--level:1;--toggle-width:1rem;--min-item-height:2rem;border-radius:var(--borderRadius-medium);color:var(--fgColor-default);display:grid;font-size:var(--text-body-size-medium);grid-template-areas:"spacer leadingAction toggle content";grid-template-columns:var(--spacer-width) var(--leading-action-width) var(--toggle-width) 1fr;position:relative;width:100%;--leading-action-width:calc(var(--has-leading-action, 0)*1.5rem);--spacer-width:calc((var(--level) - 1)*(var(--toggle-width)/2))}:is(.TreeViewRootUlStyles .TreeViewItemContainer):hover{background-color:var(--control-transparent-bgColor-hover)}@media (forced-colors:active){:is(.TreeViewRootUlStyles .TreeViewItemContainer):hover{outline:2px solid #0000;outline-offset:-2px}}@media (pointer:coarse){.TreeViewRootUlStyles .TreeViewItemContainer{--toggle-width:1.5rem;--min-item-height:2.75rem}}:is(.TreeViewRootUlStyles .TreeViewItemContainer):has(.TreeViewFailureMessage):hover{background-color:initial;cursor:default}@media (forced-colors:active){:is(.TreeViewRootUlStyles .TreeViewItemContainer):has(.TreeViewFailureMessage):hover{outline:none}}:is(.TreeViewRootUlStyles .TreeViewItemContainer):has([role=treeitem]:focus-visible){box-shadow:var(--boxShadow-thick) var(--fgColor-accent)}.TreeViewRootUlStyles:where([data-omit-spacer=true]) .TreeViewItemContainer{grid-template-columns:0 0 0 1fr}.TreeViewRootUlStyles .TreeViewItem>.TreeViewItemContainer:has(.TreeViewItemContent[aria-current=true]){background-color:var(--control-transparent-bgColor-selected)}:is(.TreeViewRootUlStyles .TreeViewItem>.TreeViewItemContainer:has(.TreeViewItemContent[aria-current=true])):after{background-color:var(--fgColor-accent);border-radius:var(--borderRadius-medium);content:"";height:1.5rem;left:calc(var(--base-size-8)*-1);position:absolute;top:calc(50% - var(--base-size-12));width:.25rem}@media (forced-colors:active){:is(.TreeViewRootUlStyles .TreeViewItem>.TreeViewItemContainer:has(.TreeViewItemContent[aria-current=true])):after{background-color:HighlightText}}.TreeViewRootUlStyles .TreeViewItemToggle{align-items:flex-start;color:var(--fgColor-muted);cursor:pointer;display:flex;grid-area:toggle;height:100%;justify-content:center;padding-top:calc(var(--min-item-height)/2 - var(--base-size-12)/2)}.TreeViewRootUlStyles .TreeViewItemToggleHover:hover{background-color:var(--control-transparent-bgColor-hover)}.TreeViewRootUlStyles .TreeViewItemToggleEnd{border-bottom-left-radius:var(--borderRadius-medium);border-top-left-radius:var(--borderRadius-medium)}.TreeViewRootUlStyles a.TreeViewItemContent:hover,.TreeViewRootUlStyles button.TreeViewItemContent:hover{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:var(--control-fgColor-rest)}.TreeViewRootUlStyles .TreeViewItemContent{cursor:pointer;display:flex;gap:var(--stack-gap-condensed);grid-area:content;height:100%;line-height:var(--custom-line-height,var(--text-body-lineHeight-medium,1.4285));outline:none;padding:0 var(--base-size-8);padding-bottom:calc((var(--min-item-height) - var(--custom-line-height, 1.3rem))/2);padding-top:calc((var(--min-item-height) - var(--custom-line-height, 1.3rem))/2)}.TreeViewRootUlStyles .TreeViewItemContent,:is(.TreeViewRootUlStyles .TreeViewItemContent) .TreeViewItemCheckbox{background-color:initial;border:none;text-align:left;touch-action:manipulation;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}:is(.TreeViewRootUlStyles .TreeViewItemContent) .TreeViewItemCheckbox{border-radius:var(--borderRadius-medium);color:var(--control-fgColor-rest);position:relative;transition:background 33.333ms linear}[aria-checked=true]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox{background:var(--control-checked-bgColor-rest);border-color:var(--control-checked-borderColor-rest);transition:background-color,border-color 80ms cubic-bezier(.32,0,.67,0) 0s}:is([aria-checked=true]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox):before{animation:checkmarkIn 80ms cubic-bezier(.65,0,.35,1) 80ms forwards;transition:visibility 0s linear 0s;visibility:visible}[aria-checked=mixed]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox{background:var(--control-checked-bgColor-rest);border-color:var(--control-checked-borderColor-rest);transition:background-color,border-color 80ms cubic-bezier(.32,0,.67,0) 0s}:is([aria-checked=mixed]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox):before{animation:checkmarkIn 80ms cubic-bezier(.65,0,.35,1) 80ms forwards;clip-path:none;mask-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIyIiBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMTAgMiI+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMCAxYTEgMSAwIDAgMSAxLTFoOGExIDEgMCAxIDEgMCAySDFhMSAxIDAgMCAxLTEtMSIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+");visibility:visible}.TreeViewRootUlStyles .TreeViewItemContentText{color:var(--control-fgColor-rest);flex:1 1 auto;width:0}.TreeViewRootUlStyles:where([data-truncate-text=true]) .TreeViewItemContentText{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.TreeViewRootUlStyles:where([data-truncate-text=false]) .TreeViewItemContentText{word-break:break-word}.TreeViewRootUlStyles .TreeViewItemVisual{align-items:center;color:var(--fgColor-muted);display:flex;height:var(--custom-line-height,1.3rem)}.TreeViewRootUlStyles .TreeViewItemLeadingAction{color:var(--fgColor-muted);display:flex;grid-area:leadingAction}:is(.TreeViewRootUlStyles .TreeViewItemLeadingAction)>button{flex-shrink:1}.TreeViewRootUlStyles .TreeViewItemLevelLine{border-color:var(--borderColor-muted);border-right:var(--borderWidth-thin) solid;height:100%;width:100%}@media (hover:hover){.TreeViewRootUlStyles .TreeViewItemLevelLine{border-color:#0000}.TreeViewRootUlStyles:focus-within .TreeViewItemLevelLine,.TreeViewRootUlStyles:hover .TreeViewItemLevelLine{border-color:var(--borderColor-muted)}}.TreeViewRootUlStyles .TreeViewVisuallyHidden{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border-width:0;white-space:nowrap}.TreeViewSkeletonItemContainerStyle{align-items:center;column-gap:.5rem;display:flex;height:2rem}@media (pointer:coarse){.TreeViewSkeletonItemContainerStyle{height:2.75rem}}.TreeViewSkeletonItemContainerStyle:nth-of-type(5n+1){--tree-item-loading-width:67%}.TreeViewSkeletonItemContainerStyle:nth-of-type(5n+2){--tree-item-loading-width:47%}.TreeViewSkeletonItemContainerStyle:nth-of-type(5n+3){--tree-item-loading-width:73%}.TreeViewSkeletonItemContainerStyle:nth-of-type(5n+4){--tree-item-loading-width:64%}.TreeViewSkeletonItemContainerStyle:nth-of-type(5n+5){--tree-item-loading-width:50%}.TreeItemSkeletonTextStyles{width:var(--tree-item-loading-width,67%)}.TreeViewFailureMessage{align-items:center;display:grid;gap:.5rem;grid-template-columns:auto 1fr;width:100%}
|
@@ -8,18 +8,21 @@
|
|
8
8
|
".TreeViewRootUlStyles .TreeViewItemContainer",
|
9
9
|
":is(.TreeViewRootUlStyles .TreeViewItemContainer):hover",
|
10
10
|
":is(.TreeViewRootUlStyles .TreeViewItemContainer):has(.TreeViewFailureMessage):hover",
|
11
|
+
":is(.TreeViewRootUlStyles .TreeViewItemContainer):has([role=treeitem]:focus-visible)",
|
11
12
|
".TreeViewRootUlStyles:where([data-omit-spacer=true]) .TreeViewItemContainer",
|
12
|
-
".TreeViewRootUlStyles .TreeViewItem[aria-current=true]
|
13
|
-
":is(.TreeViewRootUlStyles .TreeViewItem[aria-current=true]
|
14
|
-
"[aria-checked=true]:is(.TreeViewRootUlStyles .TreeViewItem)>.TreeViewItemContainer .FormControl-checkbox",
|
15
|
-
":is([aria-checked=true]:is(.TreeViewRootUlStyles .TreeViewItem)>.TreeViewItemContainer .FormControl-checkbox):before",
|
16
|
-
"[aria-checked=mixed]:is(.TreeViewRootUlStyles .TreeViewItem)>.TreeViewItemContainer .FormControl-checkbox",
|
17
|
-
":is([aria-checked=mixed]:is(.TreeViewRootUlStyles .TreeViewItem)>.TreeViewItemContainer .FormControl-checkbox):before",
|
13
|
+
".TreeViewRootUlStyles .TreeViewItem>.TreeViewItemContainer:has(.TreeViewItemContent[aria-current=true])",
|
14
|
+
":is(.TreeViewRootUlStyles .TreeViewItem>.TreeViewItemContainer:has(.TreeViewItemContent[aria-current=true])):after",
|
18
15
|
".TreeViewRootUlStyles .TreeViewItemToggle",
|
19
16
|
".TreeViewRootUlStyles .TreeViewItemToggleHover:hover",
|
20
17
|
".TreeViewRootUlStyles .TreeViewItemToggleEnd",
|
18
|
+
".TreeViewRootUlStyles a.TreeViewItemContent:hover",
|
19
|
+
".TreeViewRootUlStyles button.TreeViewItemContent:hover",
|
21
20
|
".TreeViewRootUlStyles .TreeViewItemContent",
|
22
21
|
":is(.TreeViewRootUlStyles .TreeViewItemContent) .TreeViewItemCheckbox",
|
22
|
+
"[aria-checked=true]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox",
|
23
|
+
":is([aria-checked=true]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox):before",
|
24
|
+
"[aria-checked=mixed]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox",
|
25
|
+
":is([aria-checked=mixed]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox):before",
|
23
26
|
".TreeViewRootUlStyles .TreeViewItemContentText",
|
24
27
|
".TreeViewRootUlStyles:where([data-truncate-text=true]) .TreeViewItemContentText",
|
25
28
|
".TreeViewRootUlStyles:where([data-truncate-text=false]) .TreeViewItemContentText",
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["tree_view.pcss"],"names":[],"mappings":"AAEA,sBAGE,eAAgB,CADhB,QAAS,CADT,SAgRF,CA/PE,oCACE,YAeF,CAbE,2DACE,uDAOF,CALE,8BAHF,2DAII,+BAAgC,CAEhC,iBAEJ,CADE,CAGF,kEACE,sBACF,CAGF,6CACE,SAAU,CACV,mBAAoB,CACpB,sBAAuB,CAQvB,wCAAyC,CAFzC,4BAA6B,CAC7B,cAAe,CAJf,YAAa,CAEb,sCAAuC,CAKvC,yDAA0D,CAD1D,6FAA8F,CAP9F,iBAAkB,CAElB,UAAW,CAQX,gEAAmE,CACnE,+DAwBF,CAtBE,wDACE,yDAMF,CAJE,8BAHF,wDAII,uBAA8B,CAC9B,mBAEJ,CADE,CAGF,wBA3BF,6CA4BI,qBAAsB,CACtB,yBAWJ,CAVE,CAEA,qFAEE,wBAA6B,CAD7B,cAMF,CAHE,8BAJF,qFAKI,YAEJ,CADE,CAIJ,4EACE,+BACF,CAEA,8EACE,4DAwBF,CApBE,yFAaE,sCAAuC,CACvC,wCAAyC,CARzC,UAAW,CADX,aAAc,CAFd,gCAAmC,CAFnC,iBAAkB,CAClB,mCAAoC,CAEpC,YAeF,CAHE,8BAhBF,yFAiBI,8BAEJ,CADE,CAQA,yGACE,8CAA+C,CAC/C,oDAAqD,CACrD,0EAQF,CALE,qHAGE,kEAAwE,CADxE,kCAAmC,CADnC,kBAGF,CAMF,0GACE,8CAA+C,CAC/C,oDAAqD,CACrD,0EASF,CANE,sHAGE,kEAAwE,CACxE,cAAe,CAFf,wUAAia,CADja,kBAIF,CAKN,0CAWE,sBAAuB,CAHvB,0BAA2B,CAP3B,YAAa,CAQb,gBAAiB,CAPjB,WAAY,CAQZ,sBAAuB,CAHvB,kEAKF,CAEA,qDACE,yDACF,CAEA,6CAEE,oDAAqD,CADrD,iDAEF,CAEA,2CACE,YAAa,CAWb,8BAA+B,CAD/B,iBAAkB,CATlB,WAAY,CAQZ,+EAAkF,CAPlF,4BAA6B,CAM7B,mFAAsF,CAFtF,gFAmBF,CAZE,sEAKE,wBAA6B,CAC7B,WAAY,CACZ,wCAAyC,CALzC,iCAAkC,CADlC,iBAAkB,CAElB,eAAgB,CAMhB,yBAA0B,CAD1B,qCAAsC,CAJtC,wBAAiB,CAAjB,gBAAiB,CAMjB,uCACF,CAGF,+CACE,aAAc,CACd,OACF,CAEA,gFACE,eAAgB,CAChB,sBAAuB,CACvB,kBACF,CAEA,iFAEE,qBACF,CAEA,0CAOE,kBAAmB,CADnB,0BAA2B,CAL3B,YAAa,CAIb,uCAGF,CAEA,iDAEE,0BAA2B,CAD3B,YAAa,CAEb,uBAKF,CAHE,6DACE,aACF,CAGF,6CAQE,qCAAsC,CACtC,0CAA2C,CAP3C,WAAY,CADZ,UASF,CAQA,qBACE,6CACE,kBACF,CAEA,6GAEE,qCACF,CACF,CAEA,8CAGE,UAAW,CAGX,WAAY,CACZ,eAAgB,CAHhB,SAAU,CAHV,iBAAkB,CAClB,SAAU,CAMV,kBAAsB,CAEtB,cAAe,CADf,kBAEF,CAGF,oCAEE,kBAAmB,CACnB,gBAAkB,CAFlB,YAAa,CAGb,WAyBF,CAvBE,wBANF,oCAOI,cAsBJ,CArBE,CAEA,sDACE,6BACF,CAEA,sDACE,6BACF,CAEA,sDACE,6BACF,CAEA,sDACE,6BACF,CAEA,sDACE,6BACF,CAGF,4BACE,wCACF,CAEA,wBAKE,kBAAmB,CAJnB,YAAa,CAEb,SAAW,CADX,8BAA+B,CAE/B,UAEF","file":"tree_view.css","sourcesContent":["/* stylelint-disable selector-max-type -- Copied from primer/react */\n\n.TreeViewRootUlStyles {\n padding: 0;\n margin: 0;\n list-style: none;\n\n /*\n * WARNING: This is a performance optimization.\n *\n * We define styles for the tree items at the root level of the tree\n * to avoid recomputing the styles for each item when the tree updates.\n * We're sacrificing maintainability for performance because TreeView\n * needs to be performant enough to handle large trees (thousands of items).\n *\n * This is intended to be a temporary solution until we can improve the\n * performance of our styling patterns.\n *\n * Do NOT copy this pattern without understanding the tradeoffs.\n */\n & .TreeViewItem {\n outline: none;\n\n &:focus-visible > div {\n box-shadow: var(--boxShadow-thick) var(--fgColor-accent);\n\n @media (forced-colors: active) {\n outline: 2px solid HighlightText;\n /* stylelint-disable-next-line declaration-property-value-no-unknown -- Copied from primer/react */\n outline-offset: -2;\n }\n }\n\n &[data-has-leading-action] {\n --has-leading-action: 1;\n }\n }\n\n & .TreeViewItemContainer {\n --level: 1;\n --toggle-width: 1rem;\n --min-item-height: 2rem;\n\n position: relative;\n display: grid;\n width: 100%;\n font-size: var(--text-body-size-medium);\n color: var(--fgColor-default);\n cursor: pointer;\n border-radius: var(--borderRadius-medium);\n grid-template-columns: var(--spacer-width) var(--leading-action-width) var(--toggle-width) 1fr;\n grid-template-areas: 'spacer leadingAction toggle content';\n\n --leading-action-width: calc(var(--has-leading-action, 0) * 1.5rem);\n --spacer-width: calc(calc(var(--level) - 1) * (var(--toggle-width) / 2));\n\n &:hover {\n background-color: var(--control-transparent-bgColor-hover);\n\n @media (forced-colors: active) {\n outline: 2px solid transparent;\n outline-offset: -2px;\n }\n }\n\n @media (pointer: coarse) {\n --toggle-width: 1.5rem;\n --min-item-height: 2.75rem;\n }\n\n &:has(.TreeViewFailureMessage):hover {\n cursor: default;\n background-color: transparent;\n\n @media (forced-colors: active) {\n outline: none;\n }\n }\n }\n\n &:where([data-omit-spacer='true']) .TreeViewItemContainer {\n grid-template-columns: 0 0 0 1fr;\n }\n\n & .TreeViewItem[aria-current='true'] > .TreeViewItemContainer {\n background-color: var(--control-transparent-bgColor-selected);\n\n /* Current item indicator */\n /* stylelint-disable-next-line selector-max-specificity -- Copied from primer/react */\n &::after {\n position: absolute;\n top: calc(50% - var(--base-size-12));\n left: calc(-1 * var(--base-size-8));\n width: 0.25rem;\n height: 1.5rem;\n content: '';\n\n /*\n * Use fgColor accent for consistency across all themes. Using the \"correct\" variable,\n * --bgColor-accent-emphasis, causes vrt failures for dark high contrast mode\n */\n /* stylelint-disable-next-line primer/colors */\n background-color: var(--fgColor-accent);\n border-radius: var(--borderRadius-medium);\n\n @media (forced-colors: active) {\n background-color: HighlightText;\n }\n }\n }\n\n /* stylelint-disable-next-line no-duplicate-selectors -- Copied from primer/react */\n & .TreeViewItem {\n &[aria-checked='true'] {\n /* stylelint-disable-next-line selector-max-compound-selectors, selector-max-specificity -- Copied from primer/react */\n & > .TreeViewItemContainer .FormControl-checkbox {\n background: var(--control-checked-bgColor-rest);\n border-color: var(--control-checked-borderColor-rest);\n transition: background-color, border-color 80ms cubic-bezier(0.32, 0, 0.67, 0) 0ms; /* unchecked -> checked */\n\n /* stylelint-disable-next-line max-nesting-depth, selector-max-compound-selectors, selector-max-specificity -- Copied from primer/react */\n &::before {\n visibility: visible;\n transition: visibility 0s linear 0s;\n animation: checkmarkIn 80ms cubic-bezier(0.65, 0, 0.35, 1) forwards 80ms;\n }\n }\n }\n\n &[aria-checked='mixed'] {\n /* stylelint-disable-next-line selector-max-compound-selectors, selector-max-specificity -- Copied from primer/react */\n & > .TreeViewItemContainer .FormControl-checkbox {\n background: var(--control-checked-bgColor-rest);\n border-color: var(--control-checked-borderColor-rest);\n transition: background-color, border-color 80ms cubic-bezier(0.32, 0, 0.67, 0) 0ms; /* unchecked -> checked */\n\n /* stylelint-disable-next-line max-nesting-depth, selector-max-compound-selectors, selector-max-specificity -- Copied from primer/react */\n &::before {\n visibility: visible;\n mask-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iMiIgdmlld0JveD0iMCAwIDEwIDIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMCAxQzAgMC40NDc3MTUgMC40NDc3MTUgMCAxIDBIOUM5LjU1MjI5IDAgMTAgMC40NDc3MTUgMTAgMUMxMCAxLjU1MjI4IDkuNTUyMjkgMiA5IDJIMUMwLjQ0NzcxNSAyIDAgMS41NTIyOCAwIDFaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K');\n animation: checkmarkIn 80ms cubic-bezier(0.65, 0, 0.35, 1) forwards 80ms;\n clip-path: none;\n }\n }\n }\n }\n\n & .TreeViewItemToggle {\n display: flex;\n height: 100%;\n\n /* The toggle should appear vertically centered for single-line items, but remain at the top for items that wrap\n across more lines. */\n /* stylelint-disable-next-line primer/spacing */\n padding-top: calc(var(--min-item-height) / 2 - var(--base-size-12) / 2);\n color: var(--fgColor-muted);\n grid-area: toggle;\n justify-content: center;\n align-items: flex-start;\n }\n\n & .TreeViewItemToggleHover:hover {\n background-color: var(--control-transparent-bgColor-hover);\n }\n\n & .TreeViewItemToggleEnd {\n border-top-left-radius: var(--borderRadius-medium);\n border-bottom-left-radius: var(--borderRadius-medium);\n }\n\n & .TreeViewItemContent {\n display: flex;\n height: 100%;\n padding: 0 var(--base-size-8);\n\n /* The dynamic top and bottom padding to maintain the minimum item height for single line items */\n /* stylelint-disable-next-line primer/spacing */\n padding-top: calc((var(--min-item-height) - var(--custom-line-height, 1.3rem)) / 2);\n /* stylelint-disable-next-line primer/spacing */\n padding-bottom: calc((var(--min-item-height) - var(--custom-line-height, 1.3rem)) / 2);\n line-height: var(--custom-line-height, var(--text-body-lineHeight-medium, 1.4285));\n grid-area: content;\n gap: var(--stack-gap-condensed);\n\n & .TreeViewItemCheckbox {\n position: relative;\n color: var(--control-fgColor-rest);\n text-align: left;\n user-select: none;\n background-color: transparent;\n border: none;\n border-radius: var(--borderRadius-medium);\n transition: background 33.333ms linear;\n touch-action: manipulation;\n -webkit-tap-highlight-color: transparent;\n }\n }\n\n & .TreeViewItemContentText {\n flex: 1 1 auto;\n width: 0;\n }\n\n &:where([data-truncate-text='true']) .TreeViewItemContentText {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n &:where([data-truncate-text='false']) .TreeViewItemContentText {\n /* stylelint-disable-next-line declaration-property-value-keyword-no-deprecated -- Copied from primer/react */\n word-break: break-word;\n }\n\n & .TreeViewItemVisual {\n display: flex;\n\n /* The visual icons should appear vertically centered for single-line items, but remain at the top for items that wrap\n across more lines. */\n height: var(--custom-line-height, 1.3rem);\n color: var(--fgColor-muted);\n align-items: center;\n }\n\n & .TreeViewItemLeadingAction {\n display: flex;\n color: var(--fgColor-muted);\n grid-area: leadingAction;\n\n & > button {\n flex-shrink: 1;\n }\n }\n\n & .TreeViewItemLevelLine {\n width: 100%;\n height: 100%;\n\n /*\n * On devices without hover, the nesting indicator lines\n * appear at all times.\n */\n border-color: var(--borderColor-muted);\n border-right: var(--borderWidth-thin) solid;\n }\n\n /*\n * On devices with :hover support, the nesting indicator lines\n * fade in when the user mouses over the entire component,\n * or when there's focus inside the component. This makes\n * sure the component remains simple when not in use.\n */\n @media (hover: hover) {\n .TreeViewItemLevelLine {\n border-color: transparent;\n }\n\n &:hover .TreeViewItemLevelLine,\n &:focus-within .TreeViewItemLevelLine {\n border-color: var(--borderColor-muted);\n }\n }\n\n & .TreeViewVisuallyHidden {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n /* stylelint-disable-next-line primer/spacing */\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n }\n}\n\n.TreeViewSkeletonItemContainerStyle {\n display: flex;\n align-items: center;\n column-gap: 0.5rem;\n height: 2rem;\n\n @media (pointer: coarse) {\n height: 2.75rem;\n }\n\n &:nth-of-type(5n + 1) {\n --tree-item-loading-width: 67%;\n }\n\n &:nth-of-type(5n + 2) {\n --tree-item-loading-width: 47%;\n }\n\n &:nth-of-type(5n + 3) {\n --tree-item-loading-width: 73%;\n }\n\n &:nth-of-type(5n + 4) {\n --tree-item-loading-width: 64%;\n }\n\n &:nth-of-type(5n + 5) {\n --tree-item-loading-width: 50%;\n }\n}\n\n.TreeItemSkeletonTextStyles {\n width: var(--tree-item-loading-width, 67%);\n}\n\n.TreeViewFailureMessage {\n display: grid;\n grid-template-columns: auto 1fr;\n gap: 0.5rem;\n width: 100%;\n align-items: center;\n}\n"]}
|
1
|
+
{"version":3,"sources":["tree_view.pcss"],"names":[],"mappings":"AAEA,sBAGE,eAAgB,CADhB,QAAS,CADT,SA+RF,CA9QE,oCACE,YAeF,CAbE,2DACE,uDAOF,CALE,8BAHF,2DAII,+BAAgC,CAEhC,iBAEJ,CADE,CAGF,kEACE,sBACF,CAGF,6CACE,SAAU,CACV,mBAAoB,CACpB,sBAAuB,CAOvB,wCAAyC,CADzC,4BAA6B,CAH7B,YAAa,CAEb,sCAAuC,CAIvC,yDAA0D,CAD1D,6FAA8F,CAN9F,iBAAkB,CAElB,UAAW,CAOX,gEAAmE,CACnE,+DA4BF,CA1BE,wDACE,yDAMF,CAJE,8BAHF,wDAII,uBAA8B,CAC9B,mBAEJ,CADE,CAGF,wBA1BF,6CA2BI,qBAAsB,CACtB,yBAeJ,CAdE,CAEA,qFAEE,wBAA6B,CAD7B,cAMF,CAHE,8BAJF,qFAKI,YAEJ,CADE,CAGF,qFACE,uDACF,CAGF,4EACE,+BACF,CAGA,wGACE,4DAwBF,CApBE,mHAaE,sCAAuC,CACvC,wCAAyC,CARzC,UAAW,CADX,aAAc,CAFd,gCAAmC,CAFnC,iBAAkB,CAClB,mCAAoC,CAEpC,YAeF,CAHE,8BAhBF,mHAiBI,8BAEJ,CADE,CAIJ,0CAWE,sBAAuB,CAHvB,0BAA2B,CAI3B,cAAe,CAXf,YAAa,CAQb,gBAAiB,CAPjB,WAAY,CAQZ,sBAAuB,CAHvB,kEAMF,CAEA,qDACE,yDACF,CAEA,6CAEE,oDAAqD,CADrD,iDAEF,CAGA,yGACE,iCAA0B,CAA1B,yBAA0B,CAC1B,iDACF,CAEA,2CAWE,cAAe,CAVf,YAAa,CAmBb,8BAA+B,CAD/B,iBAAkB,CAjBlB,WAAY,CAgBZ,+EAAkF,CAdlF,YAAa,CADb,4BAA6B,CAc7B,mFAAsF,CAFtF,gFAkDF,CA3CE,iHAfA,wBAA6B,CAC7B,WAAY,CAHZ,eAAgB,CAIhB,yBAA0B,CAH1B,wBAAiB,CAAjB,gBAAiB,CAIjB,uCAuBA,CAXA,sEAOE,wCAAyC,CALzC,iCAAkC,CADlC,iBAAkB,CAOlB,qCAGF,CAGE,yFACE,8CAA+C,CAC/C,oDAAqD,CACrD,0EAQF,CALE,qGAGE,kEAAwE,CADxE,kCAAmC,CADnC,kBAGF,CAKF,0FACE,8CAA+C,CAC/C,oDAAqD,CACrD,0EASF,CANE,sGAGE,kEAAwE,CACxE,cAAe,CAFf,wUAAia,CADja,kBAIF,CAKN,+CACE,iCAAkC,CAClC,aAAc,CACd,OACF,CAEA,gFACE,eAAgB,CAChB,sBAAuB,CACvB,kBACF,CAEA,iFAEE,qBACF,CAEA,0CAOE,kBAAmB,CADnB,0BAA2B,CAL3B,YAAa,CAIb,uCAGF,CAEA,iDAEE,0BAA2B,CAD3B,YAAa,CAEb,uBAKF,CAHE,6DACE,aACF,CAGF,6CAQE,qCAAsC,CACtC,0CAA2C,CAP3C,WAAY,CADZ,UASF,CAQA,qBACE,6CACE,kBACF,CAEA,6GAEE,qCACF,CACF,CAEA,8CAGE,UAAW,CAGX,WAAY,CACZ,eAAgB,CAHhB,SAAU,CAHV,iBAAkB,CAClB,SAAU,CAMV,kBAAsB,CAEtB,cAAe,CADf,kBAEF,CAGF,oCAEE,kBAAmB,CACnB,gBAAkB,CAFlB,YAAa,CAGb,WAyBF,CAvBE,wBANF,oCAOI,cAsBJ,CArBE,CAEA,sDACE,6BACF,CAEA,sDACE,6BACF,CAEA,sDACE,6BACF,CAEA,sDACE,6BACF,CAEA,sDACE,6BACF,CAGF,4BACE,wCACF,CAEA,wBAKE,kBAAmB,CAJnB,YAAa,CAEb,SAAW,CADX,8BAA+B,CAE/B,UAEF","file":"tree_view.css","sourcesContent":["/* stylelint-disable selector-max-type -- Copied from primer/react */\n\n.TreeViewRootUlStyles {\n padding: 0;\n margin: 0;\n list-style: none;\n\n /*\n * WARNING: This is a performance optimization.\n *\n * We define styles for the tree items at the root level of the tree\n * to avoid recomputing the styles for each item when the tree updates.\n * We're sacrificing maintainability for performance because TreeView\n * needs to be performant enough to handle large trees (thousands of items).\n *\n * This is intended to be a temporary solution until we can improve the\n * performance of our styling patterns.\n *\n * Do NOT copy this pattern without understanding the tradeoffs.\n */\n & .TreeViewItem {\n outline: none;\n\n &:focus-visible > div {\n box-shadow: var(--boxShadow-thick) var(--fgColor-accent);\n\n @media (forced-colors: active) {\n outline: 2px solid HighlightText;\n /* stylelint-disable-next-line declaration-property-value-no-unknown -- Copied from primer/react */\n outline-offset: -2;\n }\n }\n\n &[data-has-leading-action] {\n --has-leading-action: 1;\n }\n }\n\n & .TreeViewItemContainer {\n --level: 1;\n --toggle-width: 1rem;\n --min-item-height: 2rem;\n\n position: relative;\n display: grid;\n width: 100%;\n font-size: var(--text-body-size-medium);\n color: var(--fgColor-default);\n border-radius: var(--borderRadius-medium);\n grid-template-columns: var(--spacer-width) var(--leading-action-width) var(--toggle-width) 1fr;\n grid-template-areas: 'spacer leadingAction toggle content';\n\n --leading-action-width: calc(var(--has-leading-action, 0) * 1.5rem);\n --spacer-width: calc(calc(var(--level) - 1) * (var(--toggle-width) / 2));\n\n &:hover {\n background-color: var(--control-transparent-bgColor-hover);\n\n @media (forced-colors: active) {\n outline: 2px solid transparent;\n outline-offset: -2px;\n }\n }\n\n @media (pointer: coarse) {\n --toggle-width: 1.5rem;\n --min-item-height: 2.75rem;\n }\n\n &:has(.TreeViewFailureMessage):hover {\n cursor: default;\n background-color: transparent;\n\n @media (forced-colors: active) {\n outline: none;\n }\n }\n\n &:has([role='treeitem']:focus-visible) {\n box-shadow: var(--boxShadow-thick) var(--fgColor-accent);\n }\n }\n\n &:where([data-omit-spacer='true']) .TreeViewItemContainer {\n grid-template-columns: 0 0 0 1fr;\n }\n\n /* stylelint-disable-next-line selector-max-specificity */\n & .TreeViewItem > .TreeViewItemContainer:has(.TreeViewItemContent[aria-current='true']) {\n background-color: var(--control-transparent-bgColor-selected);\n\n /* Current item indicator */\n /* stylelint-disable-next-line selector-max-specificity -- Copied from primer/react */\n &::after {\n position: absolute;\n top: calc(50% - var(--base-size-12));\n left: calc(-1 * var(--base-size-8));\n width: 0.25rem;\n height: 1.5rem;\n content: '';\n\n /*\n * Use fgColor accent for consistency across all themes. Using the \"correct\" variable,\n * --bgColor-accent-emphasis, causes vrt failures for dark high contrast mode\n */\n /* stylelint-disable-next-line primer/colors */\n background-color: var(--fgColor-accent);\n border-radius: var(--borderRadius-medium);\n\n @media (forced-colors: active) {\n background-color: HighlightText;\n }\n }\n }\n\n & .TreeViewItemToggle {\n display: flex;\n height: 100%;\n\n /* The toggle should appear vertically centered for single-line items, but remain at the top for items that wrap\n across more lines. */\n /* stylelint-disable-next-line primer/spacing */\n padding-top: calc(var(--min-item-height) / 2 - var(--base-size-12) / 2);\n color: var(--fgColor-muted);\n grid-area: toggle;\n justify-content: center;\n align-items: flex-start;\n cursor: pointer;\n }\n\n & .TreeViewItemToggleHover:hover {\n background-color: var(--control-transparent-bgColor-hover);\n }\n\n & .TreeViewItemToggleEnd {\n border-top-left-radius: var(--borderRadius-medium);\n border-bottom-left-radius: var(--borderRadius-medium);\n }\n\n /* stylelint-disable-next-line selector-no-qualifying-type */\n & a.TreeViewItemContent:hover, button.TreeViewItemContent:hover {\n text-decoration: underline;\n text-decoration-color: var(--control-fgColor-rest);\n }\n\n & .TreeViewItemContent {\n display: flex;\n height: 100%;\n padding: 0 var(--base-size-8);\n outline: none;\n text-align: left;\n user-select: none;\n background-color: transparent;\n border: none;\n touch-action: manipulation;\n -webkit-tap-highlight-color: transparent;\n cursor: pointer;\n\n /* The dynamic top and bottom padding to maintain the minimum item height for single line items */\n /* stylelint-disable-next-line primer/spacing */\n padding-top: calc((var(--min-item-height) - var(--custom-line-height, 1.3rem)) / 2);\n /* stylelint-disable-next-line primer/spacing */\n padding-bottom: calc((var(--min-item-height) - var(--custom-line-height, 1.3rem)) / 2);\n line-height: var(--custom-line-height, var(--text-body-lineHeight-medium, 1.4285));\n grid-area: content;\n gap: var(--stack-gap-condensed);\n\n & .TreeViewItemCheckbox {\n position: relative;\n color: var(--control-fgColor-rest);\n text-align: left;\n user-select: none;\n background-color: transparent;\n border: none;\n border-radius: var(--borderRadius-medium);\n transition: background 33.333ms linear;\n touch-action: manipulation;\n -webkit-tap-highlight-color: transparent;\n }\n\n &[aria-checked='true'] {\n & .FormControl-checkbox {\n background: var(--control-checked-bgColor-rest);\n border-color: var(--control-checked-borderColor-rest);\n transition: background-color, border-color 80ms cubic-bezier(0.32, 0, 0.67, 0) 0ms; /* unchecked -> checked */\n\n /* stylelint-disable-next-line max-nesting-depth, selector-max-specificity -- Copied from primer/react */\n &::before {\n visibility: visible;\n transition: visibility 0s linear 0s;\n animation: checkmarkIn 80ms cubic-bezier(0.65, 0, 0.35, 1) forwards 80ms;\n }\n }\n }\n\n &[aria-checked='mixed'] {\n & .FormControl-checkbox {\n background: var(--control-checked-bgColor-rest);\n border-color: var(--control-checked-borderColor-rest);\n transition: background-color, border-color 80ms cubic-bezier(0.32, 0, 0.67, 0) 0ms; /* unchecked -> checked */\n\n /* stylelint-disable-next-line max-nesting-depth, selector-max-specificity -- Copied from primer/react */\n &::before {\n visibility: visible;\n mask-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iMiIgdmlld0JveD0iMCAwIDEwIDIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMCAxQzAgMC40NDc3MTUgMC40NDc3MTUgMCAxIDBIOUM5LjU1MjI5IDAgMTAgMC40NDc3MTUgMTAgMUMxMCAxLjU1MjI4IDkuNTUyMjkgMiA5IDJIMUMwLjQ0NzcxNSAyIDAgMS41NTIyOCAwIDFaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K');\n animation: checkmarkIn 80ms cubic-bezier(0.65, 0, 0.35, 1) forwards 80ms;\n clip-path: none;\n }\n }\n }\n }\n\n & .TreeViewItemContentText {\n color: var(--control-fgColor-rest);\n flex: 1 1 auto;\n width: 0;\n }\n\n &:where([data-truncate-text='true']) .TreeViewItemContentText {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n &:where([data-truncate-text='false']) .TreeViewItemContentText {\n /* stylelint-disable-next-line declaration-property-value-keyword-no-deprecated -- Copied from primer/react */\n word-break: break-word;\n }\n\n & .TreeViewItemVisual {\n display: flex;\n\n /* The visual icons should appear vertically centered for single-line items, but remain at the top for items that wrap\n across more lines. */\n height: var(--custom-line-height, 1.3rem);\n color: var(--fgColor-muted);\n align-items: center;\n }\n\n & .TreeViewItemLeadingAction {\n display: flex;\n color: var(--fgColor-muted);\n grid-area: leadingAction;\n\n & > button {\n flex-shrink: 1;\n }\n }\n\n & .TreeViewItemLevelLine {\n width: 100%;\n height: 100%;\n\n /*\n * On devices without hover, the nesting indicator lines\n * appear at all times.\n */\n border-color: var(--borderColor-muted);\n border-right: var(--borderWidth-thin) solid;\n }\n\n /*\n * On devices with :hover support, the nesting indicator lines\n * fade in when the user mouses over the entire component,\n * or when there's focus inside the component. This makes\n * sure the component remains simple when not in use.\n */\n @media (hover: hover) {\n .TreeViewItemLevelLine {\n border-color: transparent;\n }\n\n &:hover .TreeViewItemLevelLine,\n &:focus-within .TreeViewItemLevelLine {\n border-color: var(--borderColor-muted);\n }\n }\n\n & .TreeViewVisuallyHidden {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n /* stylelint-disable-next-line primer/spacing */\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n }\n}\n\n.TreeViewSkeletonItemContainerStyle {\n display: flex;\n align-items: center;\n column-gap: 0.5rem;\n height: 2rem;\n\n @media (pointer: coarse) {\n height: 2.75rem;\n }\n\n &:nth-of-type(5n + 1) {\n --tree-item-loading-width: 67%;\n }\n\n &:nth-of-type(5n + 2) {\n --tree-item-loading-width: 47%;\n }\n\n &:nth-of-type(5n + 3) {\n --tree-item-loading-width: 73%;\n }\n\n &:nth-of-type(5n + 4) {\n --tree-item-loading-width: 64%;\n }\n\n &:nth-of-type(5n + 5) {\n --tree-item-loading-width: 50%;\n }\n}\n\n.TreeItemSkeletonTextStyles {\n width: var(--tree-item-loading-width, 67%);\n}\n\n.TreeViewFailureMessage {\n display: grid;\n grid-template-columns: auto 1fr;\n gap: 0.5rem;\n width: 100%;\n align-items: center;\n}\n"]}
|