openproject-primer_view_components 0.66.2 → 0.68.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/app/assets/javascripts/components/primer/open_project/tree_view/tree_view.d.ts +3 -0
  4. data/app/assets/javascripts/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.d.ts +1 -0
  5. data/app/assets/javascripts/primer_view_components.js +1 -1
  6. data/app/assets/javascripts/primer_view_components.js.map +1 -1
  7. data/app/assets/styles/primer_view_components.css +1 -1
  8. data/app/assets/styles/primer_view_components.css.map +1 -1
  9. data/app/components/primer/open_project/page_header/title.rb +1 -1
  10. data/app/components/primer/open_project/tree_view/node.html.erb +2 -2
  11. data/app/components/primer/open_project/tree_view/node.rb +49 -26
  12. data/app/components/primer/open_project/tree_view/skeleton_loader.html.erb +1 -1
  13. data/app/components/primer/open_project/tree_view/spinner_loader.html.erb +2 -2
  14. data/app/components/primer/open_project/tree_view/sub_tree.html.erb +1 -1
  15. data/app/components/primer/open_project/tree_view/sub_tree.rb +8 -1
  16. data/app/components/primer/open_project/tree_view/sub_tree_node.rb +9 -3
  17. data/app/components/primer/open_project/tree_view/tree_view.d.ts +3 -0
  18. data/app/components/primer/open_project/tree_view/tree_view.js +63 -10
  19. data/app/components/primer/open_project/tree_view/tree_view.ts +68 -10
  20. data/app/components/primer/open_project/tree_view/tree_view_roving_tab_index.js +11 -7
  21. data/app/components/primer/open_project/tree_view/tree_view_roving_tab_index.ts +13 -8
  22. data/app/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.d.ts +1 -0
  23. data/app/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.js +52 -21
  24. data/app/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.ts +60 -20
  25. data/app/components/primer/open_project/tree_view.css +1 -1
  26. data/app/components/primer/open_project/tree_view.css.json +9 -6
  27. data/app/components/primer/open_project/tree_view.css.map +1 -1
  28. data/app/components/primer/open_project/tree_view.pcss +53 -38
  29. data/app/components/primer/open_project/tree_view.rb +88 -24
  30. data/lib/primer/view_components/version.rb +2 -2
  31. data/previews/primer/open_project/tree_view_preview/async_alpha.html.erb +12 -0
  32. data/previews/primer/open_project/tree_view_preview/buttons.html.erb +10 -0
  33. data/previews/primer/open_project/tree_view_preview/links.html.erb +17 -0
  34. data/previews/primer/open_project/tree_view_preview.rb +53 -3
  35. data/static/arguments.json +38 -2
  36. data/static/constants.json +18 -1
  37. data/static/info_arch.json +121 -3
  38. data/static/previews.json +52 -0
  39. metadata +5 -2
@@ -101,11 +101,7 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
101
101
  __classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_abortController, "f").abort();
102
102
  }
103
103
  handleEvent(event) {
104
- const checkbox = event.target.closest('.TreeViewItemCheckbox');
105
- if (checkbox && checkbox === __classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "a", _TreeViewSubTreeNodeElement_checkboxElement_get)) {
106
- __classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_handleCheckboxEvent).call(this, event);
107
- }
108
- else if (event.target === this.toggleButton) {
104
+ if (event.target === this.toggleButton) {
109
105
  __classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_handleToggleEvent).call(this, event);
110
106
  }
111
107
  else if (event.target === this.includeFragment) {
@@ -114,6 +110,11 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
114
110
  else if (event instanceof KeyboardEvent) {
115
111
  __classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_handleKeyboardEvent).call(this, event);
116
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
+ }
117
118
  }
118
119
  expand() {
119
120
  const alreadyExpanded = this.expanded;
@@ -152,10 +153,10 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
152
153
  return this.querySelectorAll(':scope > [role=treeitem]');
153
154
  }
154
155
  *eachDirectDescendantNode() {
155
- for (const leaf of this.subTree.querySelectorAll(':scope > [role=treeitem]')) {
156
+ for (const leaf of this.subTree.querySelectorAll(':scope > li > .TreeViewItemContainer > [role=treeitem]')) {
156
157
  yield leaf;
157
158
  }
158
- 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]')) {
159
160
  yield subTree;
160
161
  }
161
162
  }
@@ -164,6 +165,16 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
164
165
  yield node;
165
166
  }
166
167
  }
168
+ *eachAncestorSubTreeNode() {
169
+ if (!this.treeView)
170
+ return;
171
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
172
+ let current = this;
173
+ while (current && this.treeView.contains(current)) {
174
+ yield current;
175
+ current = current.parentElement?.closest('tree-view-sub-tree-node');
176
+ }
177
+ }
167
178
  get isEmpty() {
168
179
  return this.nodes.length === 0;
169
180
  }
@@ -209,6 +220,8 @@ _TreeViewSubTreeNodeElement_instances = new WeakSet();
209
220
  _TreeViewSubTreeNodeElement_handleToggleEvent = function _TreeViewSubTreeNodeElement_handleToggleEvent(event) {
210
221
  if (event.type === 'click') {
211
222
  this.toggle();
223
+ // eslint-disable-next-line no-restricted-syntax
224
+ event.stopPropagation();
212
225
  }
213
226
  };
214
227
  _TreeViewSubTreeNodeElement_handleIncludeFragmentEvent = function _TreeViewSubTreeNodeElement_handleIncludeFragmentEvent(event) {
@@ -223,21 +236,21 @@ _TreeViewSubTreeNodeElement_handleIncludeFragmentEvent = function _TreeViewSubTr
223
236
  break;
224
237
  // request succeeded but element has not yet been replaced
225
238
  case 'include-fragment-replace':
226
- __classPrivateFieldSet(this, _TreeViewSubTreeNodeElement_activeElementIsLoader, document.activeElement === this.loadingIndicator.closest('li'), "f");
239
+ __classPrivateFieldSet(this, _TreeViewSubTreeNodeElement_activeElementIsLoader, document.activeElement === this.loadingIndicator.closest('[role=treeitem]'), "f");
227
240
  this.loadingState = 'success';
228
241
  break;
229
242
  case 'include-fragment-replaced':
243
+ // Make sure to expand the new sub-tree, otherwise it looks like nothing happened. This prevents
244
+ // having to remember to pass `SubTree.new(expanded: true)` in the controller.
245
+ this.expanded = true;
230
246
  if (__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_activeElementIsLoader, "f")) {
231
- const firstItem = this.querySelector('[role=treeitem] [role=group] > :first-child');
247
+ const firstItem = this.querySelector('[role=group] > :first-child');
232
248
  if (!firstItem)
233
249
  return;
234
- if (firstItem.tagName.toLowerCase() === 'tree-view-sub-tree-node') {
235
- const firstChild = firstItem.querySelector('[role=treeitem]');
236
- firstChild?.focus();
237
- }
238
- else {
239
- firstItem?.focus();
240
- }
250
+ const content = firstItem.querySelector('[role=treeitem]');
251
+ if (!content)
252
+ return;
253
+ content.focus();
241
254
  }
242
255
  __classPrivateFieldSet(this, _TreeViewSubTreeNodeElement_activeElementIsLoader, false, "f");
243
256
  break;
@@ -258,7 +271,13 @@ _TreeViewSubTreeNodeElement_handleKeyboardEvent = function _TreeViewSubTreeNodeE
258
271
  case 'Enter':
259
272
  // eslint-disable-next-line no-restricted-syntax
260
273
  event.stopPropagation();
261
- this.toggle();
274
+ if (__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "a", _TreeViewSubTreeNodeElement_checkboxElement_get)) {
275
+ this.toggleChecked();
276
+ }
277
+ else if (!this.treeView?.nodeHasNativeAction(node)) {
278
+ // toggle only if this node isn't eg. an anchor or button
279
+ this.toggle();
280
+ }
262
281
  break;
263
282
  case 'ArrowRight':
264
283
  // eslint-disable-next-line no-restricted-syntax
@@ -271,10 +290,21 @@ _TreeViewSubTreeNodeElement_handleKeyboardEvent = function _TreeViewSubTreeNodeE
271
290
  this.collapse();
272
291
  break;
273
292
  case ' ':
274
- // eslint-disable-next-line no-restricted-syntax
275
- event.stopPropagation();
276
- event.preventDefault();
277
- this.toggleChecked();
293
+ if (__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "a", _TreeViewSubTreeNodeElement_checkboxElement_get)) {
294
+ // eslint-disable-next-line no-restricted-syntax
295
+ event.stopPropagation();
296
+ event.preventDefault();
297
+ this.toggleChecked();
298
+ }
299
+ else {
300
+ if (node instanceof HTMLAnchorElement) {
301
+ // simulate click on space for anchors (buttons already handle this natively)
302
+ node.click();
303
+ }
304
+ else if (!this.treeView?.nodeHasNativeAction(node)) {
305
+ this.toggle();
306
+ }
307
+ }
278
308
  break;
279
309
  }
280
310
  };
@@ -291,6 +321,7 @@ _TreeViewSubTreeNodeElement_update = function _TreeViewSubTreeNodeElement_update
291
321
  if (this.subTree)
292
322
  this.subTree.hidden = false;
293
323
  this.node.setAttribute('aria-expanded', 'true');
324
+ this.treeView?.expandAncestorsForNode(this);
294
325
  if (this.iconPair) {
295
326
  this.iconPair.showExpanded();
296
327
  }
@@ -136,16 +136,18 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
136
136
  }
137
137
 
138
138
  handleEvent(event: Event) {
139
- const checkbox = (event.target as Element).closest('.TreeViewItemCheckbox')
140
-
141
- if (checkbox && checkbox === this.#checkboxElement) {
142
- this.#handleCheckboxEvent(event)
143
- } else if (event.target === this.toggleButton) {
139
+ if (event.target === this.toggleButton) {
144
140
  this.#handleToggleEvent(event)
145
141
  } else if (event.target === this.includeFragment) {
146
142
  this.#handleIncludeFragmentEvent(event)
147
143
  } else if (event instanceof KeyboardEvent) {
148
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)
149
151
  }
150
152
  }
151
153
 
@@ -198,11 +200,13 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
198
200
  }
199
201
 
200
202
  *eachDirectDescendantNode(): Generator<Element> {
201
- for (const leaf of this.subTree.querySelectorAll(':scope > [role=treeitem]')) {
203
+ for (const leaf of this.subTree.querySelectorAll(':scope > li > .TreeViewItemContainer > [role=treeitem]')) {
202
204
  yield leaf
203
205
  }
204
206
 
205
- for (const subTree of this.subTree.querySelectorAll(':scope > tree-view-sub-tree-node > [role=treeitem]')) {
207
+ for (const subTree of this.subTree.querySelectorAll(
208
+ ':scope > tree-view-sub-tree-node > li > .TreeViewItemContainer > [role=treeitem]',
209
+ )) {
206
210
  yield subTree
207
211
  }
208
212
  }
@@ -213,6 +217,19 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
213
217
  }
214
218
  }
215
219
 
220
+ *eachAncestorSubTreeNode(): Generator<TreeViewSubTreeNodeElement> {
221
+ if (!this.treeView) return
222
+
223
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
224
+ let current: TreeViewSubTreeNodeElement | null = this
225
+
226
+ while (current && this.treeView.contains(current)) {
227
+ yield current
228
+
229
+ current = current.parentElement?.closest('tree-view-sub-tree-node') as TreeViewSubTreeNodeElement | null
230
+ }
231
+ }
232
+
216
233
  get isEmpty(): boolean {
217
234
  return this.nodes.length === 0
218
235
  }
@@ -224,6 +241,8 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
224
241
  #handleToggleEvent(event: Event) {
225
242
  if (event.type === 'click') {
226
243
  this.toggle()
244
+ // eslint-disable-next-line no-restricted-syntax
245
+ event.stopPropagation()
227
246
  }
228
247
  }
229
248
 
@@ -241,21 +260,23 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
241
260
 
242
261
  // request succeeded but element has not yet been replaced
243
262
  case 'include-fragment-replace':
244
- this.#activeElementIsLoader = document.activeElement === this.loadingIndicator.closest('li')
263
+ this.#activeElementIsLoader = document.activeElement === this.loadingIndicator.closest('[role=treeitem]')
245
264
  this.loadingState = 'success'
246
265
  break
247
266
 
248
267
  case 'include-fragment-replaced':
268
+ // Make sure to expand the new sub-tree, otherwise it looks like nothing happened. This prevents
269
+ // having to remember to pass `SubTree.new(expanded: true)` in the controller.
270
+ this.expanded = true
271
+
249
272
  if (this.#activeElementIsLoader) {
250
- const firstItem = this.querySelector('[role=treeitem] [role=group] > :first-child') as HTMLElement | null
273
+ const firstItem = this.querySelector('[role=group] > :first-child') as HTMLElement | null
251
274
  if (!firstItem) return
252
275
 
253
- if (firstItem.tagName.toLowerCase() === 'tree-view-sub-tree-node') {
254
- const firstChild = firstItem.querySelector('[role=treeitem]') as HTMLElement | null
255
- firstChild?.focus()
256
- } else {
257
- firstItem?.focus()
258
- }
276
+ const content = firstItem.querySelector('[role=treeitem]') as HTMLElement | null
277
+ if (!content) return
278
+
279
+ content.focus()
259
280
  }
260
281
 
261
282
  this.#activeElementIsLoader = false
@@ -280,7 +301,14 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
280
301
  case 'Enter':
281
302
  // eslint-disable-next-line no-restricted-syntax
282
303
  event.stopPropagation()
283
- this.toggle()
304
+
305
+ if (this.#checkboxElement) {
306
+ this.toggleChecked()
307
+ } else if (!this.treeView?.nodeHasNativeAction(node)) {
308
+ // toggle only if this node isn't eg. an anchor or button
309
+ this.toggle()
310
+ }
311
+
284
312
  break
285
313
 
286
314
  case 'ArrowRight':
@@ -296,10 +324,21 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
296
324
  break
297
325
 
298
326
  case ' ':
299
- // eslint-disable-next-line no-restricted-syntax
300
- event.stopPropagation()
301
- event.preventDefault()
302
- this.toggleChecked()
327
+ if (this.#checkboxElement) {
328
+ // eslint-disable-next-line no-restricted-syntax
329
+ event.stopPropagation()
330
+ event.preventDefault()
331
+
332
+ this.toggleChecked()
333
+ } else {
334
+ if (node instanceof HTMLAnchorElement) {
335
+ // simulate click on space for anchors (buttons already handle this natively)
336
+ node.click()
337
+ } else if (!this.treeView?.nodeHasNativeAction(node)) {
338
+ this.toggle()
339
+ }
340
+ }
341
+
303
342
  break
304
343
  }
305
344
  }
@@ -355,6 +394,7 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
355
394
  if (this.expanded) {
356
395
  if (this.subTree) this.subTree.hidden = false
357
396
  this.node.setAttribute('aria-expanded', 'true')
397
+ this.treeView?.expandAncestorsForNode(this)
358
398
 
359
399
  if (this.iconPair) {
360
400
  this.iconPair.showExpanded()
@@ -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);cursor:pointer;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}}.TreeViewRootUlStyles:where([data-omit-spacer=true]) .TreeViewItemContainer{grid-template-columns:0 0 0 1fr}.TreeViewRootUlStyles .TreeViewItem[aria-current=true]>.TreeViewItemContainer{background-color:var(--control-transparent-bgColor-selected)}:is(.TreeViewRootUlStyles .TreeViewItem[aria-current=true]>.TreeViewItemContainer):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[aria-current=true]>.TreeViewItemContainer):after{background-color:HighlightText}}[aria-checked=true]:is(.TreeViewRootUlStyles .TreeViewItem)>.TreeViewItemContainer .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 .TreeViewItem)>.TreeViewItemContainer .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 .TreeViewItem)>.TreeViewItemContainer .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 .TreeViewItem)>.TreeViewItemContainer .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 .TreeViewItemToggle{align-items:flex-start;color:var(--fgColor-muted);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 .TreeViewItemContent{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));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)}:is(.TreeViewRootUlStyles .TreeViewItemContent) .TreeViewItemCheckbox{background-color:initial;border:none;border-radius:var(--borderRadius-medium);color:var(--control-fgColor-rest);position:relative;text-align:left;touch-action:manipulation;transition:background 33.333ms linear;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.TreeViewRootUlStyles .TreeViewItemContentText{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%}
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]>.TreeViewItemContainer",
13
- ":is(.TreeViewRootUlStyles .TreeViewItem[aria-current=true]>.TreeViewItemContainer):after",
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"]}
@@ -46,7 +46,6 @@
46
46
  width: 100%;
47
47
  font-size: var(--text-body-size-medium);
48
48
  color: var(--fgColor-default);
49
- cursor: pointer;
50
49
  border-radius: var(--borderRadius-medium);
51
50
  grid-template-columns: var(--spacer-width) var(--leading-action-width) var(--toggle-width) 1fr;
52
51
  grid-template-areas: 'spacer leadingAction toggle content';
@@ -76,13 +75,18 @@
76
75
  outline: none;
77
76
  }
78
77
  }
78
+
79
+ &:has([role='treeitem']:focus-visible) {
80
+ box-shadow: var(--boxShadow-thick) var(--fgColor-accent);
81
+ }
79
82
  }
80
83
 
81
84
  &:where([data-omit-spacer='true']) .TreeViewItemContainer {
82
85
  grid-template-columns: 0 0 0 1fr;
83
86
  }
84
87
 
85
- & .TreeViewItem[aria-current='true'] > .TreeViewItemContainer {
88
+ /* stylelint-disable-next-line selector-max-specificity */
89
+ & .TreeViewItem > .TreeViewItemContainer:has(.TreeViewItemContent[aria-current='true']) {
86
90
  background-color: var(--control-transparent-bgColor-selected);
87
91
 
88
92
  /* Current item indicator */
@@ -109,42 +113,6 @@
109
113
  }
110
114
  }
111
115
 
112
- /* stylelint-disable-next-line no-duplicate-selectors -- Copied from primer/react */
113
- & .TreeViewItem {
114
- &[aria-checked='true'] {
115
- /* stylelint-disable-next-line selector-max-compound-selectors, selector-max-specificity -- Copied from primer/react */
116
- & > .TreeViewItemContainer .FormControl-checkbox {
117
- background: var(--control-checked-bgColor-rest);
118
- border-color: var(--control-checked-borderColor-rest);
119
- transition: background-color, border-color 80ms cubic-bezier(0.32, 0, 0.67, 0) 0ms; /* unchecked -> checked */
120
-
121
- /* stylelint-disable-next-line max-nesting-depth, selector-max-compound-selectors, selector-max-specificity -- Copied from primer/react */
122
- &::before {
123
- visibility: visible;
124
- transition: visibility 0s linear 0s;
125
- animation: checkmarkIn 80ms cubic-bezier(0.65, 0, 0.35, 1) forwards 80ms;
126
- }
127
- }
128
- }
129
-
130
- &[aria-checked='mixed'] {
131
- /* stylelint-disable-next-line selector-max-compound-selectors, selector-max-specificity -- Copied from primer/react */
132
- & > .TreeViewItemContainer .FormControl-checkbox {
133
- background: var(--control-checked-bgColor-rest);
134
- border-color: var(--control-checked-borderColor-rest);
135
- transition: background-color, border-color 80ms cubic-bezier(0.32, 0, 0.67, 0) 0ms; /* unchecked -> checked */
136
-
137
- /* stylelint-disable-next-line max-nesting-depth, selector-max-compound-selectors, selector-max-specificity -- Copied from primer/react */
138
- &::before {
139
- visibility: visible;
140
- mask-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iMiIgdmlld0JveD0iMCAwIDEwIDIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMCAxQzAgMC40NDc3MTUgMC40NDc3MTUgMCAxIDBIOUM5LjU1MjI5IDAgMTAgMC40NDc3MTUgMTAgMUMxMCAxLjU1MjI4IDkuNTUyMjkgMiA5IDJIMUMwLjQ0NzcxNSAyIDAgMS41NTIyOCAwIDFaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K');
141
- animation: checkmarkIn 80ms cubic-bezier(0.65, 0, 0.35, 1) forwards 80ms;
142
- clip-path: none;
143
- }
144
- }
145
- }
146
- }
147
-
148
116
  & .TreeViewItemToggle {
149
117
  display: flex;
150
118
  height: 100%;
@@ -157,6 +125,7 @@
157
125
  grid-area: toggle;
158
126
  justify-content: center;
159
127
  align-items: flex-start;
128
+ cursor: pointer;
160
129
  }
161
130
 
162
131
  & .TreeViewItemToggleHover:hover {
@@ -168,10 +137,24 @@
168
137
  border-bottom-left-radius: var(--borderRadius-medium);
169
138
  }
170
139
 
140
+ /* stylelint-disable-next-line selector-no-qualifying-type */
141
+ & a.TreeViewItemContent:hover, button.TreeViewItemContent:hover {
142
+ text-decoration: underline;
143
+ text-decoration-color: var(--control-fgColor-rest);
144
+ }
145
+
171
146
  & .TreeViewItemContent {
172
147
  display: flex;
173
148
  height: 100%;
174
149
  padding: 0 var(--base-size-8);
150
+ outline: none;
151
+ text-align: left;
152
+ user-select: none;
153
+ background-color: transparent;
154
+ border: none;
155
+ touch-action: manipulation;
156
+ -webkit-tap-highlight-color: transparent;
157
+ cursor: pointer;
175
158
 
176
159
  /* The dynamic top and bottom padding to maintain the minimum item height for single line items */
177
160
  /* stylelint-disable-next-line primer/spacing */
@@ -194,9 +177,41 @@
194
177
  touch-action: manipulation;
195
178
  -webkit-tap-highlight-color: transparent;
196
179
  }
180
+
181
+ &[aria-checked='true'] {
182
+ & .FormControl-checkbox {
183
+ background: var(--control-checked-bgColor-rest);
184
+ border-color: var(--control-checked-borderColor-rest);
185
+ transition: background-color, border-color 80ms cubic-bezier(0.32, 0, 0.67, 0) 0ms; /* unchecked -> checked */
186
+
187
+ /* stylelint-disable-next-line max-nesting-depth, selector-max-specificity -- Copied from primer/react */
188
+ &::before {
189
+ visibility: visible;
190
+ transition: visibility 0s linear 0s;
191
+ animation: checkmarkIn 80ms cubic-bezier(0.65, 0, 0.35, 1) forwards 80ms;
192
+ }
193
+ }
194
+ }
195
+
196
+ &[aria-checked='mixed'] {
197
+ & .FormControl-checkbox {
198
+ background: var(--control-checked-bgColor-rest);
199
+ border-color: var(--control-checked-borderColor-rest);
200
+ transition: background-color, border-color 80ms cubic-bezier(0.32, 0, 0.67, 0) 0ms; /* unchecked -> checked */
201
+
202
+ /* stylelint-disable-next-line max-nesting-depth, selector-max-specificity -- Copied from primer/react */
203
+ &::before {
204
+ visibility: visible;
205
+ mask-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iMiIgdmlld0JveD0iMCAwIDEwIDIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMCAxQzAgMC40NDc3MTUgMC40NDc3MTUgMCAxIDBIOUM5LjU1MjI5IDAgMTAgMC40NDc3MTUgMTAgMUMxMCAxLjU1MjI4IDkuNTUyMjkgMiA5IDJIMUMwLjQ0NzcxNSAyIDAgMS41NTIyOCAwIDFaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K');
206
+ animation: checkmarkIn 80ms cubic-bezier(0.65, 0, 0.35, 1) forwards 80ms;
207
+ clip-path: none;
208
+ }
209
+ }
210
+ }
197
211
  }
198
212
 
199
213
  & .TreeViewItemContentText {
214
+ color: var(--control-fgColor-rest);
200
215
  flex: 1 1 auto;
201
216
  width: 0;
202
217
  }