@openproject/primer-view-components 0.67.0 → 0.68.0-rc.882e71b3f

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.
@@ -22,6 +22,7 @@ export declare class TreeViewElement extends HTMLElement {
22
22
  getNodeCheckedValue(node: Element): TreeViewCheckedValue;
23
23
  nodeHasCheckBox(node: Element): boolean;
24
24
  nodeHasNativeAction(node: Element): boolean;
25
+ expandAncestorsForNode(node: HTMLElement): void;
25
26
  infoFromNode(node: Element, newCheckedValue?: TreeViewCheckedValue): TreeViewNodeInfo | null;
26
27
  }
27
28
  declare global {
@@ -15,7 +15,7 @@ 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_eventIsActivation, _TreeViewElement_nodeForEvent, _TreeViewElement_handleNodeEvent, _TreeViewElement_eventIsCheckboxToggle, _TreeViewElement_handleCheckboxToggle, _TreeViewElement_handleNodeActivated, _TreeViewElement_handleNodeFocused, _TreeViewElement_handleNodeKeyboardEvent, _TreeViewElement_setNodeCheckedValue;
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
19
  import { controller } from '@github/catalyst';
20
20
  import { useRovingTabIndex } from './tree_view_roving_tab_index';
21
21
  let TreeViewElement = class TreeViewElement extends HTMLElement {
@@ -30,6 +30,24 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
30
30
  this.addEventListener('focusin', this, { signal });
31
31
  this.addEventListener('keydown', this, { signal });
32
32
  useRovingTabIndex(this);
33
+ // catch-all for any straggler nodes that aren't available when connectedCallback runs
34
+ new MutationObserver(mutations => {
35
+ for (const mutation of mutations) {
36
+ for (const addedNode of mutation.addedNodes) {
37
+ if (!(addedNode instanceof HTMLElement))
38
+ continue;
39
+ // eslint-disable-next-line custom-elements/no-dom-traversal-in-connectedcallback
40
+ if (addedNode.querySelector('[aria-expanded=true]')) {
41
+ __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_autoExpandFrom).call(this, addedNode);
42
+ }
43
+ }
44
+ }
45
+ }).observe(this, { childList: true, subtree: true });
46
+ // eslint-disable-next-line github/no-then -- We don't want to wait for this to resolve, just get on with it
47
+ customElements.whenDefined('tree-view-sub-tree-node').then(() => {
48
+ // depends on TreeViewSubTreeNodeElement#eachAncestorSubTreeNode, which may not be defined yet
49
+ __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_autoExpandFrom).call(this, this);
50
+ });
33
51
  }
34
52
  disconnectedCallback() {
35
53
  __classPrivateFieldGet(this, _TreeViewElement_abortController, "f").abort();
@@ -132,6 +150,16 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
132
150
  nodeHasNativeAction(node) {
133
151
  return node instanceof HTMLAnchorElement || node instanceof HTMLButtonElement;
134
152
  }
153
+ expandAncestorsForNode(node) {
154
+ const subTreeNode = node.closest('tree-view-sub-tree-node');
155
+ if (!subTreeNode)
156
+ return;
157
+ for (const ancestor of subTreeNode.eachAncestorSubTreeNode()) {
158
+ if (!ancestor.expanded) {
159
+ ancestor.expand();
160
+ }
161
+ }
162
+ }
135
163
  // PRIVATE API METHOD
136
164
  //
137
165
  // This would normally be marked private, but it's called by TreeViewSubTreeNodes
@@ -152,6 +180,11 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
152
180
  };
153
181
  _TreeViewElement_abortController = new WeakMap();
154
182
  _TreeViewElement_instances = new WeakSet();
183
+ _TreeViewElement_autoExpandFrom = function _TreeViewElement_autoExpandFrom(root) {
184
+ for (const element of root.querySelectorAll('[aria-expanded=true]')) {
185
+ this.expandAncestorsForNode(element);
186
+ }
187
+ };
155
188
  _TreeViewElement_eventIsActivation = function _TreeViewElement_eventIsActivation(event) {
156
189
  return event.type === 'click';
157
190
  };
@@ -28,6 +28,7 @@ export declare class TreeViewSubTreeNodeElement extends HTMLElement {
28
28
  get nodes(): NodeListOf<Element>;
29
29
  eachDirectDescendantNode(): Generator<Element>;
30
30
  eachDescendantNode(): Generator<Element>;
31
+ eachAncestorSubTreeNode(): Generator<TreeViewSubTreeNodeElement>;
31
32
  get isEmpty(): boolean;
32
33
  get treeView(): TreeViewElement | null;
33
34
  toggleChecked(): void;
@@ -165,6 +165,16 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
165
165
  yield node;
166
166
  }
167
167
  }
168
+ *eachAncestorSubTreeNode() {
169
+ if (!this.treeView)
170
+ return;
171
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
172
+ let current = this;
173
+ while (current && this.treeView.contains(current)) {
174
+ yield current;
175
+ current = current.parentElement?.closest('tree-view-sub-tree-node');
176
+ }
177
+ }
168
178
  get isEmpty() {
169
179
  return this.nodes.length === 0;
170
180
  }
@@ -230,6 +240,9 @@ _TreeViewSubTreeNodeElement_handleIncludeFragmentEvent = function _TreeViewSubTr
230
240
  this.loadingState = 'success';
231
241
  break;
232
242
  case 'include-fragment-replaced':
243
+ // Make sure to expand the new sub-tree, otherwise it looks like nothing happened. This prevents
244
+ // having to remember to pass `SubTree.new(expanded: true)` in the controller.
245
+ this.expanded = true;
233
246
  if (__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_activeElementIsLoader, "f")) {
234
247
  const firstItem = this.querySelector('[role=group] > :first-child');
235
248
  if (!firstItem)
@@ -308,6 +321,7 @@ _TreeViewSubTreeNodeElement_update = function _TreeViewSubTreeNodeElement_update
308
321
  if (this.subTree)
309
322
  this.subTree.hidden = false;
310
323
  this.node.setAttribute('aria-expanded', 'true');
324
+ this.treeView?.expandAncestorsForNode(this);
311
325
  if (this.iconPair) {
312
326
  this.iconPair.showExpanded();
313
327
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openproject/primer-view-components",
3
- "version": "0.67.0",
3
+ "version": "0.68.0-rc.882e71b3f",
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",