@openproject/primer-view-components 0.70.5 → 0.71.0-rc.5dc134b91

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 (24) hide show
  1. package/app/assets/javascripts/components/primer/alpha/segmented_control.d.ts +2 -2
  2. package/app/assets/javascripts/components/primer/open_project/filterable_tree_view.d.ts +29 -0
  3. package/app/assets/javascripts/components/primer/open_project/tree_view/tree_view.d.ts +11 -1
  4. package/app/assets/javascripts/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.d.ts +5 -1
  5. package/app/assets/javascripts/components/primer/primer.d.ts +1 -0
  6. package/app/assets/javascripts/primer_view_components.js +1 -1
  7. package/app/assets/javascripts/primer_view_components.js.map +1 -1
  8. package/app/assets/styles/primer_view_components.css +1 -1
  9. package/app/assets/styles/primer_view_components.css.map +1 -1
  10. package/app/components/primer/alpha/segmented_control.d.ts +2 -2
  11. package/app/components/primer/alpha/segmented_control.js +12 -0
  12. package/app/components/primer/alpha/stack.css +1 -1
  13. package/app/components/primer/alpha/stack.css.json +5 -1
  14. package/app/components/primer/open_project/filterable_tree_view.d.ts +29 -0
  15. package/app/components/primer/open_project/filterable_tree_view.js +409 -0
  16. package/app/components/primer/open_project/tree_view/tree_view.d.ts +11 -1
  17. package/app/components/primer/open_project/tree_view/tree_view.js +120 -20
  18. package/app/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.d.ts +5 -1
  19. package/app/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.js +27 -4
  20. package/app/components/primer/open_project/tree_view.css +1 -1
  21. package/app/components/primer/open_project/tree_view.css.json +9 -0
  22. package/app/components/primer/primer.d.ts +1 -0
  23. package/app/components/primer/primer.js +1 -0
  24. package/package.json +1 -1
@@ -15,8 +15,8 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
15
15
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
16
16
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
17
17
  };
18
- var _TreeViewElement_instances, _TreeViewElement_abortController, _TreeViewElement_autoExpandFrom, _TreeViewElement_eventIsActivation, _TreeViewElement_nodeForEvent, _TreeViewElement_handleNodeEvent, _TreeViewElement_eventIsCheckboxToggle, _TreeViewElement_handleCheckboxToggle, _TreeViewElement_handleNodeActivated, _TreeViewElement_handleNodeFocused, _TreeViewElement_handleNodeKeyboardEvent, _TreeViewElement_setNodeCheckedValue;
19
- import { controller } from '@github/catalyst';
18
+ var _TreeViewElement_instances, _TreeViewElement_abortController, _TreeViewElement_autoExpandFrom, _TreeViewElement_eventIsActivation, _TreeViewElement_nodeForEvent, _TreeViewElement_handleNodeEvent, _TreeViewElement_eventIsCheckboxToggle, _TreeViewElement_handleCheckboxToggle, _TreeViewElement_handleNodeActivated, _TreeViewElement_handleNodeFocused, _TreeViewElement_handleNodeKeyboardEvent;
19
+ import { controller, target } from '@github/catalyst';
20
20
  import { useRovingTabIndex } from './tree_view_roving_tab_index';
21
21
  let TreeViewElement = class TreeViewElement extends HTMLElement {
22
22
  constructor() {
@@ -43,12 +43,53 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
43
43
  }
44
44
  }
45
45
  }).observe(this, { childList: true, subtree: true });
46
+ const updateInputsObserver = new MutationObserver(mutations => {
47
+ if (!this.formInputContainer)
48
+ return;
49
+ // There is another MutationObserver in TreeViewSubTreeNodeElement that manages checking/unchecking
50
+ // nodes based on the component's select strategy. These two observers can conflict and cause infinite
51
+ // looping, so we make sure something actually changed before computing inputs again.
52
+ const somethingChanged = mutations.some(m => {
53
+ if (!(m.target instanceof HTMLElement))
54
+ return false;
55
+ return m.target.getAttribute('aria-checked') !== m.oldValue;
56
+ });
57
+ if (!somethingChanged)
58
+ return;
59
+ const newInputs = [];
60
+ // eslint-disable-next-line custom-elements/no-dom-traversal-in-connectedcallback
61
+ for (const node of this.querySelectorAll('[role=treeitem][aria-checked=true]')) {
62
+ const newInput = this.formInputPrototype.cloneNode();
63
+ newInput.removeAttribute('data-target');
64
+ newInput.removeAttribute('form');
65
+ const payload = {
66
+ path: this.getNodePath(node),
67
+ };
68
+ const inputValue = this.getFormInputValueForNode(node);
69
+ if (inputValue)
70
+ payload.value = inputValue;
71
+ newInput.value = JSON.stringify(payload);
72
+ newInputs.push(newInput);
73
+ }
74
+ this.formInputContainer.replaceChildren(...newInputs);
75
+ });
76
+ updateInputsObserver.observe(this, {
77
+ childList: true,
78
+ subtree: true,
79
+ attributeFilter: ['aria-checked'],
80
+ });
46
81
  // eslint-disable-next-line github/no-then -- We don't want to wait for this to resolve, just get on with it
47
82
  customElements.whenDefined('tree-view-sub-tree-node').then(() => {
48
83
  // depends on TreeViewSubTreeNodeElement#eachAncestorSubTreeNode, which may not be defined yet
49
84
  __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_autoExpandFrom).call(this, this);
50
85
  });
51
86
  }
87
+ rootLeafNodes() {
88
+ return this.querySelectorAll(':scope > ul > li > .TreeViewItemContainer [role=treeitem]');
89
+ }
90
+ rootSubTreeNodes() {
91
+ return this.querySelectorAll(':scope > ul > tree-view-sub-tree-node');
92
+ }
52
93
  disconnectedCallback() {
53
94
  __classPrivateFieldGet(this, _TreeViewElement_abortController, "f").abort();
54
95
  }
@@ -58,6 +99,9 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
58
99
  __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_handleNodeEvent).call(this, node, event);
59
100
  }
60
101
  }
102
+ getFormInputValueForNode(node) {
103
+ return node.getAttribute('data-value');
104
+ }
61
105
  getNodePath(node) {
62
106
  const rawPath = node.getAttribute('data-path');
63
107
  if (rawPath) {
@@ -101,13 +145,13 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
101
145
  const node = this.nodeAtPath(path);
102
146
  if (!node)
103
147
  return;
104
- __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_setNodeCheckedValue).call(this, node, 'true');
148
+ this.setNodeCheckedValue(node, 'true');
105
149
  }
106
150
  uncheckAtPath(path) {
107
151
  const node = this.nodeAtPath(path);
108
152
  if (!node)
109
153
  return;
110
- __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_setNodeCheckedValue).call(this, node, 'false');
154
+ this.setNodeCheckedValue(node, 'false');
111
155
  }
112
156
  toggleCheckedAtPath(path) {
113
157
  const node = this.nodeAtPath(path);
@@ -128,6 +172,12 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
128
172
  return 'false';
129
173
  return this.getNodeCheckedValue(node);
130
174
  }
175
+ disabledValueAtPath(path) {
176
+ const node = this.nodeAtPath(path);
177
+ if (!node)
178
+ return false;
179
+ return this.getNodeDisabledValue(node);
180
+ }
131
181
  nodeAtPath(path, selector) {
132
182
  const pathStr = JSON.stringify(path);
133
183
  return this.querySelector(`${selector || ''}[data-path="${CSS.escape(pathStr)}"]`);
@@ -141,9 +191,23 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
141
191
  leafAtPath(path) {
142
192
  return this.nodeAtPath(path, '[data-node-type=leaf]');
143
193
  }
194
+ setNodeCheckedValue(node, value) {
195
+ node.setAttribute('aria-checked', value.toString());
196
+ }
144
197
  getNodeCheckedValue(node) {
145
198
  return (node.getAttribute('aria-checked') || 'false');
146
199
  }
200
+ getNodeDisabledValue(node) {
201
+ return node.getAttribute('aria-disabled') === 'true';
202
+ }
203
+ setNodeDisabledValue(node, disabled) {
204
+ if (disabled) {
205
+ node.setAttribute('aria-disabled', 'true');
206
+ }
207
+ else {
208
+ node.removeAttribute('aria-disabled');
209
+ }
210
+ }
147
211
  nodeHasCheckBox(node) {
148
212
  return node.querySelector('.TreeViewItemCheckbox') !== null;
149
213
  }
@@ -160,6 +224,11 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
160
224
  }
161
225
  }
162
226
  }
227
+ changeSelectStrategy(newStrategy) {
228
+ for (const subTreeNode of this.querySelectorAll('tree-view-sub-tree-node')) {
229
+ subTreeNode.changeSelectStrategy(newStrategy);
230
+ }
231
+ }
163
232
  // PRIVATE API METHOD
164
233
  //
165
234
  // This would normally be marked private, but it's called by TreeViewSubTreeNodes
@@ -189,22 +258,22 @@ _TreeViewElement_eventIsActivation = function _TreeViewElement_eventIsActivation
189
258
  return event.type === 'click';
190
259
  };
191
260
  _TreeViewElement_nodeForEvent = function _TreeViewElement_nodeForEvent(event) {
192
- const target = event.target;
193
- const node = target.closest('[role=treeitem]');
261
+ const eventTarget = event.target;
262
+ const node = eventTarget.closest('[role=treeitem]');
194
263
  if (!node)
195
264
  return null;
196
- if (target.closest('.TreeViewItemToggle'))
265
+ if (eventTarget.closest('.TreeViewItemToggle'))
197
266
  return null;
198
- if (target.closest('.TreeViewItemLeadingAction'))
267
+ if (eventTarget.closest('.TreeViewItemLeadingAction'))
199
268
  return null;
200
269
  return node;
201
270
  };
202
271
  _TreeViewElement_handleNodeEvent = function _TreeViewElement_handleNodeEvent(node, event) {
203
272
  if (__classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_eventIsCheckboxToggle).call(this, event, node)) {
204
- __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_handleCheckboxToggle).call(this, node);
273
+ __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_handleCheckboxToggle).call(this, event, node);
205
274
  }
206
275
  else if (__classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_eventIsActivation).call(this, event)) {
207
- __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_handleNodeActivated).call(this, node);
276
+ __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_handleNodeActivated).call(this, event, node);
208
277
  }
209
278
  else if (event.type === 'focusin') {
210
279
  __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_handleNodeFocused).call(this, node);
@@ -216,19 +285,43 @@ _TreeViewElement_handleNodeEvent = function _TreeViewElement_handleNodeEvent(nod
216
285
  _TreeViewElement_eventIsCheckboxToggle = function _TreeViewElement_eventIsCheckboxToggle(event, node) {
217
286
  return event.type === 'click' && this.nodeHasCheckBox(node);
218
287
  };
219
- _TreeViewElement_handleCheckboxToggle = function _TreeViewElement_handleCheckboxToggle(node) {
220
- // only handle checking of leaf nodes
288
+ _TreeViewElement_handleCheckboxToggle = function _TreeViewElement_handleCheckboxToggle(event, node) {
289
+ if (this.getNodeDisabledValue(node)) {
290
+ event.preventDefault();
291
+ return;
292
+ }
293
+ // only handle checking of leaf nodes, see TreeViewSubTreeNodeElement for the code that
294
+ // handles checking sub tree items.
221
295
  const type = this.getNodeType(node);
222
296
  if (type !== 'leaf')
223
297
  return;
298
+ const checkValue = this.getNodeCheckedValue(node);
299
+ const newCheckValue = checkValue === 'false' ? 'true' : 'false';
300
+ const nodeInfo = this.infoFromNode(node, newCheckValue);
301
+ const checkSuccess = this.dispatchEvent(new CustomEvent('treeViewBeforeNodeChecked', {
302
+ bubbles: true,
303
+ cancelable: true,
304
+ detail: [nodeInfo],
305
+ }));
306
+ if (!checkSuccess)
307
+ return;
224
308
  if (this.getNodeCheckedValue(node) === 'true') {
225
- __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_setNodeCheckedValue).call(this, node, 'false');
309
+ this.setNodeCheckedValue(node, 'false');
226
310
  }
227
311
  else {
228
- __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_setNodeCheckedValue).call(this, node, 'true');
312
+ this.setNodeCheckedValue(node, 'true');
229
313
  }
314
+ this.dispatchEvent(new CustomEvent('treeViewNodeChecked', {
315
+ bubbles: true,
316
+ cancelable: true,
317
+ detail: [nodeInfo],
318
+ }));
230
319
  };
231
- _TreeViewElement_handleNodeActivated = function _TreeViewElement_handleNodeActivated(node) {
320
+ _TreeViewElement_handleNodeActivated = function _TreeViewElement_handleNodeActivated(event, node) {
321
+ if (this.getNodeDisabledValue(node)) {
322
+ event.preventDefault();
323
+ return;
324
+ }
232
325
  // do not emit activation events for buttons and anchors, since it is assumed any activation
233
326
  // behavior for these element types is user- or browser-defined
234
327
  if (!(node instanceof HTMLDivElement))
@@ -262,13 +355,17 @@ _TreeViewElement_handleNodeKeyboardEvent = function _TreeViewElement_handleNodeK
262
355
  switch (event.key) {
263
356
  case ' ':
264
357
  case 'Enter':
358
+ if (this.getNodeDisabledValue(node)) {
359
+ event.preventDefault();
360
+ break;
361
+ }
265
362
  if (this.nodeHasCheckBox(node)) {
266
363
  event.preventDefault();
267
364
  if (this.getNodeCheckedValue(node) === 'true') {
268
- __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_setNodeCheckedValue).call(this, node, 'false');
365
+ this.setNodeCheckedValue(node, 'false');
269
366
  }
270
367
  else {
271
- __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_setNodeCheckedValue).call(this, node, 'true');
368
+ this.setNodeCheckedValue(node, 'true');
272
369
  }
273
370
  }
274
371
  else if (node instanceof HTMLAnchorElement) {
@@ -278,9 +375,12 @@ _TreeViewElement_handleNodeKeyboardEvent = function _TreeViewElement_handleNodeK
278
375
  break;
279
376
  }
280
377
  };
281
- _TreeViewElement_setNodeCheckedValue = function _TreeViewElement_setNodeCheckedValue(node, value) {
282
- node.setAttribute('aria-checked', value.toString());
283
- };
378
+ __decorate([
379
+ target
380
+ ], TreeViewElement.prototype, "formInputContainer", void 0);
381
+ __decorate([
382
+ target
383
+ ], TreeViewElement.prototype, "formInputPrototype", void 0);
284
384
  TreeViewElement = __decorate([
285
385
  controller
286
386
  ], TreeViewElement);
@@ -2,6 +2,7 @@ import { TreeViewIconPairElement } from './tree_view_icon_pair_element';
2
2
  import { TreeViewIncludeFragmentElement } from './tree_view_include_fragment_element';
3
3
  import { TreeViewElement } from './tree_view';
4
4
  type LoadingState = 'loading' | 'error' | 'success';
5
+ export type SelectStrategy = 'self' | 'descendants' | 'mixed_descendants';
5
6
  export declare class TreeViewSubTreeNodeElement extends HTMLElement {
6
7
  #private;
7
8
  node: HTMLElement;
@@ -19,7 +20,8 @@ export declare class TreeViewSubTreeNodeElement extends HTMLElement {
19
20
  set expanded(newValue: boolean);
20
21
  get loadingState(): LoadingState;
21
22
  set loadingState(newState: LoadingState);
22
- get selectStrategy(): string;
23
+ get selectStrategy(): SelectStrategy;
24
+ get level(): number;
23
25
  disconnectedCallback(): void;
24
26
  handleEvent(event: Event): void;
25
27
  expand(): void;
@@ -27,11 +29,13 @@ export declare class TreeViewSubTreeNodeElement extends HTMLElement {
27
29
  toggle(): void;
28
30
  get nodes(): NodeListOf<Element>;
29
31
  eachDirectDescendantNode(): Generator<Element>;
32
+ eachDirectDescendantSubTreeNode(): Generator<TreeViewSubTreeNodeElement>;
30
33
  eachDescendantNode(): Generator<Element>;
31
34
  eachAncestorSubTreeNode(): Generator<TreeViewSubTreeNodeElement>;
32
35
  get isEmpty(): boolean;
33
36
  get treeView(): TreeViewElement | null;
34
37
  toggleChecked(): void;
38
+ changeSelectStrategy(newStrategy: SelectStrategy): void;
35
39
  }
36
40
  declare global {
37
41
  interface Window {
@@ -48,7 +48,7 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
48
48
  }, { signal });
49
49
  });
50
50
  const checkedMutationObserver = new MutationObserver(() => {
51
- if (this.selectStrategy !== 'descendants')
51
+ if (this.selectStrategy !== 'mixed_descendants')
52
52
  return;
53
53
  let checkType = 'unknown';
54
54
  for (const node of this.eachDirectDescendantNode()) {
@@ -95,7 +95,10 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
95
95
  __classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_update).call(this);
96
96
  }
97
97
  get selectStrategy() {
98
- return this.node.getAttribute('data-select-strategy') || 'descendants';
98
+ return (this.node.getAttribute('data-select-strategy') || 'descendants');
99
+ }
100
+ get level() {
101
+ return parseInt(this.node.getAttribute('aria-level') || '0');
99
102
  }
100
103
  disconnectedCallback() {
101
104
  __classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_abortController, "f").abort();
@@ -160,6 +163,11 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
160
163
  yield subTree;
161
164
  }
162
165
  }
166
+ *eachDirectDescendantSubTreeNode() {
167
+ for (const subTree of this.subTree.querySelectorAll(':scope > tree-view-sub-tree-node')) {
168
+ yield subTree;
169
+ }
170
+ }
163
171
  *eachDescendantNode() {
164
172
  for (const node of this.subTree.querySelectorAll('[role=treeitem]')) {
165
173
  yield node;
@@ -182,13 +190,13 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
182
190
  return this.closest('tree-view');
183
191
  }
184
192
  toggleChecked() {
185
- const checkValue = this.node.getAttribute('aria-checked') || 'false';
193
+ const checkValue = this.treeView?.getNodeCheckedValue(this.node) || 'false';
186
194
  const newCheckValue = checkValue === 'false' ? 'true' : 'false';
187
195
  const nodeInfos = [];
188
196
  const rootInfo = this.treeView?.infoFromNode(this.node, newCheckValue);
189
197
  if (rootInfo)
190
198
  nodeInfos.push(rootInfo);
191
- if (this.selectStrategy === 'descendants') {
199
+ if (this.selectStrategy === 'descendants' || this.selectStrategy === 'mixed_descendants') {
192
200
  for (const node of this.eachDescendantNode()) {
193
201
  const info = this.treeView?.infoFromNode(node, newCheckValue);
194
202
  if (info)
@@ -211,6 +219,9 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
211
219
  detail: nodeInfos,
212
220
  }));
213
221
  }
222
+ changeSelectStrategy(newStrategy) {
223
+ this.node.setAttribute('data-select-strategy', newStrategy);
224
+ }
214
225
  };
215
226
  _TreeViewSubTreeNodeElement_expanded = new WeakMap();
216
227
  _TreeViewSubTreeNodeElement_loadingState = new WeakMap();
@@ -269,6 +280,10 @@ _TreeViewSubTreeNodeElement_handleKeyboardEvent = function _TreeViewSubTreeNodeE
269
280
  }
270
281
  switch (event.key) {
271
282
  case 'Enter':
283
+ if (this.treeView?.getNodeDisabledValue(node)) {
284
+ event.preventDefault();
285
+ break;
286
+ }
272
287
  // eslint-disable-next-line no-restricted-syntax
273
288
  event.stopPropagation();
274
289
  if (__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "a", _TreeViewSubTreeNodeElement_checkboxElement_get)) {
@@ -290,6 +305,10 @@ _TreeViewSubTreeNodeElement_handleKeyboardEvent = function _TreeViewSubTreeNodeE
290
305
  this.collapse();
291
306
  break;
292
307
  case ' ':
308
+ if (this.treeView?.getNodeDisabledValue(node)) {
309
+ event.preventDefault();
310
+ break;
311
+ }
293
312
  if (__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "a", _TreeViewSubTreeNodeElement_checkboxElement_get)) {
294
313
  // eslint-disable-next-line no-restricted-syntax
295
314
  event.stopPropagation();
@@ -309,6 +328,10 @@ _TreeViewSubTreeNodeElement_handleKeyboardEvent = function _TreeViewSubTreeNodeE
309
328
  }
310
329
  };
311
330
  _TreeViewSubTreeNodeElement_handleCheckboxEvent = function _TreeViewSubTreeNodeElement_handleCheckboxEvent(event) {
331
+ if (this.treeView?.getNodeDisabledValue(this.node)) {
332
+ event.preventDefault();
333
+ return;
334
+ }
312
335
  if (event.type !== 'click')
313
336
  return;
314
337
  this.toggleChecked();
@@ -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",
@@ -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';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openproject/primer-view-components",
3
- "version": "0.70.5",
3
+ "version": "0.71.0-rc.5dc134b91",
4
4
  "description": "ViewComponents of the Primer Design System for OpenProject",
5
5
  "main": "app/assets/javascripts/primer_view_components.js",
6
6
  "module": "app/components/primer/primer.js",