@salesforcedevs/dx-components 1.40.4-style-fix-alpha → 1.40.4-style-fix-alpha3
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/package.json
CHANGED
|
@@ -40,6 +40,34 @@
|
|
|
40
40
|
);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
/* Nested fit-content menus (content action toolbar). Flat fit-content menus,
|
|
44
|
+
including the version picker, keep the option rules above. */
|
|
45
|
+
.menu-fit-content.menu-nested {
|
|
46
|
+
--dx-c-popover-width: max-content;
|
|
47
|
+
--dx-c-popover-padding: var(--dx-g-spacing-sm) 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.menu-fit-content.menu-nested .menu_list {
|
|
51
|
+
width: 100%;
|
|
52
|
+
align-items: flex-start;
|
|
53
|
+
gap: var(--dx-g-spacing-sm);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.menu-fit-content.menu-nested .menu_option:not(:first-child) {
|
|
57
|
+
border-top: var(--border);
|
|
58
|
+
margin-top: 0;
|
|
59
|
+
padding-top: var(--dx-g-spacing-sm);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.menu-fit-content .menu_heading {
|
|
63
|
+
margin: 0;
|
|
64
|
+
padding: var(--dx-g-spacing-smd) var(--dx-g-spacing-lg);
|
|
65
|
+
font-family: var(--dx-g-font-sans);
|
|
66
|
+
line-height: var(--dx-g-spacing-mlg);
|
|
67
|
+
text-transform: none;
|
|
68
|
+
color: var(--dx-g-gray-10);
|
|
69
|
+
}
|
|
70
|
+
|
|
43
71
|
@media screen and (max-width: 1000px) {
|
|
44
72
|
.menu-nested .menu_option:not(:first-child) {
|
|
45
73
|
border-top: var(--border);
|
|
@@ -89,7 +89,15 @@ export default class Popover extends LightningElement {
|
|
|
89
89
|
|
|
90
90
|
this.dispatchEvent(new CustomEvent("open"));
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
this.clearOpenListenersTimer();
|
|
93
|
+
// Defer so the opening click is not treated as an outside click.
|
|
94
|
+
// Drop the callback if the popover closes before it runs, or the
|
|
95
|
+
// document listeners attach with nothing left to remove them.
|
|
96
|
+
this.openListenersTimer = setTimeout(() => {
|
|
97
|
+
this.openListenersTimer = undefined;
|
|
98
|
+
if (!this._open) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
93
101
|
this.setPosition();
|
|
94
102
|
this.attachListenersTopopover();
|
|
95
103
|
});
|
|
@@ -98,6 +106,7 @@ export default class Popover extends LightningElement {
|
|
|
98
106
|
|
|
99
107
|
@api
|
|
100
108
|
closePopover(focusControl: boolean = false) {
|
|
109
|
+
this.clearOpenListenersTimer();
|
|
101
110
|
if (!this._open) {
|
|
102
111
|
return;
|
|
103
112
|
}
|
|
@@ -134,6 +143,7 @@ export default class Popover extends LightningElement {
|
|
|
134
143
|
|
|
135
144
|
private controlled: boolean = false;
|
|
136
145
|
private pointerOpened: boolean = false;
|
|
146
|
+
private openListenersTimer?: ReturnType<typeof setTimeout>;
|
|
137
147
|
private _open: boolean = false;
|
|
138
148
|
private _rendered: boolean = isPrerender();
|
|
139
149
|
private _role: string | null = null;
|
|
@@ -146,6 +156,7 @@ export default class Popover extends LightningElement {
|
|
|
146
156
|
// LIFECYCLE METHODS
|
|
147
157
|
|
|
148
158
|
disconnectedCallback() {
|
|
159
|
+
this.clearOpenListenersTimer();
|
|
149
160
|
document.removeEventListener(
|
|
150
161
|
"click",
|
|
151
162
|
this.interactOutsideListener,
|
|
@@ -262,13 +273,42 @@ export default class Popover extends LightningElement {
|
|
|
262
273
|
|
|
263
274
|
// Capture on document: click-open leaves focus on the trigger, and slotted
|
|
264
275
|
// menu options live outside this shadow tree, so the panel's onkeydown
|
|
265
|
-
// never sees Escape.
|
|
276
|
+
// never sees Escape. Only the innermost popover in the event path handles
|
|
277
|
+
// it, so Escape in another control does not close this menu or cancel that
|
|
278
|
+
// control's own Escape behavior.
|
|
266
279
|
private onDocumentKeydown = (e: KeyboardEvent) => {
|
|
267
|
-
if (e.key
|
|
268
|
-
|
|
280
|
+
if ((e.key !== "Escape" && e.key !== "Esc") || !this.handlesEscape(e)) {
|
|
281
|
+
return;
|
|
269
282
|
}
|
|
283
|
+
this.closeOnEscape(e);
|
|
270
284
|
};
|
|
271
285
|
|
|
286
|
+
private handlesEscape(e: KeyboardEvent): boolean {
|
|
287
|
+
if (!this._open || e.defaultPrevented) {
|
|
288
|
+
return false;
|
|
289
|
+
}
|
|
290
|
+
const host = this.template.host;
|
|
291
|
+
const path = e.composedPath();
|
|
292
|
+
for (const node of path) {
|
|
293
|
+
if (node instanceof Element && node.localName === "dx-popover") {
|
|
294
|
+
return node === host;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// A non-composed event fired in this shadow or on the trigger does
|
|
298
|
+
// not list the host. The panel and control listeners still apply.
|
|
299
|
+
return (
|
|
300
|
+
(this.popover !== null && path.includes(this.popover)) ||
|
|
301
|
+
(this.control !== null && path.includes(this.control))
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
private clearOpenListenersTimer() {
|
|
306
|
+
if (this.openListenersTimer !== undefined) {
|
|
307
|
+
clearTimeout(this.openListenersTimer);
|
|
308
|
+
this.openListenersTimer = undefined;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
272
312
|
private closeOnEscape(e: KeyboardEvent) {
|
|
273
313
|
if (!this.open) {
|
|
274
314
|
return;
|
|
@@ -300,7 +340,7 @@ export default class Popover extends LightningElement {
|
|
|
300
340
|
}
|
|
301
341
|
}
|
|
302
342
|
|
|
303
|
-
private onControlClick = () => {
|
|
343
|
+
private onControlClick = (e: MouseEvent) => {
|
|
304
344
|
if (this.controlled && this.open) {
|
|
305
345
|
this.dispatchRequestCloseEvent("click-control");
|
|
306
346
|
return;
|
|
@@ -321,7 +361,10 @@ export default class Popover extends LightningElement {
|
|
|
321
361
|
return;
|
|
322
362
|
}
|
|
323
363
|
|
|
324
|
-
|
|
364
|
+
// Enter/Space on a button synthesizes a click with detail 0. Only a
|
|
365
|
+
// pointer click should blur the trigger on Escape; keyboard activation
|
|
366
|
+
// must leave focus on the control.
|
|
367
|
+
this.pointerOpened = e.detail > 0;
|
|
325
368
|
this.openPopover();
|
|
326
369
|
};
|
|
327
370
|
|
|
@@ -110,6 +110,7 @@ export class TreeHandler {
|
|
|
110
110
|
link,
|
|
111
111
|
method: node.method,
|
|
112
112
|
showForwardArrow: node.showForwardArrow,
|
|
113
|
+
redirectToChild: node.redirectToChild,
|
|
113
114
|
versions: node.versions
|
|
114
115
|
};
|
|
115
116
|
|
|
@@ -122,7 +123,11 @@ export class TreeHandler {
|
|
|
122
123
|
|
|
123
124
|
this._nodeMap[convertedNode.key] = mapItem;
|
|
124
125
|
this.indexName(convertedNode.name, convertedNode.key);
|
|
125
|
-
|
|
126
|
+
// A redirect parent can carry a child's href. This index runs after
|
|
127
|
+
// the child, so recording it would make the parent win selection.
|
|
128
|
+
if (!convertedNode.redirectToChild) {
|
|
129
|
+
this.indexName(convertedNode.link?.href, convertedNode.key);
|
|
130
|
+
}
|
|
126
131
|
// Index this topic's own versioned URLs only. Parent-only switching
|
|
127
132
|
// URLs point at a child with content and must not steal that child's
|
|
128
133
|
// selection.
|
|
@@ -236,10 +236,14 @@ export default class TreeItem extends LightningElement {
|
|
|
236
236
|
this.sendGtm(event);
|
|
237
237
|
return;
|
|
238
238
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
this.
|
|
242
|
-
|
|
239
|
+
// No copied destination. A markdown descendant is selected below.
|
|
240
|
+
// A chain with no content page only expands.
|
|
241
|
+
if (!firstContentNode(this._treeNode)?.link?.href) {
|
|
242
|
+
const isSelectAction = false;
|
|
243
|
+
this.doExpand(isSelectAction);
|
|
244
|
+
this.sendGtm(event);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
243
247
|
}
|
|
244
248
|
|
|
245
249
|
if (this.isParent) {
|
|
@@ -45,18 +45,21 @@ export default class TreeTile extends LightningElement {
|
|
|
45
45
|
* screen reader users (WCAG 2.4.4)
|
|
46
46
|
*/
|
|
47
47
|
get linkAriaLabel(): string | null {
|
|
48
|
-
if (!this.treeNode.redirectToChild
|
|
48
|
+
if (!this.treeNode.redirectToChild) {
|
|
49
49
|
return null;
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
52
52
|
* The redirect can target a deep descendant, so walk the first-child
|
|
53
53
|
* chain to the node that owns the destination link and name it.
|
|
54
|
+
* The destination href may live on this anchor (parent-only topics do
|
|
55
|
+
* not copy it onto the parent node).
|
|
54
56
|
*/
|
|
55
57
|
let destination = this.treeNode.children?.[0];
|
|
56
58
|
while (destination?.redirectToChild) {
|
|
57
59
|
destination = destination.children?.[0];
|
|
58
60
|
}
|
|
59
|
-
|
|
61
|
+
const triggerHref = this.href || this.treeNode.link?.href;
|
|
62
|
+
return destination?.link?.href && destination.link.href === triggerHref
|
|
60
63
|
? `${this.treeNode.label}, opens ${destination.label}`
|
|
61
64
|
: null;
|
|
62
65
|
}
|