openproject-primer_view_components 0.70.5 → 0.71.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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/app/assets/javascripts/components/primer/alpha/segmented_control.d.ts +2 -2
  4. data/app/assets/javascripts/components/primer/open_project/filterable_tree_view.d.ts +29 -0
  5. data/app/assets/javascripts/components/primer/open_project/tree_view/tree_view.d.ts +11 -1
  6. data/app/assets/javascripts/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.d.ts +5 -1
  7. data/app/assets/javascripts/components/primer/primer.d.ts +1 -0
  8. data/app/assets/javascripts/primer_view_components.js +1 -1
  9. data/app/assets/javascripts/primer_view_components.js.map +1 -1
  10. data/app/assets/styles/primer_view_components.css +1 -1
  11. data/app/assets/styles/primer_view_components.css.map +1 -1
  12. data/app/components/primer/alpha/segmented_control.d.ts +2 -2
  13. data/app/components/primer/alpha/segmented_control.js +12 -0
  14. data/app/components/primer/alpha/segmented_control.ts +16 -1
  15. data/app/components/primer/alpha/stack.css +1 -1
  16. data/app/components/primer/alpha/stack.css.json +5 -1
  17. data/app/components/primer/alpha/stack.css.map +1 -1
  18. data/app/components/primer/alpha/stack.pcss +13 -0
  19. data/app/components/primer/alpha/stack.rb +2 -1
  20. data/app/components/primer/open_project/filterable_tree_view/sub_tree.rb +39 -0
  21. data/app/components/primer/open_project/filterable_tree_view.d.ts +29 -0
  22. data/app/components/primer/open_project/filterable_tree_view.html.erb +28 -0
  23. data/app/components/primer/open_project/filterable_tree_view.js +409 -0
  24. data/app/components/primer/open_project/filterable_tree_view.rb +254 -0
  25. data/app/components/primer/open_project/filterable_tree_view.ts +492 -0
  26. data/app/components/primer/open_project/tree_view/node.rb +19 -3
  27. data/app/components/primer/open_project/tree_view/sub_tree_node.rb +14 -4
  28. data/app/components/primer/open_project/tree_view/tree_view.d.ts +11 -1
  29. data/app/components/primer/open_project/tree_view/tree_view.js +120 -20
  30. data/app/components/primer/open_project/tree_view/tree_view.ts +137 -18
  31. data/app/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.d.ts +5 -1
  32. data/app/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.js +27 -4
  33. data/app/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.ts +36 -5
  34. data/app/components/primer/open_project/tree_view.css +1 -1
  35. data/app/components/primer/open_project/tree_view.css.json +9 -0
  36. data/app/components/primer/open_project/tree_view.css.map +1 -1
  37. data/app/components/primer/open_project/tree_view.html.erb +4 -0
  38. data/app/components/primer/open_project/tree_view.pcss +48 -0
  39. data/app/components/primer/open_project/tree_view.rb +6 -1
  40. data/app/components/primer/primer.d.ts +1 -0
  41. data/app/components/primer/primer.js +1 -0
  42. data/app/components/primer/primer.ts +1 -0
  43. data/app/lib/primer/forms/base_component.rb +1 -1
  44. data/app/lib/primer/forms/dsl/text_field_input.rb +2 -0
  45. data/config/locales/en.yml +20 -0
  46. data/lib/primer/view_components/version.rb +2 -2
  47. data/previews/primer/open_project/filterable_tree_view_preview/_custom_select_js.html.erb +62 -0
  48. data/previews/primer/open_project/filterable_tree_view_preview/custom_checkbox_text.html.erb +26 -0
  49. data/previews/primer/open_project/filterable_tree_view_preview/custom_no_results_text.html.erb +28 -0
  50. data/previews/primer/open_project/filterable_tree_view_preview/custom_segmented_control.html.erb +31 -0
  51. data/previews/primer/open_project/filterable_tree_view_preview/default.html.erb +26 -0
  52. data/previews/primer/open_project/filterable_tree_view_preview/form_input.html.erb +32 -0
  53. data/previews/primer/open_project/filterable_tree_view_preview/playground.html.erb +26 -0
  54. data/previews/primer/open_project/filterable_tree_view_preview.rb +125 -0
  55. data/previews/primer/open_project/tree_view_preview/buttons.html.erb +4 -4
  56. data/previews/primer/open_project/tree_view_preview/default.html.erb +4 -4
  57. data/previews/primer/open_project/tree_view_preview/leaf_node_playground.html.erb +1 -1
  58. data/previews/primer/open_project/tree_view_preview/links.html.erb +4 -4
  59. data/previews/primer/open_project/tree_view_preview.rb +18 -8
  60. data/static/arguments.json +89 -3
  61. data/static/audited_at.json +2 -0
  62. data/static/constants.json +40 -1
  63. data/static/info_arch.json +220 -3
  64. data/static/previews.json +86 -0
  65. data/static/statuses.json +2 -0
  66. metadata +18 -2
@@ -7,6 +7,8 @@ import type {TreeViewNodeInfo} from '../../shared_events'
7
7
 
8
8
  type LoadingState = 'loading' | 'error' | 'success'
9
9
 
10
+ export type SelectStrategy = 'self' | 'descendants' | 'mixed_descendants'
11
+
10
12
  @controller
11
13
  export class TreeViewSubTreeNodeElement extends HTMLElement {
12
14
  @target node: HTMLElement
@@ -70,7 +72,7 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
70
72
  )
71
73
 
72
74
  const checkedMutationObserver = new MutationObserver(() => {
73
- if (this.selectStrategy !== 'descendants') return
75
+ if (this.selectStrategy !== 'mixed_descendants') return
74
76
 
75
77
  let checkType = 'unknown'
76
78
 
@@ -127,8 +129,12 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
127
129
  this.#update()
128
130
  }
129
131
 
130
- get selectStrategy(): string {
131
- return this.node.getAttribute('data-select-strategy') || 'descendants'
132
+ get selectStrategy(): SelectStrategy {
133
+ return (this.node.getAttribute('data-select-strategy') || 'descendants') as SelectStrategy
134
+ }
135
+
136
+ get level(): number {
137
+ return parseInt(this.node.getAttribute('aria-level') || '0')
132
138
  }
133
139
 
134
140
  disconnectedCallback() {
@@ -211,6 +217,12 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
211
217
  }
212
218
  }
213
219
 
220
+ *eachDirectDescendantSubTreeNode(): Generator<TreeViewSubTreeNodeElement> {
221
+ for (const subTree of this.subTree.querySelectorAll(':scope > tree-view-sub-tree-node')) {
222
+ yield subTree as TreeViewSubTreeNodeElement
223
+ }
224
+ }
225
+
214
226
  *eachDescendantNode(): Generator<Element> {
215
227
  for (const node of this.subTree.querySelectorAll('[role=treeitem]')) {
216
228
  yield node
@@ -299,6 +311,11 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
299
311
 
300
312
  switch (event.key) {
301
313
  case 'Enter':
314
+ if (this.treeView?.getNodeDisabledValue(node)) {
315
+ event.preventDefault()
316
+ break
317
+ }
318
+
302
319
  // eslint-disable-next-line no-restricted-syntax
303
320
  event.stopPropagation()
304
321
 
@@ -324,6 +341,11 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
324
341
  break
325
342
 
326
343
  case ' ':
344
+ if (this.treeView?.getNodeDisabledValue(node)) {
345
+ event.preventDefault()
346
+ break
347
+ }
348
+
327
349
  if (this.#checkboxElement) {
328
350
  // eslint-disable-next-line no-restricted-syntax
329
351
  event.stopPropagation()
@@ -344,6 +366,11 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
344
366
  }
345
367
 
346
368
  #handleCheckboxEvent(event: Event) {
369
+ if (this.treeView?.getNodeDisabledValue(this.node)) {
370
+ event.preventDefault()
371
+ return
372
+ }
373
+
347
374
  if (event.type !== 'click') return
348
375
 
349
376
  this.toggleChecked()
@@ -354,13 +381,13 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
354
381
  }
355
382
 
356
383
  toggleChecked() {
357
- const checkValue = this.node.getAttribute('aria-checked') || 'false'
384
+ const checkValue = this.treeView?.getNodeCheckedValue(this.node) || 'false'
358
385
  const newCheckValue = checkValue === 'false' ? 'true' : 'false'
359
386
  const nodeInfos: TreeViewNodeInfo[] = []
360
387
  const rootInfo = this.treeView?.infoFromNode(this.node, newCheckValue)
361
388
  if (rootInfo) nodeInfos.push(rootInfo)
362
389
 
363
- if (this.selectStrategy === 'descendants') {
390
+ if (this.selectStrategy === 'descendants' || this.selectStrategy === 'mixed_descendants') {
364
391
  for (const node of this.eachDescendantNode()) {
365
392
  const info = this.treeView?.infoFromNode(node, newCheckValue)
366
393
  if (info) nodeInfos.push(info)
@@ -439,6 +466,10 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
439
466
  get #checkboxElement(): HTMLElement | null {
440
467
  return this.querySelector('.TreeViewItemCheckbox')
441
468
  }
469
+
470
+ changeSelectStrategy(newStrategy: SelectStrategy) {
471
+ this.node.setAttribute('data-select-strategy', newStrategy)
472
+ }
442
473
  }
443
474
 
444
475
  if (!window.customElements.get('tree-view-sub-tree-node')) {
@@ -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);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%}
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 :has(.TreeViewItemContent[aria-disabled=true]){cursor:not-allowed}.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}[aria-disabled=true]:is(.TreeViewRootUlStyles .TreeViewItemContent){pointer-events:none}[aria-disabled=true]:is(.TreeViewRootUlStyles .TreeViewItemContent) .TreeViewItemContentText{color:var(--control-fgColor-disabled)}:is([aria-disabled=true]:is(.TreeViewRootUlStyles .TreeViewItemContent) .TreeViewItemVisual) svg,[aria-disabled=true]:is(.TreeViewRootUlStyles .TreeViewItemContent) .TreeViewItemVisual{fill:var(--control-fgColor-disabled)}@media (hover:hover){:is([aria-disabled=true]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox):hover{cursor:not-allowed}[aria-disabled=true]:is(.TreeViewRootUlStyles .TreeViewItemContent):hover{background-color:initial;cursor:not-allowed}}:is(.TreeViewRootUlStyles .TreeViewItemContent) ::highlight(primer-filterable-tree-view-search-results){background-color:var(--label-yellow-bgColor-active);color:var(--fgColor-default)}:is(.TreeViewRootUlStyles .TreeViewItemContent) mark{background-color:var(--label-yellow-bgColor-active);color:var(--fgColor-default)}.TreeViewRootUlStyles .TreeViewItemContentText{color:var(--control-fgColor-rest);flex:1 1 auto;-webkit-user-select: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%}
@@ -17,12 +17,21 @@
17
17
  ".TreeViewRootUlStyles .TreeViewItemToggleEnd",
18
18
  ".TreeViewRootUlStyles a.TreeViewItemContent:hover",
19
19
  ".TreeViewRootUlStyles button.TreeViewItemContent:hover",
20
+ ".TreeViewRootUlStyles :has(.TreeViewItemContent[aria-disabled=true])",
20
21
  ".TreeViewRootUlStyles .TreeViewItemContent",
21
22
  ":is(.TreeViewRootUlStyles .TreeViewItemContent) .TreeViewItemCheckbox",
22
23
  "[aria-checked=true]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox",
23
24
  ":is([aria-checked=true]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox):before",
24
25
  "[aria-checked=mixed]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox",
25
26
  ":is([aria-checked=mixed]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox):before",
27
+ "[aria-disabled=true]:is(.TreeViewRootUlStyles .TreeViewItemContent)",
28
+ "[aria-disabled=true]:is(.TreeViewRootUlStyles .TreeViewItemContent) .TreeViewItemContentText",
29
+ ":is([aria-disabled=true]:is(.TreeViewRootUlStyles .TreeViewItemContent) .TreeViewItemVisual) svg",
30
+ "[aria-disabled=true]:is(.TreeViewRootUlStyles .TreeViewItemContent) .TreeViewItemVisual",
31
+ ":is([aria-disabled=true]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox):hover",
32
+ "[aria-disabled=true]:is(.TreeViewRootUlStyles .TreeViewItemContent):hover",
33
+ ":is(.TreeViewRootUlStyles .TreeViewItemContent) ::highlight(primer-filterable-tree-view-search-results)",
34
+ ":is(.TreeViewRootUlStyles .TreeViewItemContent) mark",
26
35
  ".TreeViewRootUlStyles .TreeViewItemContentText",
27
36
  ".TreeViewRootUlStyles:where([data-truncate-text=true]) .TreeViewItemContentText",
28
37
  ".TreeViewRootUlStyles:where([data-truncate-text=false]) .TreeViewItemContentText",
@@ -1 +1 @@
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"]}
1
+ {"version":3,"sources":["tree_view.pcss"],"names":[],"mappings":"AAEA,sBAGE,eAAgB,CADhB,QAAS,CADT,SA+UF,CA9TE,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,qEACE,kBACF,CAEA,2CAWE,cAAe,CAVf,YAAa,CAmBb,8BAA+B,CAD/B,iBAAkB,CAjBlB,WAAY,CAgBZ,+EAAkF,CAdlF,YAAa,CADb,4BAA6B,CAc7B,mFAAsF,CAFtF,gFA2FF,CApFE,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,CAIJ,oEACE,mBA4BF,CA1BE,6FACE,qCACF,CAKE,yLACE,oCACF,CAIA,qBACE,qGACE,kBACF,CAKF,0EAEE,wBAA6B,CAD7B,kBAEF,CAPA,CAWJ,wGACE,mDAAoD,CACpD,4BACF,CAEA,qDACE,mDAAoD,CACpD,4BACF,CAGF,+CACE,iCAAkC,CAClC,aAAc,CAId,wBAAyB,CAHzB,OAIF,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 & :has(.TreeViewItemContent[aria-disabled=true]) {\n cursor: not-allowed;\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 &[aria-disabled=\"true\"] {\n pointer-events: none;\n\n & .TreeViewItemContentText {\n color: var(--control-fgColor-disabled);\n }\n\n & .TreeViewItemVisual {\n fill: var(--control-fgColor-disabled);\n\n & svg {\n fill: var(--control-fgColor-disabled);\n }\n }\n\n & .FormControl-checkbox {\n @media (hover: hover) {\n &:hover {\n cursor: not-allowed;\n }\n }\n }\n\n @media (hover: hover) {\n &:hover {\n cursor: not-allowed;\n background-color: transparent;\n }\n }\n }\n\n & ::highlight(primer-filterable-tree-view-search-results) {\n background-color: var(--label-yellow-bgColor-active);\n color: var(--fgColor-default);\n }\n\n & mark {\n background-color: var(--label-yellow-bgColor-active);\n color: var(--fgColor-default);\n }\n }\n\n & .TreeViewItemContentText {\n color: var(--control-fgColor-rest);\n flex: 1 1 auto;\n width: 0;\n /* Do not remove, as otherwise the filter result of the filterableTreeView will not be shown in Safari\n see: https://bugs.webkit.org/show_bug.cgi?id=278455 */\n -webkit-user-select: auto;\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,4 +1,8 @@
1
1
  <tree-view>
2
+ <% if acts_as_form_input? %>
3
+ <%= @form_arguments[:builder].hidden_field(@form_arguments[:name], multiple: true, skip_default_ids: true, form: "", data: { target: "tree-view.formInputPrototype" }) %>
4
+ <div data-target="tree-view.formInputContainer"></div>
5
+ <% end %>
2
6
  <%= render(Primer::BaseComponent.new(**@system_arguments)) do %>
3
7
  <% nodes.each do |node| %>
4
8
  <%= node %>
@@ -143,6 +143,10 @@
143
143
  text-decoration-color: var(--control-fgColor-rest);
144
144
  }
145
145
 
146
+ & :has(.TreeViewItemContent[aria-disabled=true]) {
147
+ cursor: not-allowed;
148
+ }
149
+
146
150
  & .TreeViewItemContent {
147
151
  display: flex;
148
152
  height: 100%;
@@ -208,12 +212,56 @@
208
212
  }
209
213
  }
210
214
  }
215
+
216
+ &[aria-disabled="true"] {
217
+ pointer-events: none;
218
+
219
+ & .TreeViewItemContentText {
220
+ color: var(--control-fgColor-disabled);
221
+ }
222
+
223
+ & .TreeViewItemVisual {
224
+ fill: var(--control-fgColor-disabled);
225
+
226
+ & svg {
227
+ fill: var(--control-fgColor-disabled);
228
+ }
229
+ }
230
+
231
+ & .FormControl-checkbox {
232
+ @media (hover: hover) {
233
+ &:hover {
234
+ cursor: not-allowed;
235
+ }
236
+ }
237
+ }
238
+
239
+ @media (hover: hover) {
240
+ &:hover {
241
+ cursor: not-allowed;
242
+ background-color: transparent;
243
+ }
244
+ }
245
+ }
246
+
247
+ & ::highlight(primer-filterable-tree-view-search-results) {
248
+ background-color: var(--label-yellow-bgColor-active);
249
+ color: var(--fgColor-default);
250
+ }
251
+
252
+ & mark {
253
+ background-color: var(--label-yellow-bgColor-active);
254
+ color: var(--fgColor-default);
255
+ }
211
256
  }
212
257
 
213
258
  & .TreeViewItemContentText {
214
259
  color: var(--control-fgColor-rest);
215
260
  flex: 1 1 auto;
216
261
  width: 0;
262
+ /* Do not remove, as otherwise the filter result of the filterableTreeView will not be shown in Safari
263
+ see: https://bugs.webkit.org/show_bug.cgi?id=278455 */
264
+ -webkit-user-select: auto;
217
265
  }
218
266
 
219
267
  &:where([data-truncate-text='true']) .TreeViewItemContentText {
@@ -406,8 +406,9 @@ module Primer
406
406
 
407
407
  # @param node_variant [Symbol] The variant to use for this node. <%= one_of(Primer::OpenProject::TreeView::NODE_VARIANT_OPTIONS) %>
408
408
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>.
409
- def initialize(node_variant: DEFAULT_NODE_VARIANT, **system_arguments)
409
+ def initialize(node_variant: DEFAULT_NODE_VARIANT, form_arguments: {}, **system_arguments)
410
410
  @system_arguments = deny_tag_argument(**system_arguments)
411
+ @form_arguments = form_arguments
411
412
 
412
413
  @node_variant = fetch_or_fallback(NODE_VARIANT_OPTIONS, node_variant, DEFAULT_NODE_VARIANT)
413
414
 
@@ -419,6 +420,10 @@ module Primer
419
420
  )
420
421
  end
421
422
 
423
+ def acts_as_form_input?
424
+ @form_arguments[:builder] && @form_arguments[:name]
425
+ end
426
+
422
427
  private
423
428
 
424
429
  def before_render
@@ -37,3 +37,4 @@ import './open_project/tree_view/tree_view';
37
37
  import './open_project/tree_view/tree_view_icon_pair_element';
38
38
  import './open_project/tree_view/tree_view_sub_tree_node_element';
39
39
  import './open_project/tree_view/tree_view_include_fragment_element';
40
+ import './open_project/filterable_tree_view';
@@ -37,3 +37,4 @@ import './open_project/tree_view/tree_view';
37
37
  import './open_project/tree_view/tree_view_icon_pair_element';
38
38
  import './open_project/tree_view/tree_view_sub_tree_node_element';
39
39
  import './open_project/tree_view/tree_view_include_fragment_element';
40
+ import './open_project/filterable_tree_view';
@@ -37,3 +37,4 @@ import './open_project/tree_view/tree_view'
37
37
  import './open_project/tree_view/tree_view_icon_pair_element'
38
38
  import './open_project/tree_view/tree_view_sub_tree_node_element'
39
39
  import './open_project/tree_view/tree_view_include_fragment_element'
40
+ import './open_project/filterable_tree_view'
@@ -14,7 +14,7 @@ module Primer
14
14
  )
15
15
  end
16
16
 
17
- delegate :required?, :disabled?, :hidden?, to: :@input
17
+ delegate :required?, :disabled?, :hidden?, :merge_input_arguments!, to: :@input
18
18
 
19
19
  def perform_render(&block)
20
20
  return "" unless render?
@@ -41,6 +41,8 @@ module Primer
41
41
  add_input_data(:target, "primer-text-field.inputElement #{system_arguments.dig(:data, :target) || ''}")
42
42
  add_input_classes("FormControl-inset") if inset?
43
43
  add_input_classes("FormControl-monospace") if monospace?
44
+
45
+ yield(self) if block_given?
44
46
  end
45
47
 
46
48
  alias show_clear_button? show_clear_button
@@ -0,0 +1,20 @@
1
+ en:
2
+ button_back: "Back"
3
+ button_cancel: "Cancel"
4
+ button_close: "Close"
5
+ button_delete: "Delete"
6
+ button_delete_permanently: "Delete permanently"
7
+ button_filter: "Filter"
8
+ button_save: "Save"
9
+
10
+ filterable_tree_view:
11
+ filter_mode:
12
+ all: "All"
13
+ label: "Filter mode"
14
+ selected: "Selected"
15
+ include_sub_items: "Include sub-items"
16
+ no_results_text: "No results"
17
+
18
+ label_title: "Title"
19
+ label_loading: "Loading..."
20
+ label_more: "More"
@@ -5,8 +5,8 @@ module Primer
5
5
  module ViewComponents
6
6
  module VERSION
7
7
  MAJOR = 0
8
- MINOR = 70
9
- PATCH = 5
8
+ MINOR = 71
9
+ PATCH = 0
10
10
 
11
11
  STRING = [MAJOR, MINOR, PATCH].join(".")
12
12
  end
@@ -0,0 +1,62 @@
1
+ <script>
2
+ function ready(fn) {
3
+ if (document.readyState !== 'loading') {
4
+ fn()
5
+ } else {
6
+ document.addEventListener('DOMContentLoaded', fn)
7
+ }
8
+ }
9
+
10
+ ready(() => {
11
+ const filterableTreeView = document.querySelector('filterable-tree-view')
12
+ filterableTreeView.filterFn = (node, query, filterMode) => {
13
+ const ranges = []
14
+
15
+ if (query.length > 0) {
16
+ const lowercaseQuery = query.toLowerCase()
17
+ const treeWalker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT)
18
+ let currentNode = treeWalker.nextNode()
19
+
20
+ while (currentNode) {
21
+ const lowercaseNodeText = currentNode.textContent?.toLocaleLowerCase() || ''
22
+ let startIndex = 0
23
+
24
+ while (startIndex < lowercaseNodeText.length) {
25
+ const index = lowercaseNodeText.indexOf(lowercaseQuery, startIndex)
26
+ if (index === -1) break
27
+
28
+ const range = new Range()
29
+ range.setStart(currentNode, index)
30
+ range.setEnd(currentNode, index + lowercaseQuery.length)
31
+ ranges.push(range)
32
+
33
+ startIndex = index + lowercaseQuery.length
34
+ }
35
+
36
+ currentNode = treeWalker.nextNode()
37
+ }
38
+ }
39
+
40
+ if (ranges.length === 0 && query.length > 0) {
41
+ return null
42
+ }
43
+
44
+ switch (filterMode) {
45
+ case 'teacher': {
46
+ // Only match nodes that are teachers
47
+ if (!node.dataset.path.includes('Students')) {
48
+ return ranges
49
+ }
50
+
51
+ break
52
+ }
53
+
54
+ case 'all': {
55
+ return ranges
56
+ }
57
+ }
58
+
59
+ return null
60
+ }
61
+ })
62
+ </script>
@@ -0,0 +1,26 @@
1
+ <%= render(Primer::OpenProject::FilterableTreeView.new(include_sub_items_check_box_arguments: { name: :include_sub_items, label: "Including pupils" })) do |tree| %>
2
+ <% tree.with_sub_tree(label: "Students", expanded: expanded) do |hogwarts| %>
3
+ <% hogwarts.with_sub_tree(label: "Ravenclaw", expanded: expanded) do |ravenclaw| %>
4
+ <% ravenclaw.with_leaf(label: "Luna Lovegood") %>
5
+ <% end %>
6
+
7
+ <% hogwarts.with_sub_tree(label: "Slytherin", expanded: expanded) do |hufflepuff| %>
8
+ <% hufflepuff.with_leaf(label: "Draco Malfoy") %>
9
+ <% end %>
10
+
11
+ <% hogwarts.with_sub_tree(label: "Hufflepuff", expanded: expanded) do |hufflepuff| %>
12
+ <% hufflepuff.with_leaf(label: "Susan Bones") %>
13
+ <% end %>
14
+
15
+ <% hogwarts.with_sub_tree(label: "Gryffindor", expanded: expanded) do |hufflepuff| %>
16
+ <% hufflepuff.with_leaf(label: "Harry Potter") %>
17
+ <% hufflepuff.with_leaf(label: "Ronald Weasley") %>
18
+ <% hufflepuff.with_leaf(label: "Hermione Granger") %>
19
+ <% end %>
20
+ <% end %>
21
+
22
+ <% tree.with_leaf(label: "Albus Dumbledore") %>
23
+ <% tree.with_leaf(label: "Minerva McGonagall") %>
24
+ <% tree.with_leaf(label: "Severus Snape") %>
25
+ <% tree.with_leaf(label: "Rubeus Hagrid") %>
26
+ <% end %>
@@ -0,0 +1,28 @@
1
+ <%= render(Primer::OpenProject::FilterableTreeView.new(
2
+ filter_input_arguments: {placeholder: "Search me!", name: "filter", label: "Filter", visually_hide_label: true},
3
+ no_results_node_arguments: { label: "All wizards and witches have left the building" })) do |tree| %>
4
+ <% tree.with_sub_tree(label: "Students", expanded: expanded) do |hogwarts| %>
5
+ <% hogwarts.with_sub_tree(label: "Ravenclaw", expanded: expanded) do |ravenclaw| %>
6
+ <% ravenclaw.with_leaf(label: "Luna Lovegood") %>
7
+ <% end %>
8
+
9
+ <% hogwarts.with_sub_tree(label: "Slytherin", expanded: expanded) do |hufflepuff| %>
10
+ <% hufflepuff.with_leaf(label: "Draco Malfoy") %>
11
+ <% end %>
12
+
13
+ <% hogwarts.with_sub_tree(label: "Hufflepuff", expanded: expanded) do |hufflepuff| %>
14
+ <% hufflepuff.with_leaf(label: "Susan Bones") %>
15
+ <% end %>
16
+
17
+ <% hogwarts.with_sub_tree(label: "Gryffindor", expanded: expanded) do |hufflepuff| %>
18
+ <% hufflepuff.with_leaf(label: "Harry Potter") %>
19
+ <% hufflepuff.with_leaf(label: "Ronald Weasley") %>
20
+ <% hufflepuff.with_leaf(label: "Hermione Granger") %>
21
+ <% end %>
22
+ <% end %>
23
+
24
+ <% tree.with_leaf(label: "Albus Dumbledore") %>
25
+ <% tree.with_leaf(label: "Minerva McGonagall") %>
26
+ <% tree.with_leaf(label: "Severus Snape") %>
27
+ <% tree.with_leaf(label: "Rubeus Hagrid") %>
28
+ <% end %>
@@ -0,0 +1,31 @@
1
+ <%= render(Primer::OpenProject::FilterableTreeView.new) do |tree| %>
2
+ <% tree.with_filter_mode(name: "teacher", label: "Teacher") %>
3
+ <% tree.with_filter_mode(name: "all", label: "All", selected: true) %>
4
+
5
+ <% tree.with_sub_tree(label: "Students", expanded: expanded) do |hogwarts| %>
6
+ <% hogwarts.with_sub_tree(label: "Ravenclaw", expanded: expanded) do |ravenclaw| %>
7
+ <% ravenclaw.with_leaf(label: "Luna Lovegood") %>
8
+ <% end %>
9
+
10
+ <% hogwarts.with_sub_tree(label: "Slytherin", expanded: expanded) do |hufflepuff| %>
11
+ <% hufflepuff.with_leaf(label: "Draco Malfoy") %>
12
+ <% end %>
13
+
14
+ <% hogwarts.with_sub_tree(label: "Hufflepuff", expanded: expanded) do |hufflepuff| %>
15
+ <% hufflepuff.with_leaf(label: "Susan Bones") %>
16
+ <% end %>
17
+
18
+ <% hogwarts.with_sub_tree(label: "Gryffindor", expanded: expanded) do |hufflepuff| %>
19
+ <% hufflepuff.with_leaf(label: "Harry Potter") %>
20
+ <% hufflepuff.with_leaf(label: "Ronald Weasley") %>
21
+ <% hufflepuff.with_leaf(label: "Hermione Granger") %>
22
+ <% end %>
23
+ <% end %>
24
+
25
+ <% tree.with_leaf(label: "Albus Dumbledore") %>
26
+ <% tree.with_leaf(label: "Minerva McGonagall") %>
27
+ <% tree.with_leaf(label: "Severus Snape") %>
28
+ <% tree.with_leaf(label: "Rubeus Hagrid") %>
29
+ <% end %>
30
+
31
+ <%= render partial: "primer/open_project/filterable_tree_view_preview/custom_select_js", locals: { } %>
@@ -0,0 +1,26 @@
1
+ <%= render(Primer::OpenProject::FilterableTreeView.new) do |tree| %>
2
+ <% tree.with_sub_tree(label: "Students", expanded: expanded) do |hogwarts| %>
3
+ <% hogwarts.with_sub_tree(label: "Ravenclaw", expanded: expanded) do |ravenclaw| %>
4
+ <% ravenclaw.with_leaf(label: "Luna Lovegood") %>
5
+ <% end %>
6
+
7
+ <% hogwarts.with_sub_tree(label: "Slytherin", expanded: expanded) do |hufflepuff| %>
8
+ <% hufflepuff.with_leaf(label: "Draco Malfoy") %>
9
+ <% end %>
10
+
11
+ <% hogwarts.with_sub_tree(label: "Hufflepuff", expanded: expanded) do |hufflepuff| %>
12
+ <% hufflepuff.with_leaf(label: "Susan Bones") %>
13
+ <% end %>
14
+
15
+ <% hogwarts.with_sub_tree(label: "Gryffindor", expanded: expanded) do |hufflepuff| %>
16
+ <% hufflepuff.with_leaf(label: "Harry Potter") %>
17
+ <% hufflepuff.with_leaf(label: "Ronald Weasley") %>
18
+ <% hufflepuff.with_leaf(label: "Hermione Granger") %>
19
+ <% end %>
20
+ <% end %>
21
+
22
+ <% tree.with_leaf(label: "Albus Dumbledore") %>
23
+ <% tree.with_leaf(label: "Minerva McGonagall") %>
24
+ <% tree.with_leaf(label: "Severus Snape") %>
25
+ <% tree.with_leaf(label: "Rubeus Hagrid") %>
26
+ <% end %>
@@ -0,0 +1,32 @@
1
+ <%= form_with(url: primer_view_components.generic_form_submission_path(format: :json)) do |f| %>
2
+ <%= render(Primer::Alpha::Stack.new) do %>
3
+ <%= render(Primer::OpenProject::FilterableTreeView.new(form_arguments: { builder: f, name: "characters" })) do |tree| %>
4
+ <% tree.with_sub_tree(label: "Students", expanded: expanded) do |hogwarts| %>
5
+ <% hogwarts.with_sub_tree(label: "Ravenclaw", expanded: expanded) do |ravenclaw| %>
6
+ <% ravenclaw.with_leaf(label: "Luna Lovegood") %>
7
+ <% end %>
8
+
9
+ <% hogwarts.with_sub_tree(label: "Slytherin", expanded: expanded) do |hufflepuff| %>
10
+ <% hufflepuff.with_leaf(label: "Draco Malfoy") %>
11
+ <% end %>
12
+
13
+ <% hogwarts.with_sub_tree(label: "Hufflepuff", expanded: expanded) do |hufflepuff| %>
14
+ <% hufflepuff.with_leaf(label: "Susan Bones") %>
15
+ <% end %>
16
+
17
+ <% hogwarts.with_sub_tree(label: "Gryffindor", expanded: expanded) do |hufflepuff| %>
18
+ <% hufflepuff.with_leaf(label: "Harry Potter") %>
19
+ <% hufflepuff.with_leaf(label: "Ronald Weasley") %>
20
+ <% hufflepuff.with_leaf(label: "Hermione Granger") %>
21
+ <% end %>
22
+ <% end %>
23
+
24
+ <% tree.with_leaf(label: "Albus Dumbledore") %>
25
+ <% tree.with_leaf(label: "Minerva McGonagall") %>
26
+ <% tree.with_leaf(label: "Severus Snape") %>
27
+ <% tree.with_leaf(label: "Rubeus Hagrid") %>
28
+ <% end %>
29
+
30
+ <%= render(Primer::Alpha::SubmitButton.new(name: :submit, label: "Submit")) %>
31
+ <% end %>
32
+ <% end %>
@@ -0,0 +1,26 @@
1
+ <%= render(Primer::OpenProject::FilterableTreeView.new) do |tree| %>
2
+ <% tree.with_sub_tree(label: "Students", expanded: expanded) do |hogwarts| %>
3
+ <% hogwarts.with_sub_tree(label: "Ravenclaw", expanded: expanded) do |ravenclaw| %>
4
+ <% ravenclaw.with_leaf(label: "Luna Lovegood") %>
5
+ <% end %>
6
+
7
+ <% hogwarts.with_sub_tree(label: "Slytherin", expanded: expanded) do |hufflepuff| %>
8
+ <% hufflepuff.with_leaf(label: "Draco Malfoy") %>
9
+ <% end %>
10
+
11
+ <% hogwarts.with_sub_tree(label: "Hufflepuff", expanded: expanded) do |hufflepuff| %>
12
+ <% hufflepuff.with_leaf(label: "Susan Bones") %>
13
+ <% end %>
14
+
15
+ <% hogwarts.with_sub_tree(label: "Gryffindor", expanded: expanded) do |hufflepuff| %>
16
+ <% hufflepuff.with_leaf(label: "Harry Potter") %>
17
+ <% hufflepuff.with_leaf(label: "Ronald Weasley") %>
18
+ <% hufflepuff.with_leaf(label: "Hermione Granger") %>
19
+ <% end %>
20
+ <% end %>
21
+
22
+ <% tree.with_leaf(label: "Albus Dumbledore") %>
23
+ <% tree.with_leaf(label: "Minerva McGonagall") %>
24
+ <% tree.with_leaf(label: "Severus Snape") %>
25
+ <% tree.with_leaf(label: "Rubeus Hagrid") %>
26
+ <% end %>