@openproject/primer-view-components 0.66.2 → 0.67.0-rc.87a99bede
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.
- package/app/assets/javascripts/components/primer/open_project/tree_view/tree_view.d.ts +2 -0
- package/app/assets/javascripts/primer_view_components.js +1 -1
- package/app/assets/javascripts/primer_view_components.js.map +1 -1
- package/app/assets/styles/primer_view_components.css +1 -1
- package/app/assets/styles/primer_view_components.css.map +1 -1
- package/app/components/primer/open_project/tree_view/tree_view.d.ts +2 -0
- package/app/components/primer/open_project/tree_view/tree_view.js +29 -9
- package/app/components/primer/open_project/tree_view/tree_view_roving_tab_index.js +11 -7
- package/app/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.js +38 -21
- package/app/components/primer/open_project/tree_view.css +1 -1
- package/app/components/primer/open_project/tree_view.css.json +9 -6
- package/package.json +1 -1
- package/static/arguments.json +38 -2
- package/static/constants.json +17 -0
- package/static/info_arch.json +95 -3
- package/static/previews.json +26 -0
|
@@ -20,6 +20,8 @@ export declare class TreeViewElement extends HTMLElement {
|
|
|
20
20
|
subTreeAtPath(path: string[]): TreeViewSubTreeNodeElement | null;
|
|
21
21
|
leafAtPath(path: string[]): HTMLLIElement | null;
|
|
22
22
|
getNodeCheckedValue(node: Element): TreeViewCheckedValue;
|
|
23
|
+
nodeHasCheckBox(node: Element): boolean;
|
|
24
|
+
nodeHasNativeAction(node: Element): boolean;
|
|
23
25
|
infoFromNode(node: Element, newCheckedValue?: TreeViewCheckedValue): TreeViewNodeInfo | null;
|
|
24
26
|
}
|
|
25
27
|
declare global {
|
|
@@ -126,6 +126,12 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
|
|
|
126
126
|
getNodeCheckedValue(node) {
|
|
127
127
|
return (node.getAttribute('aria-checked') || 'false');
|
|
128
128
|
}
|
|
129
|
+
nodeHasCheckBox(node) {
|
|
130
|
+
return node.querySelector('.TreeViewItemCheckbox') !== null;
|
|
131
|
+
}
|
|
132
|
+
nodeHasNativeAction(node) {
|
|
133
|
+
return node instanceof HTMLAnchorElement || node instanceof HTMLButtonElement;
|
|
134
|
+
}
|
|
129
135
|
// PRIVATE API METHOD
|
|
130
136
|
//
|
|
131
137
|
// This would normally be marked private, but it's called by TreeViewSubTreeNodes
|
|
@@ -161,7 +167,7 @@ _TreeViewElement_nodeForEvent = function _TreeViewElement_nodeForEvent(event) {
|
|
|
161
167
|
return node;
|
|
162
168
|
};
|
|
163
169
|
_TreeViewElement_handleNodeEvent = function _TreeViewElement_handleNodeEvent(node, event) {
|
|
164
|
-
if (__classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_eventIsCheckboxToggle).call(this, event)) {
|
|
170
|
+
if (__classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_eventIsCheckboxToggle).call(this, event, node)) {
|
|
165
171
|
__classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_handleCheckboxToggle).call(this, node);
|
|
166
172
|
}
|
|
167
173
|
else if (__classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_eventIsActivation).call(this, event)) {
|
|
@@ -174,8 +180,8 @@ _TreeViewElement_handleNodeEvent = function _TreeViewElement_handleNodeEvent(nod
|
|
|
174
180
|
__classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_handleNodeKeyboardEvent).call(this, event, node);
|
|
175
181
|
}
|
|
176
182
|
};
|
|
177
|
-
_TreeViewElement_eventIsCheckboxToggle = function _TreeViewElement_eventIsCheckboxToggle(event) {
|
|
178
|
-
return event.type === 'click' &&
|
|
183
|
+
_TreeViewElement_eventIsCheckboxToggle = function _TreeViewElement_eventIsCheckboxToggle(event, node) {
|
|
184
|
+
return event.type === 'click' && this.nodeHasCheckBox(node);
|
|
179
185
|
};
|
|
180
186
|
_TreeViewElement_handleCheckboxToggle = function _TreeViewElement_handleCheckboxToggle(node) {
|
|
181
187
|
// only handle checking of leaf nodes
|
|
@@ -190,6 +196,10 @@ _TreeViewElement_handleCheckboxToggle = function _TreeViewElement_handleCheckbox
|
|
|
190
196
|
}
|
|
191
197
|
};
|
|
192
198
|
_TreeViewElement_handleNodeActivated = function _TreeViewElement_handleNodeActivated(node) {
|
|
199
|
+
// do not emit activation events for buttons and anchors, since it is assumed any activation
|
|
200
|
+
// behavior for these element types is user- or browser-defined
|
|
201
|
+
if (!(node instanceof HTMLDivElement))
|
|
202
|
+
return;
|
|
193
203
|
const path = this.getNodePath(node);
|
|
194
204
|
const activationSuccess = this.dispatchEvent(new CustomEvent('treeViewBeforeNodeActivated', {
|
|
195
205
|
bubbles: true,
|
|
@@ -198,7 +208,10 @@ _TreeViewElement_handleNodeActivated = function _TreeViewElement_handleNodeActiv
|
|
|
198
208
|
}));
|
|
199
209
|
if (!activationSuccess)
|
|
200
210
|
return;
|
|
201
|
-
|
|
211
|
+
// navigate or trigger button, don't toggle
|
|
212
|
+
if (!this.nodeHasNativeAction(node)) {
|
|
213
|
+
this.toggleAtPath(path);
|
|
214
|
+
}
|
|
202
215
|
this.dispatchEvent(new CustomEvent('treeViewNodeActivated', {
|
|
203
216
|
bubbles: true,
|
|
204
217
|
detail: this.infoFromNode(node),
|
|
@@ -215,12 +228,19 @@ _TreeViewElement_handleNodeKeyboardEvent = function _TreeViewElement_handleNodeK
|
|
|
215
228
|
}
|
|
216
229
|
switch (event.key) {
|
|
217
230
|
case ' ':
|
|
218
|
-
|
|
219
|
-
if (this.
|
|
220
|
-
|
|
231
|
+
case 'Enter':
|
|
232
|
+
if (this.nodeHasCheckBox(node)) {
|
|
233
|
+
event.preventDefault();
|
|
234
|
+
if (this.getNodeCheckedValue(node) === 'true') {
|
|
235
|
+
__classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_setNodeCheckedValue).call(this, node, 'false');
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
__classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_setNodeCheckedValue).call(this, node, 'true');
|
|
239
|
+
}
|
|
221
240
|
}
|
|
222
|
-
else {
|
|
223
|
-
|
|
241
|
+
else if (node instanceof HTMLAnchorElement) {
|
|
242
|
+
// simulate click on space
|
|
243
|
+
node.click();
|
|
224
244
|
}
|
|
225
245
|
break;
|
|
226
246
|
}
|
|
@@ -22,12 +22,6 @@ export function useRovingTabIndex(containerEl) {
|
|
|
22
22
|
return getNextFocusableElement(from, event) ?? from;
|
|
23
23
|
},
|
|
24
24
|
focusInStrategy: () => {
|
|
25
|
-
// Don't try to execute the focusInStrategy if focus is coming from a click.
|
|
26
|
-
// The clicked row will receive focus correctly by default.
|
|
27
|
-
// If a chevron is clicked, setting the focus through the focuszone will prevent its toggle.
|
|
28
|
-
// if (mouseDownRef.current) {
|
|
29
|
-
// return undefined
|
|
30
|
-
// }
|
|
31
25
|
let currentItem = containerEl.querySelector('[aria-current]');
|
|
32
26
|
currentItem = currentItem?.checkVisibility() ? currentItem : null;
|
|
33
27
|
const firstItem = containerEl.querySelector('[role="treeitem"]');
|
|
@@ -110,11 +104,21 @@ function getVisibleElement(element, direction) {
|
|
|
110
104
|
}
|
|
111
105
|
let next = direction === 'next' ? walker.nextNode() : walker.previousNode();
|
|
112
106
|
// If next element is nested inside a collapsed subtree, continue iterating
|
|
113
|
-
while (next instanceof HTMLElement && next
|
|
107
|
+
while (next instanceof HTMLElement && collapsedParent(next, root)) {
|
|
114
108
|
next = direction === 'next' ? walker.nextNode() : walker.previousNode();
|
|
115
109
|
}
|
|
116
110
|
return next instanceof HTMLElement ? next : undefined;
|
|
117
111
|
}
|
|
112
|
+
function collapsedParent(node, root) {
|
|
113
|
+
for (const ancestor of root.querySelectorAll('[role=treeitem][aria-expanded=false]')) {
|
|
114
|
+
if (node === ancestor)
|
|
115
|
+
continue;
|
|
116
|
+
if (ancestor.closest('li')?.contains(node)) {
|
|
117
|
+
return ancestor;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
118
122
|
function getFirstChildElement(element) {
|
|
119
123
|
const firstChild = element.querySelector('[role=treeitem]');
|
|
120
124
|
return firstChild instanceof HTMLElement ? firstChild : undefined;
|
|
@@ -101,11 +101,7 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
|
|
|
101
101
|
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_abortController, "f").abort();
|
|
102
102
|
}
|
|
103
103
|
handleEvent(event) {
|
|
104
|
-
|
|
105
|
-
if (checkbox && checkbox === __classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "a", _TreeViewSubTreeNodeElement_checkboxElement_get)) {
|
|
106
|
-
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_handleCheckboxEvent).call(this, event);
|
|
107
|
-
}
|
|
108
|
-
else if (event.target === this.toggleButton) {
|
|
104
|
+
if (event.target === this.toggleButton) {
|
|
109
105
|
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_handleToggleEvent).call(this, event);
|
|
110
106
|
}
|
|
111
107
|
else if (event.target === this.includeFragment) {
|
|
@@ -114,6 +110,11 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
|
|
|
114
110
|
else if (event instanceof KeyboardEvent) {
|
|
115
111
|
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_handleKeyboardEvent).call(this, event);
|
|
116
112
|
}
|
|
113
|
+
else if (event.target.closest('[role=treeitem]') === this.node &&
|
|
114
|
+
event.type === 'click' &&
|
|
115
|
+
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "a", _TreeViewSubTreeNodeElement_checkboxElement_get)) {
|
|
116
|
+
__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_handleCheckboxEvent).call(this, event);
|
|
117
|
+
}
|
|
117
118
|
}
|
|
118
119
|
expand() {
|
|
119
120
|
const alreadyExpanded = this.expanded;
|
|
@@ -152,10 +153,10 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
|
|
|
152
153
|
return this.querySelectorAll(':scope > [role=treeitem]');
|
|
153
154
|
}
|
|
154
155
|
*eachDirectDescendantNode() {
|
|
155
|
-
for (const leaf of this.subTree.querySelectorAll(':scope > [role=treeitem]')) {
|
|
156
|
+
for (const leaf of this.subTree.querySelectorAll(':scope > li > .TreeViewItemContainer > [role=treeitem]')) {
|
|
156
157
|
yield leaf;
|
|
157
158
|
}
|
|
158
|
-
for (const subTree of this.subTree.querySelectorAll(':scope > tree-view-sub-tree-node > [role=treeitem]')) {
|
|
159
|
+
for (const subTree of this.subTree.querySelectorAll(':scope > tree-view-sub-tree-node > li > .TreeViewItemContainer > [role=treeitem]')) {
|
|
159
160
|
yield subTree;
|
|
160
161
|
}
|
|
161
162
|
}
|
|
@@ -209,6 +210,8 @@ _TreeViewSubTreeNodeElement_instances = new WeakSet();
|
|
|
209
210
|
_TreeViewSubTreeNodeElement_handleToggleEvent = function _TreeViewSubTreeNodeElement_handleToggleEvent(event) {
|
|
210
211
|
if (event.type === 'click') {
|
|
211
212
|
this.toggle();
|
|
213
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
214
|
+
event.stopPropagation();
|
|
212
215
|
}
|
|
213
216
|
};
|
|
214
217
|
_TreeViewSubTreeNodeElement_handleIncludeFragmentEvent = function _TreeViewSubTreeNodeElement_handleIncludeFragmentEvent(event) {
|
|
@@ -223,21 +226,18 @@ _TreeViewSubTreeNodeElement_handleIncludeFragmentEvent = function _TreeViewSubTr
|
|
|
223
226
|
break;
|
|
224
227
|
// request succeeded but element has not yet been replaced
|
|
225
228
|
case 'include-fragment-replace':
|
|
226
|
-
__classPrivateFieldSet(this, _TreeViewSubTreeNodeElement_activeElementIsLoader, document.activeElement === this.loadingIndicator.closest('
|
|
229
|
+
__classPrivateFieldSet(this, _TreeViewSubTreeNodeElement_activeElementIsLoader, document.activeElement === this.loadingIndicator.closest('[role=treeitem]'), "f");
|
|
227
230
|
this.loadingState = 'success';
|
|
228
231
|
break;
|
|
229
232
|
case 'include-fragment-replaced':
|
|
230
233
|
if (__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_activeElementIsLoader, "f")) {
|
|
231
|
-
const firstItem = this.querySelector('[role=
|
|
234
|
+
const firstItem = this.querySelector('[role=group] > :first-child');
|
|
232
235
|
if (!firstItem)
|
|
233
236
|
return;
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
else {
|
|
239
|
-
firstItem?.focus();
|
|
240
|
-
}
|
|
237
|
+
const content = firstItem.querySelector('[role=treeitem]');
|
|
238
|
+
if (!content)
|
|
239
|
+
return;
|
|
240
|
+
content.focus();
|
|
241
241
|
}
|
|
242
242
|
__classPrivateFieldSet(this, _TreeViewSubTreeNodeElement_activeElementIsLoader, false, "f");
|
|
243
243
|
break;
|
|
@@ -258,7 +258,13 @@ _TreeViewSubTreeNodeElement_handleKeyboardEvent = function _TreeViewSubTreeNodeE
|
|
|
258
258
|
case 'Enter':
|
|
259
259
|
// eslint-disable-next-line no-restricted-syntax
|
|
260
260
|
event.stopPropagation();
|
|
261
|
-
this
|
|
261
|
+
if (__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "a", _TreeViewSubTreeNodeElement_checkboxElement_get)) {
|
|
262
|
+
this.toggleChecked();
|
|
263
|
+
}
|
|
264
|
+
else if (!this.treeView?.nodeHasNativeAction(node)) {
|
|
265
|
+
// toggle only if this node isn't eg. an anchor or button
|
|
266
|
+
this.toggle();
|
|
267
|
+
}
|
|
262
268
|
break;
|
|
263
269
|
case 'ArrowRight':
|
|
264
270
|
// eslint-disable-next-line no-restricted-syntax
|
|
@@ -271,10 +277,21 @@ _TreeViewSubTreeNodeElement_handleKeyboardEvent = function _TreeViewSubTreeNodeE
|
|
|
271
277
|
this.collapse();
|
|
272
278
|
break;
|
|
273
279
|
case ' ':
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
280
|
+
if (__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "a", _TreeViewSubTreeNodeElement_checkboxElement_get)) {
|
|
281
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
282
|
+
event.stopPropagation();
|
|
283
|
+
event.preventDefault();
|
|
284
|
+
this.toggleChecked();
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
if (node instanceof HTMLAnchorElement) {
|
|
288
|
+
// simulate click on space for anchors (buttons already handle this natively)
|
|
289
|
+
node.click();
|
|
290
|
+
}
|
|
291
|
+
else if (!this.treeView?.nodeHasNativeAction(node)) {
|
|
292
|
+
this.toggle();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
278
295
|
break;
|
|
279
296
|
}
|
|
280
297
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.TreeViewRootUlStyles{list-style:none;margin:0;padding:0}.TreeViewRootUlStyles .TreeViewItem{outline:none}:is(.TreeViewRootUlStyles .TreeViewItem):focus-visible>div{box-shadow:var(--boxShadow-thick) var(--fgColor-accent)}@media (forced-colors:active){:is(.TreeViewRootUlStyles .TreeViewItem):focus-visible>div{outline:2px solid HighlightText;outline-offset:-2}}[data-has-leading-action]:is(.TreeViewRootUlStyles .TreeViewItem){--has-leading-action:1}.TreeViewRootUlStyles .TreeViewItemContainer{--level:1;--toggle-width:1rem;--min-item-height:2rem;border-radius:var(--borderRadius-medium);color:var(--fgColor-default);
|
|
1
|
+
.TreeViewRootUlStyles{list-style:none;margin:0;padding:0}.TreeViewRootUlStyles .TreeViewItem{outline:none}:is(.TreeViewRootUlStyles .TreeViewItem):focus-visible>div{box-shadow:var(--boxShadow-thick) var(--fgColor-accent)}@media (forced-colors:active){:is(.TreeViewRootUlStyles .TreeViewItem):focus-visible>div{outline:2px solid HighlightText;outline-offset:-2}}[data-has-leading-action]:is(.TreeViewRootUlStyles .TreeViewItem){--has-leading-action:1}.TreeViewRootUlStyles .TreeViewItemContainer{--level:1;--toggle-width:1rem;--min-item-height:2rem;border-radius:var(--borderRadius-medium);color:var(--fgColor-default);display:grid;font-size:var(--text-body-size-medium);grid-template-areas:"spacer leadingAction toggle content";grid-template-columns:var(--spacer-width) var(--leading-action-width) var(--toggle-width) 1fr;position:relative;width:100%;--leading-action-width:calc(var(--has-leading-action, 0)*1.5rem);--spacer-width:calc((var(--level) - 1)*(var(--toggle-width)/2))}:is(.TreeViewRootUlStyles .TreeViewItemContainer):hover{background-color:var(--control-transparent-bgColor-hover)}@media (forced-colors:active){:is(.TreeViewRootUlStyles .TreeViewItemContainer):hover{outline:2px solid #0000;outline-offset:-2px}}@media (pointer:coarse){.TreeViewRootUlStyles .TreeViewItemContainer{--toggle-width:1.5rem;--min-item-height:2.75rem}}:is(.TreeViewRootUlStyles .TreeViewItemContainer):has(.TreeViewFailureMessage):hover{background-color:initial;cursor:default}@media (forced-colors:active){:is(.TreeViewRootUlStyles .TreeViewItemContainer):has(.TreeViewFailureMessage):hover{outline:none}}:is(.TreeViewRootUlStyles .TreeViewItemContainer):has([role=treeitem]:focus-visible){box-shadow:var(--boxShadow-thick) var(--fgColor-accent)}.TreeViewRootUlStyles:where([data-omit-spacer=true]) .TreeViewItemContainer{grid-template-columns:0 0 0 1fr}.TreeViewRootUlStyles .TreeViewItem>.TreeViewItemContainer:has(.TreeViewItemContent[aria-current=true]){background-color:var(--control-transparent-bgColor-selected)}:is(.TreeViewRootUlStyles .TreeViewItem>.TreeViewItemContainer:has(.TreeViewItemContent[aria-current=true])):after{background-color:var(--fgColor-accent);border-radius:var(--borderRadius-medium);content:"";height:1.5rem;left:calc(var(--base-size-8)*-1);position:absolute;top:calc(50% - var(--base-size-12));width:.25rem}@media (forced-colors:active){:is(.TreeViewRootUlStyles .TreeViewItem>.TreeViewItemContainer:has(.TreeViewItemContent[aria-current=true])):after{background-color:HighlightText}}.TreeViewRootUlStyles .TreeViewItemToggle{align-items:flex-start;color:var(--fgColor-muted);cursor:pointer;display:flex;grid-area:toggle;height:100%;justify-content:center;padding-top:calc(var(--min-item-height)/2 - var(--base-size-12)/2)}.TreeViewRootUlStyles .TreeViewItemToggleHover:hover{background-color:var(--control-transparent-bgColor-hover)}.TreeViewRootUlStyles .TreeViewItemToggleEnd{border-bottom-left-radius:var(--borderRadius-medium);border-top-left-radius:var(--borderRadius-medium)}.TreeViewRootUlStyles a.TreeViewItemContent:hover,.TreeViewRootUlStyles button.TreeViewItemContent:hover{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:var(--control-fgColor-rest)}.TreeViewRootUlStyles .TreeViewItemContent{cursor:pointer;display:flex;gap:var(--stack-gap-condensed);grid-area:content;height:100%;line-height:var(--custom-line-height,var(--text-body-lineHeight-medium,1.4285));outline:none;padding:0 var(--base-size-8);padding-bottom:calc((var(--min-item-height) - var(--custom-line-height, 1.3rem))/2);padding-top:calc((var(--min-item-height) - var(--custom-line-height, 1.3rem))/2)}.TreeViewRootUlStyles .TreeViewItemContent,:is(.TreeViewRootUlStyles .TreeViewItemContent) .TreeViewItemCheckbox{background-color:initial;border:none;text-align:left;touch-action:manipulation;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}:is(.TreeViewRootUlStyles .TreeViewItemContent) .TreeViewItemCheckbox{border-radius:var(--borderRadius-medium);color:var(--control-fgColor-rest);position:relative;transition:background 33.333ms linear}[aria-checked=true]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox{background:var(--control-checked-bgColor-rest);border-color:var(--control-checked-borderColor-rest);transition:background-color,border-color 80ms cubic-bezier(.32,0,.67,0) 0s}:is([aria-checked=true]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox):before{animation:checkmarkIn 80ms cubic-bezier(.65,0,.35,1) 80ms forwards;transition:visibility 0s linear 0s;visibility:visible}[aria-checked=mixed]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox{background:var(--control-checked-bgColor-rest);border-color:var(--control-checked-borderColor-rest);transition:background-color,border-color 80ms cubic-bezier(.32,0,.67,0) 0s}:is([aria-checked=mixed]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox):before{animation:checkmarkIn 80ms cubic-bezier(.65,0,.35,1) 80ms forwards;clip-path:none;mask-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIyIiBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMTAgMiI+PHBhdGggZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMCAxYTEgMSAwIDAgMSAxLTFoOGExIDEgMCAxIDEgMCAySDFhMSAxIDAgMCAxLTEtMSIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+");visibility:visible}.TreeViewRootUlStyles .TreeViewItemContentText{color:var(--control-fgColor-rest);flex:1 1 auto;width:0}.TreeViewRootUlStyles:where([data-truncate-text=true]) .TreeViewItemContentText{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.TreeViewRootUlStyles:where([data-truncate-text=false]) .TreeViewItemContentText{word-break:break-word}.TreeViewRootUlStyles .TreeViewItemVisual{align-items:center;color:var(--fgColor-muted);display:flex;height:var(--custom-line-height,1.3rem)}.TreeViewRootUlStyles .TreeViewItemLeadingAction{color:var(--fgColor-muted);display:flex;grid-area:leadingAction}:is(.TreeViewRootUlStyles .TreeViewItemLeadingAction)>button{flex-shrink:1}.TreeViewRootUlStyles .TreeViewItemLevelLine{border-color:var(--borderColor-muted);border-right:var(--borderWidth-thin) solid;height:100%;width:100%}@media (hover:hover){.TreeViewRootUlStyles .TreeViewItemLevelLine{border-color:#0000}.TreeViewRootUlStyles:focus-within .TreeViewItemLevelLine,.TreeViewRootUlStyles:hover .TreeViewItemLevelLine{border-color:var(--borderColor-muted)}}.TreeViewRootUlStyles .TreeViewVisuallyHidden{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border-width:0;white-space:nowrap}.TreeViewSkeletonItemContainerStyle{align-items:center;column-gap:.5rem;display:flex;height:2rem}@media (pointer:coarse){.TreeViewSkeletonItemContainerStyle{height:2.75rem}}.TreeViewSkeletonItemContainerStyle:nth-of-type(5n+1){--tree-item-loading-width:67%}.TreeViewSkeletonItemContainerStyle:nth-of-type(5n+2){--tree-item-loading-width:47%}.TreeViewSkeletonItemContainerStyle:nth-of-type(5n+3){--tree-item-loading-width:73%}.TreeViewSkeletonItemContainerStyle:nth-of-type(5n+4){--tree-item-loading-width:64%}.TreeViewSkeletonItemContainerStyle:nth-of-type(5n+5){--tree-item-loading-width:50%}.TreeItemSkeletonTextStyles{width:var(--tree-item-loading-width,67%)}.TreeViewFailureMessage{align-items:center;display:grid;gap:.5rem;grid-template-columns:auto 1fr;width:100%}
|
|
@@ -8,18 +8,21 @@
|
|
|
8
8
|
".TreeViewRootUlStyles .TreeViewItemContainer",
|
|
9
9
|
":is(.TreeViewRootUlStyles .TreeViewItemContainer):hover",
|
|
10
10
|
":is(.TreeViewRootUlStyles .TreeViewItemContainer):has(.TreeViewFailureMessage):hover",
|
|
11
|
+
":is(.TreeViewRootUlStyles .TreeViewItemContainer):has([role=treeitem]:focus-visible)",
|
|
11
12
|
".TreeViewRootUlStyles:where([data-omit-spacer=true]) .TreeViewItemContainer",
|
|
12
|
-
".TreeViewRootUlStyles .TreeViewItem[aria-current=true]
|
|
13
|
-
":is(.TreeViewRootUlStyles .TreeViewItem[aria-current=true]
|
|
14
|
-
"[aria-checked=true]:is(.TreeViewRootUlStyles .TreeViewItem)>.TreeViewItemContainer .FormControl-checkbox",
|
|
15
|
-
":is([aria-checked=true]:is(.TreeViewRootUlStyles .TreeViewItem)>.TreeViewItemContainer .FormControl-checkbox):before",
|
|
16
|
-
"[aria-checked=mixed]:is(.TreeViewRootUlStyles .TreeViewItem)>.TreeViewItemContainer .FormControl-checkbox",
|
|
17
|
-
":is([aria-checked=mixed]:is(.TreeViewRootUlStyles .TreeViewItem)>.TreeViewItemContainer .FormControl-checkbox):before",
|
|
13
|
+
".TreeViewRootUlStyles .TreeViewItem>.TreeViewItemContainer:has(.TreeViewItemContent[aria-current=true])",
|
|
14
|
+
":is(.TreeViewRootUlStyles .TreeViewItem>.TreeViewItemContainer:has(.TreeViewItemContent[aria-current=true])):after",
|
|
18
15
|
".TreeViewRootUlStyles .TreeViewItemToggle",
|
|
19
16
|
".TreeViewRootUlStyles .TreeViewItemToggleHover:hover",
|
|
20
17
|
".TreeViewRootUlStyles .TreeViewItemToggleEnd",
|
|
18
|
+
".TreeViewRootUlStyles a.TreeViewItemContent:hover",
|
|
19
|
+
".TreeViewRootUlStyles button.TreeViewItemContent:hover",
|
|
21
20
|
".TreeViewRootUlStyles .TreeViewItemContent",
|
|
22
21
|
":is(.TreeViewRootUlStyles .TreeViewItemContent) .TreeViewItemCheckbox",
|
|
22
|
+
"[aria-checked=true]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox",
|
|
23
|
+
":is([aria-checked=true]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox):before",
|
|
24
|
+
"[aria-checked=mixed]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox",
|
|
25
|
+
":is([aria-checked=mixed]:is(.TreeViewRootUlStyles .TreeViewItemContent) .FormControl-checkbox):before",
|
|
23
26
|
".TreeViewRootUlStyles .TreeViewItemContentText",
|
|
24
27
|
".TreeViewRootUlStyles:where([data-truncate-text=true]) .TreeViewItemContentText",
|
|
25
28
|
".TreeViewRootUlStyles:where([data-truncate-text=false]) .TreeViewItemContentText",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openproject/primer-view-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.67.0-rc.87a99bede",
|
|
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",
|
package/static/arguments.json
CHANGED
|
@@ -5419,6 +5419,12 @@
|
|
|
5419
5419
|
"source": "https://github.com/primer/view_components/tree/main/app/components/primer/open_project/file_tree_view.rb",
|
|
5420
5420
|
"lookbook": "https://primer.style/view-components/lookbook/inspect/primer/open_project/file_tree_view/default/",
|
|
5421
5421
|
"parameters": [
|
|
5422
|
+
{
|
|
5423
|
+
"name": "node_variant",
|
|
5424
|
+
"type": "Symbol",
|
|
5425
|
+
"default": "`:div`",
|
|
5426
|
+
"description": "The variant to use for this node. One of `:anchor`, `:button`, or `:div`."
|
|
5427
|
+
},
|
|
5422
5428
|
{
|
|
5423
5429
|
"name": "system_arguments",
|
|
5424
5430
|
"type": "Hash",
|
|
@@ -5844,6 +5850,12 @@
|
|
|
5844
5850
|
"source": "https://github.com/primer/view_components/tree/main/app/components/primer/open_project/tree_view.rb",
|
|
5845
5851
|
"lookbook": "https://primer.style/view-components/lookbook/inspect/primer/open_project/tree_view/default/",
|
|
5846
5852
|
"parameters": [
|
|
5853
|
+
{
|
|
5854
|
+
"name": "node_variant",
|
|
5855
|
+
"type": "Symbol",
|
|
5856
|
+
"default": "`:div`",
|
|
5857
|
+
"description": "The variant to use for this node. One of `:anchor`, `:button`, or `:div`."
|
|
5858
|
+
},
|
|
5847
5859
|
{
|
|
5848
5860
|
"name": "system_arguments",
|
|
5849
5861
|
"type": "Hash",
|
|
@@ -5970,6 +5982,18 @@
|
|
|
5970
5982
|
"default": "N/A",
|
|
5971
5983
|
"description": "The node's \"path,\" i.e. this node's label and the labels of all its ancestors. This node should be reachable by traversing the tree following this path."
|
|
5972
5984
|
},
|
|
5985
|
+
{
|
|
5986
|
+
"name": "node_variant",
|
|
5987
|
+
"type": "Symbol",
|
|
5988
|
+
"default": "N/A",
|
|
5989
|
+
"description": "The node variant to use for the node's content, i.e. the `:button` or `:div`. One of `:anchor`, `:button`, or `:div`."
|
|
5990
|
+
},
|
|
5991
|
+
{
|
|
5992
|
+
"name": "href",
|
|
5993
|
+
"type": "String",
|
|
5994
|
+
"default": "`nil`",
|
|
5995
|
+
"description": "The URL to use as the `href` attribute for this node. If set to a truthy value, the `tag:` parameter is ignored and assumed to be `:a`."
|
|
5996
|
+
},
|
|
5973
5997
|
{
|
|
5974
5998
|
"name": "current",
|
|
5975
5999
|
"type": "Boolean",
|
|
@@ -5989,10 +6013,10 @@
|
|
|
5989
6013
|
"description": "The checked state of the node's checkbox. One of `false`, `mixed`, or `true`."
|
|
5990
6014
|
},
|
|
5991
6015
|
{
|
|
5992
|
-
"name": "
|
|
6016
|
+
"name": "content_arguments",
|
|
5993
6017
|
"type": "Hash",
|
|
5994
6018
|
"default": "N/A",
|
|
5995
|
-
"description": "
|
|
6019
|
+
"description": "Arguments attached to the node's content, i.e the `<button>` or `<a>` element. [System arguments](/system-arguments)"
|
|
5996
6020
|
}
|
|
5997
6021
|
]
|
|
5998
6022
|
},
|
|
@@ -6054,6 +6078,12 @@
|
|
|
6054
6078
|
"source": "https://github.com/primer/view_components/tree/main/app/components/primer/open_project/tree_view/sub_tree.rb",
|
|
6055
6079
|
"lookbook": "https://primer.style/view-components/lookbook/inspect/primer/open_project/tree_view/sub_tree/default/",
|
|
6056
6080
|
"parameters": [
|
|
6081
|
+
{
|
|
6082
|
+
"name": "node_variant",
|
|
6083
|
+
"type": "Symbol",
|
|
6084
|
+
"default": "N/A",
|
|
6085
|
+
"description": "The variant to use for this node. One of `:anchor`, `:button`, or `:div`."
|
|
6086
|
+
},
|
|
6057
6087
|
{
|
|
6058
6088
|
"name": "system_arguments",
|
|
6059
6089
|
"type": "Hash",
|
|
@@ -6110,6 +6140,12 @@
|
|
|
6110
6140
|
"default": "N/A",
|
|
6111
6141
|
"description": "The node's \"path,\" i.e. this node's label and the labels of all its ancestors. This node should be reachable by traversing the tree following this path."
|
|
6112
6142
|
},
|
|
6143
|
+
{
|
|
6144
|
+
"name": "node_variant",
|
|
6145
|
+
"type": "Symbol",
|
|
6146
|
+
"default": "N/A",
|
|
6147
|
+
"description": "The variant to use for this node. One of `:anchor`, `:button`, or `:div`."
|
|
6148
|
+
},
|
|
6113
6149
|
{
|
|
6114
6150
|
"name": "expanded",
|
|
6115
6151
|
"type": "Boolean",
|
package/static/constants.json
CHANGED
|
@@ -1786,12 +1786,18 @@
|
|
|
1786
1786
|
"GeneratedSlotMethods": "Primer::OpenProject::SubHeader::SegmentedControl::GeneratedSlotMethods"
|
|
1787
1787
|
},
|
|
1788
1788
|
"Primer::OpenProject::TreeView": {
|
|
1789
|
+
"DEFAULT_NODE_VARIANT": "div",
|
|
1789
1790
|
"GeneratedSlotMethods": "Primer::OpenProject::TreeView::GeneratedSlotMethods",
|
|
1790
1791
|
"Icon": "Primer::OpenProject::TreeView::Icon",
|
|
1791
1792
|
"IconPair": "Primer::OpenProject::TreeView::IconPair",
|
|
1792
1793
|
"LeadingAction": "Primer::OpenProject::TreeView::LeadingAction",
|
|
1793
1794
|
"LeafNode": "Primer::OpenProject::TreeView::LeafNode",
|
|
1794
1795
|
"LoadingFailureMessage": "Primer::OpenProject::TreeView::LoadingFailureMessage",
|
|
1796
|
+
"NODE_VARIANT_OPTIONS": [
|
|
1797
|
+
"div",
|
|
1798
|
+
"anchor",
|
|
1799
|
+
"button"
|
|
1800
|
+
],
|
|
1795
1801
|
"Node": "Primer::OpenProject::TreeView::Node",
|
|
1796
1802
|
"SkeletonLoader": "Primer::OpenProject::TreeView::SkeletonLoader",
|
|
1797
1803
|
"SpinnerLoader": "Primer::OpenProject::TreeView::SpinnerLoader",
|
|
@@ -1824,8 +1830,19 @@
|
|
|
1824
1830
|
"mixed"
|
|
1825
1831
|
],
|
|
1826
1832
|
"DEFAULT_CHECKED_STATE": false,
|
|
1833
|
+
"DEFAULT_NODE_VARIANT": "div",
|
|
1827
1834
|
"DEFAULT_SELECT_VARIANT": "none",
|
|
1828
1835
|
"GeneratedSlotMethods": "Primer::OpenProject::TreeView::Node::GeneratedSlotMethods",
|
|
1836
|
+
"NODE_VARIANT_TAG_MAP": {
|
|
1837
|
+
"div": "div",
|
|
1838
|
+
"button": "button",
|
|
1839
|
+
"anchor": "a"
|
|
1840
|
+
},
|
|
1841
|
+
"NODE_VARIANT_TAG_OPTIONS": [
|
|
1842
|
+
"div",
|
|
1843
|
+
"button",
|
|
1844
|
+
"anchor"
|
|
1845
|
+
],
|
|
1829
1846
|
"SELECT_VARIANT_OPTIONS": [
|
|
1830
1847
|
"multiple",
|
|
1831
1848
|
"none"
|