lightning-base-components 1.16.9-alpha → 1.17.2-alpha
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/metadata/raptor.json +25 -13
- package/package.json +7 -11
- package/scopedImports/@salesforce-internal-core.appVersion.js +1 -1
- package/scopedImports/@salesforce-label-LightningLookup.noAccess.js +1 -0
- package/scopedImports/@salesforce-label-LightningToast.close.js +1 -0
- package/src/lightning/accordionSection/accordionSection.html +2 -2
- package/src/lightning/accordionSection/accordionSection.js +21 -2
- package/src/lightning/baseCombobox/baseCombobox.html +1 -1
- package/src/lightning/baseCombobox/baseCombobox.js +17 -2
- package/src/lightning/baseCombobox/keyboard.js +26 -0
- package/src/lightning/buttonGroup/buttonGroup.css +9 -0
- package/src/lightning/buttonGroup/buttonGroup.html +1 -1
- package/src/lightning/buttonMenu/buttonMenu.html +2 -5
- package/src/lightning/buttonMenu/buttonMenu.js +1 -4
- package/src/lightning/buttonStateful/buttonStateful.html +2 -1
- package/src/lightning/buttonStateful/buttonStateful.js +10 -0
- package/src/lightning/card/__docs__/card.md +1 -1
- package/src/lightning/card/card.html +3 -1
- package/src/lightning/card/card.js +51 -15
- package/src/lightning/card/utils.js +0 -14
- package/src/lightning/checkboxGroup/checkboxGroup.html +1 -1
- package/src/lightning/datatable/renderManager.js +14 -5
- package/src/lightning/datatable/rowSelection.js +4 -4
- package/src/lightning/datatable/rows.js +1 -0
- package/src/lightning/datatable/templates/table/table.html +2 -0
- package/src/lightning/focusUtils/focus.js +42 -0
- package/src/lightning/focusUtils/focusUtils.js +1 -0
- package/src/lightning/formattedAddress/formattedAddress.js +1 -1
- package/src/lightning/input/input.html +5 -2
- package/src/lightning/input/input.js +13 -1
- package/src/lightning/modalBase/modalBase.js +7 -6
- package/src/lightning/primitiveBubble/primitiveBubble.css +9 -0
- package/src/lightning/primitiveBubble/primitiveBubble.js +3 -1
- package/src/lightning/primitiveCellActions/primitiveCellActions.html +1 -0
- package/src/lightning/primitiveCellActions/primitiveCellActions.js +1 -1
- package/src/lightning/primitiveCellFactory/cellWithStandardLayout.html +3 -1
- package/src/lightning/primitiveCellFactory/primitiveCellFactory.js +1 -0
- package/src/lightning/primitiveTreegridCellToggle/primitiveTreegridCellToggle.js +8 -3
- package/src/lightning/radioGroup/radioGroup.html +1 -1
- package/src/lightning/textarea/textarea.js +13 -1
- package/src/lightning/tooltipLibrary/tooltipLibrary.js +7 -0
- package/src/lightning/tree/tree.html +1 -1
- package/src/lightning/tree/tree.js +25 -1
- package/src/lightning/treeGrid/__docs__/treeGrid.md +12 -0
- package/src/lightning/treeGrid/treeGrid.js +12 -4
- package/src/lightning/utilsPrivate/ariaLevelHeadingUtils.js +11 -0
- package/src/lightning/utilsPrivate/os.js +36 -0
- package/src/lightning/utilsPrivate/utilsPrivate.js +7 -0
- package/src/lightning/verticalNavigationSection/verticalNavigationSection.html +1 -1
- package/src/lightning/verticalNavigationSection/verticalNavigationSection.js +22 -1
- package/scopedImports/@salesforce-label-LightningToast.missingToastLabel.js +0 -1
- package/scopedImports/@salesforce-label-LightningToastContainer.missingToastConfig.js +0 -1
- package/scopedImports/@salesforce-label-LightningToastContainer.missingToastProperty.js +0 -1
package/metadata/raptor.json
CHANGED
|
@@ -20,6 +20,9 @@
|
|
|
20
20
|
"actions"
|
|
21
21
|
],
|
|
22
22
|
"properties": [
|
|
23
|
+
{
|
|
24
|
+
"name": "headingLevel"
|
|
25
|
+
},
|
|
23
26
|
{
|
|
24
27
|
"name": "label"
|
|
25
28
|
},
|
|
@@ -352,6 +355,9 @@
|
|
|
352
355
|
"minVersion": "0.0",
|
|
353
356
|
"slotNames": [],
|
|
354
357
|
"properties": [
|
|
358
|
+
{
|
|
359
|
+
"name": "disabled"
|
|
360
|
+
},
|
|
355
361
|
{
|
|
356
362
|
"name": "groupOrder"
|
|
357
363
|
},
|
|
@@ -398,9 +404,15 @@
|
|
|
398
404
|
{
|
|
399
405
|
"name": "headingLevel"
|
|
400
406
|
},
|
|
407
|
+
{
|
|
408
|
+
"name": "hideHeader"
|
|
409
|
+
},
|
|
401
410
|
{
|
|
402
411
|
"name": "iconName"
|
|
403
412
|
},
|
|
413
|
+
{
|
|
414
|
+
"name": "label"
|
|
415
|
+
},
|
|
404
416
|
{
|
|
405
417
|
"name": "variant"
|
|
406
418
|
}
|
|
@@ -860,6 +872,7 @@
|
|
|
860
872
|
"minVersion": "54.0"
|
|
861
873
|
},
|
|
862
874
|
"experienceModelApi": {},
|
|
875
|
+
"f6Controller": {},
|
|
863
876
|
"fieldDependencyManager": {},
|
|
864
877
|
"fieldUtils": {},
|
|
865
878
|
"fileDownload": {
|
|
@@ -2339,19 +2352,7 @@
|
|
|
2339
2352
|
"slotNames": [],
|
|
2340
2353
|
"properties": [
|
|
2341
2354
|
{
|
|
2342
|
-
"name": "
|
|
2343
|
-
},
|
|
2344
|
-
{
|
|
2345
|
-
"name": "fieldLevelHelp"
|
|
2346
|
-
},
|
|
2347
|
-
{
|
|
2348
|
-
"name": "label"
|
|
2349
|
-
},
|
|
2350
|
-
{
|
|
2351
|
-
"name": "required"
|
|
2352
|
-
},
|
|
2353
|
-
{
|
|
2354
|
-
"name": "variant"
|
|
2355
|
+
"name": "disabled"
|
|
2355
2356
|
}
|
|
2356
2357
|
],
|
|
2357
2358
|
"methods": [
|
|
@@ -3560,6 +3561,11 @@
|
|
|
3560
3561
|
{
|
|
3561
3562
|
"name": "variant"
|
|
3562
3563
|
}
|
|
3564
|
+
],
|
|
3565
|
+
"methods": [
|
|
3566
|
+
{
|
|
3567
|
+
"name": "focus"
|
|
3568
|
+
}
|
|
3563
3569
|
]
|
|
3564
3570
|
},
|
|
3565
3571
|
"toastContainer": {
|
|
@@ -3588,6 +3594,9 @@
|
|
|
3588
3594
|
{
|
|
3589
3595
|
"name": "header"
|
|
3590
3596
|
},
|
|
3597
|
+
{
|
|
3598
|
+
"name": "headingLevel"
|
|
3599
|
+
},
|
|
3591
3600
|
{
|
|
3592
3601
|
"name": "items"
|
|
3593
3602
|
},
|
|
@@ -3808,6 +3817,9 @@
|
|
|
3808
3817
|
""
|
|
3809
3818
|
],
|
|
3810
3819
|
"properties": [
|
|
3820
|
+
{
|
|
3821
|
+
"name": "headingLevel"
|
|
3822
|
+
},
|
|
3811
3823
|
{
|
|
3812
3824
|
"name": "label"
|
|
3813
3825
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lightning-base-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.2-alpha",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"files": [
|
|
6
6
|
"external",
|
|
@@ -910,6 +910,10 @@
|
|
|
910
910
|
"name": "@salesforce/label/LightningLookup.messageWhenMissingInformation",
|
|
911
911
|
"path": "scopedImports/@salesforce-label-LightningLookup.messageWhenMissingInformation.js"
|
|
912
912
|
},
|
|
913
|
+
{
|
|
914
|
+
"name": "@salesforce/label/LightningLookup.noAccess",
|
|
915
|
+
"path": "scopedImports/@salesforce-label-LightningLookup.noAccess.js"
|
|
916
|
+
},
|
|
913
917
|
{
|
|
914
918
|
"name": "@salesforce/label/LightningPicklist.available",
|
|
915
919
|
"path": "scopedImports/@salesforce-label-LightningPicklist.available.js"
|
|
@@ -1067,16 +1071,8 @@
|
|
|
1067
1071
|
"path": "scopedImports/@salesforce-label-LightningToast.errorLabel.js"
|
|
1068
1072
|
},
|
|
1069
1073
|
{
|
|
1070
|
-
"name": "@salesforce/label/LightningToast.
|
|
1071
|
-
"path": "scopedImports/@salesforce-label-LightningToast.
|
|
1072
|
-
},
|
|
1073
|
-
{
|
|
1074
|
-
"name": "@salesforce/label/LightningToastContainer.missingToastProperty",
|
|
1075
|
-
"path": "scopedImports/@salesforce-label-LightningToastContainer.missingToastProperty.js"
|
|
1076
|
-
},
|
|
1077
|
-
{
|
|
1078
|
-
"name": "@salesforce/label/LightningToastContainer.missingToastConfig",
|
|
1079
|
-
"path": "scopedImports/@salesforce-label-LightningToastContainer.missingToastConfig.js"
|
|
1074
|
+
"name": "@salesforce/label/LightningToast.close",
|
|
1075
|
+
"path": "scopedImports/@salesforce-label-LightningToast.close.js"
|
|
1080
1076
|
},
|
|
1081
1077
|
{
|
|
1082
1078
|
"name": "@salesforce/label/Global_Entity.created_by",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '
|
|
1
|
+
export default '242';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default 'No access';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default 'Close';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<section class={computedSectionClasses}>
|
|
3
3
|
<div class="slds-accordion__summary">
|
|
4
|
-
<
|
|
4
|
+
<h2 aria-level={_privateHeadingAriaLevel} onkeydown={handleKeyDown} class="slds-accordion__summary-heading">
|
|
5
5
|
<button class="section-control slds-button slds-button_reset slds-accordion__summary-action"
|
|
6
6
|
type="button"
|
|
7
7
|
aria-expanded={computedAriaExpanded}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
</lightning-primitive-icon>
|
|
15
15
|
<span class="slds-accordion__summary-content" title={label}>{label}</span>
|
|
16
16
|
</button>
|
|
17
|
-
</
|
|
17
|
+
</h2>
|
|
18
18
|
<slot name="actions"></slot>
|
|
19
19
|
</div>
|
|
20
20
|
<div id='lgt-accordion-section' hidden={computedHidden} aria-hidden={computedAriaHidden} class="slds-accordion__content">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LightningElement, api, track } from 'lwc';
|
|
2
|
-
import { classSet } from 'lightning/utils';
|
|
3
2
|
import { generateUniqueId } from 'lightning/inputUtils';
|
|
4
|
-
import { keyCodes } from 'lightning/utilsPrivate';
|
|
3
|
+
import { keyCodes, isHeadingLevelValid } from 'lightning/utilsPrivate';
|
|
4
|
+
import { classSet } from 'lightning/utils';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* A single section that is nested in an accordion component.
|
|
@@ -30,6 +30,25 @@ export default class LightningAccordionSection extends LightningElement {
|
|
|
30
30
|
|
|
31
31
|
@track privateIsOpen = false;
|
|
32
32
|
|
|
33
|
+
_privateHeadingAriaLevel;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Changes the 'aria-level' attribute value for the
|
|
37
|
+
* <h2> markup tag in the card's title element. Supported values
|
|
38
|
+
* are (1, 2, 3, 4, 5, 6).
|
|
39
|
+
* @type {string | number}
|
|
40
|
+
*/
|
|
41
|
+
@api
|
|
42
|
+
get headingLevel() {
|
|
43
|
+
return this._privateHeadingAriaLevel;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
set headingLevel(value) {
|
|
47
|
+
if (isHeadingLevelValid(value)) {
|
|
48
|
+
this._privateHeadingAriaLevel = value;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
33
52
|
/**
|
|
34
53
|
* Section should have received focus, but hasn't yet.
|
|
35
54
|
*/
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
<template if:false={hasInputPill}>
|
|
76
76
|
<div class="slds-input__icon-group slds-input__icon-group_right">
|
|
77
77
|
<template if:true={showInputActivityIndicator}>
|
|
78
|
-
<div
|
|
78
|
+
<div class="slds-spinner slds-spinner_brand slds-spinner_x-small slds-input__spinner">
|
|
79
79
|
<span class="slds-assistive-text">{i18n.loadingText}</span>
|
|
80
80
|
<div class="slds-spinner__dot-a"></div>
|
|
81
81
|
<div class="slds-spinner__dot-b"></div>
|
|
@@ -95,6 +95,7 @@ export default class LightningBaseCombobox extends LightningElement {
|
|
|
95
95
|
_autocomplete = 'off';
|
|
96
96
|
originDisableDefaultHighlight;
|
|
97
97
|
privateDisableDefaultHighlight;
|
|
98
|
+
_editingMode = false;
|
|
98
99
|
|
|
99
100
|
constructor() {
|
|
100
101
|
super();
|
|
@@ -347,12 +348,14 @@ export default class LightningBaseCombobox extends LightningElement {
|
|
|
347
348
|
synchronizeAttrs(input, {
|
|
348
349
|
[ARIA_LABELLEDBY]: this.inputLabelledById,
|
|
349
350
|
[ARIA_DESCRIBEDBY]: this.computedAriaDescribedBy,
|
|
350
|
-
[ARIA_ACTIVEDESCENDANT]: this._activeElementDomId,
|
|
351
351
|
[ARIA_CONTROLS]: this.computedInputControls,
|
|
352
352
|
[ARIA_LABEL]: this.isUserInputDisabled
|
|
353
353
|
? this.computedButtonTriggerAriaLabel
|
|
354
354
|
: this.inputLabel,
|
|
355
355
|
[ARIA_INVALID]: this.computedAriaInvalid,
|
|
356
|
+
[ARIA_ACTIVEDESCENDANT]: this._editingMode
|
|
357
|
+
? undefined
|
|
358
|
+
: this._activeElementDomId,
|
|
356
359
|
});
|
|
357
360
|
}
|
|
358
361
|
|
|
@@ -605,6 +608,7 @@ export default class LightningBaseCombobox extends LightningElement {
|
|
|
605
608
|
|
|
606
609
|
handleOptionMouseEnter(event) {
|
|
607
610
|
if (event.target.hasAttribute('aria-selected')) {
|
|
611
|
+
this._editingMode = false;
|
|
608
612
|
this.highlightOption(event.target);
|
|
609
613
|
}
|
|
610
614
|
}
|
|
@@ -662,6 +666,10 @@ export default class LightningBaseCombobox extends LightningElement {
|
|
|
662
666
|
if (this.dropdownDisabled) {
|
|
663
667
|
return;
|
|
664
668
|
}
|
|
669
|
+
// For details: https://developer.mozilla.org/en-US/docs/Web/API/Element/keydown_event
|
|
670
|
+
if (event.isComposing || event.keyCode === 229) {
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
665
673
|
if (this.hasInputPill) {
|
|
666
674
|
this.handlePillKeyDown(event);
|
|
667
675
|
} else {
|
|
@@ -953,7 +961,7 @@ export default class LightningBaseCombobox extends LightningElement {
|
|
|
953
961
|
|
|
954
962
|
highlightDefaultItem() {
|
|
955
963
|
this.removeHighlight();
|
|
956
|
-
if (!this.privateDisableDefaultHighlight) {
|
|
964
|
+
if (!this.privateDisableDefaultHighlight && !this._editingMode) {
|
|
957
965
|
// eslint-disable-next-line @lwc/lwc/no-async-operation
|
|
958
966
|
requestAnimationFrame(() => {
|
|
959
967
|
this.highlightOptionAndScrollIntoView(
|
|
@@ -1041,6 +1049,13 @@ export default class LightningBaseCombobox extends LightningElement {
|
|
|
1041
1049
|
closeDropdown() {
|
|
1042
1050
|
that.closeDropdown();
|
|
1043
1051
|
},
|
|
1052
|
+
setEditingMode(isEditing) {
|
|
1053
|
+
that._editingMode = isEditing;
|
|
1054
|
+
if (isEditing) {
|
|
1055
|
+
that._activeElementDomId = null;
|
|
1056
|
+
}
|
|
1057
|
+
that.synchronizeA11y();
|
|
1058
|
+
},
|
|
1044
1059
|
};
|
|
1045
1060
|
}
|
|
1046
1061
|
|
|
@@ -157,6 +157,31 @@ const eventKeyToHandlerMap = {
|
|
|
157
157
|
Delete: handleDeletionKeys,
|
|
158
158
|
};
|
|
159
159
|
|
|
160
|
+
const NON_EDITING_KEYS = [
|
|
161
|
+
'Enter',
|
|
162
|
+
'PageUp',
|
|
163
|
+
'PageDown',
|
|
164
|
+
'Home',
|
|
165
|
+
'End',
|
|
166
|
+
'Down',
|
|
167
|
+
'Up',
|
|
168
|
+
'ArrowUp',
|
|
169
|
+
'ArrowDown',
|
|
170
|
+
'Esc',
|
|
171
|
+
'Escape',
|
|
172
|
+
'Tab',
|
|
173
|
+
];
|
|
174
|
+
const isAnEditingKey = (key) => {
|
|
175
|
+
return !NON_EDITING_KEYS.includes(key);
|
|
176
|
+
};
|
|
177
|
+
const handleEditingMode = ({ event, dropdownInterface }) => {
|
|
178
|
+
if (isAnEditingKey(event.key)) {
|
|
179
|
+
dropdownInterface.setEditingMode(true);
|
|
180
|
+
} else {
|
|
181
|
+
dropdownInterface.setEditingMode(false);
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
|
|
160
185
|
export function handleKeyDownOnInput({
|
|
161
186
|
event,
|
|
162
187
|
currentIndex,
|
|
@@ -168,4 +193,5 @@ export function handleKeyDownOnInput({
|
|
|
168
193
|
} else {
|
|
169
194
|
handleTypedCharacters(parameters);
|
|
170
195
|
}
|
|
196
|
+
handleEditingMode(parameters);
|
|
171
197
|
}
|
|
@@ -1,2 +1,11 @@
|
|
|
1
1
|
/* @import 'lightning/sldsCommon';
|
|
2
2
|
@import './button-group.slds.css'; */
|
|
3
|
+
|
|
4
|
+
/* Fix for lihgtning-button-icon not being flush with lightning-button, for details see: W-11658757
|
|
5
|
+
*
|
|
6
|
+
* :host:not([data-render-mode]) - specifies that this style will only be applied in synthetic shadow mode
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
:host:not([data-render-mode]) .fix_button-group-flexbox {
|
|
10
|
+
display: inline-flex;
|
|
11
|
+
}
|
|
@@ -11,8 +11,6 @@
|
|
|
11
11
|
onblur={handleBlur}
|
|
12
12
|
onfocus={handleFocus}
|
|
13
13
|
type="button"
|
|
14
|
-
aria-controls="lgt-button-menu-dropdown"
|
|
15
|
-
id="lgt-button-menu"
|
|
16
14
|
onmousedown={handleButtonMouseDown}
|
|
17
15
|
tabindex={tabIndex}
|
|
18
16
|
part="button button-icon">
|
|
@@ -40,10 +38,9 @@
|
|
|
40
38
|
<lightning-spinner size="small" alternative-text={computedLoadingStateAlternativeText}></lightning-spinner>
|
|
41
39
|
</template>
|
|
42
40
|
<template if:false={isLoading}>
|
|
43
|
-
<div
|
|
44
|
-
|
|
41
|
+
<div
|
|
42
|
+
class="slds-dropdown__list slds-dropdown_length-with-icon-10"
|
|
45
43
|
role="menu"
|
|
46
|
-
aria-labelledby="lgt-button-menu"
|
|
47
44
|
onprivateselect={handleMenuItemPrivateSelect}
|
|
48
45
|
onprivateblur={handlePrivateBlur}
|
|
49
46
|
onprivatefocus={handlePrivateFocus}
|
|
@@ -772,10 +772,7 @@ export default class LightningButtonMenu extends LightningElement {
|
|
|
772
772
|
// prevent blur during a non-blurring focus change
|
|
773
773
|
// set lock so that while focusing on menutitem, menu doesnt close
|
|
774
774
|
this.cancelBlur();
|
|
775
|
-
|
|
776
|
-
requestAnimationFrame(() => {
|
|
777
|
-
menuItem.focus();
|
|
778
|
-
});
|
|
775
|
+
menuItem.focus();
|
|
779
776
|
}
|
|
780
777
|
// allowBlur is called when the menu items receives focus
|
|
781
778
|
}
|
|
@@ -22,6 +22,11 @@ export default class LightningButtonStateful extends LightningElement {
|
|
|
22
22
|
isClicked: false,
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Passthrough to pass disabled attribute onto button
|
|
27
|
+
*/
|
|
28
|
+
@api disabled;
|
|
29
|
+
|
|
25
30
|
/**
|
|
26
31
|
* The name of the icon to be used in the format 'utility:check' when the state is true.
|
|
27
32
|
*
|
|
@@ -104,6 +109,11 @@ export default class LightningButtonStateful extends LightningElement {
|
|
|
104
109
|
this.state.selected = normalizeBoolean(value);
|
|
105
110
|
}
|
|
106
111
|
|
|
112
|
+
renderedCallback() {
|
|
113
|
+
// change host style to disable pointer event.
|
|
114
|
+
this.template.host.style.pointerEvents = this.disabled ? 'none' : '';
|
|
115
|
+
}
|
|
116
|
+
|
|
107
117
|
/**
|
|
108
118
|
* Sets focus on the button.
|
|
109
119
|
*/
|
|
@@ -111,4 +111,4 @@ This component has usage differences from its Aura counterpart. See [Base Compon
|
|
|
111
111
|
|
|
112
112
|
#### Source Code
|
|
113
113
|
|
|
114
|
-
`lightning-card` is available in the [Base Components Recipes GitHub repository](https://github.com/salesforce/base-components-recipes#documentation). It's transpiled into the `c` namespace so that you can use it in your own projects.
|
|
114
|
+
`lightning-card` is available in the [Base Components Recipes GitHub repository](https://github.com/salesforce/base-components-recipes#documentation). It's transpiled into the `c` namespace so that you can use it in your own projects.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<article class={computedWrapperClassNames} part="card">
|
|
2
|
+
<article class={computedWrapperClassNames} aria-label={label} part="card">
|
|
3
|
+
<template if:true={computedHidden}>
|
|
3
4
|
<div class="slds-card__header slds-grid">
|
|
4
5
|
<header class="slds-media slds-media_center slds-has-flexi-truncate" part="header">
|
|
5
6
|
<template if:true={hasIcon}>
|
|
@@ -32,6 +33,7 @@
|
|
|
32
33
|
</div>
|
|
33
34
|
</header>
|
|
34
35
|
</div>
|
|
36
|
+
</template>
|
|
35
37
|
<div class="slds-card__body" part="body">
|
|
36
38
|
<slot></slot>
|
|
37
39
|
</div>
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { LightningElement, api } from 'lwc';
|
|
2
2
|
import { classSet } from 'lightning/utils';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
isBase,
|
|
6
|
-
isHeadingLevelValid,
|
|
7
|
-
DEFAULT_HEADING_LEVEL,
|
|
8
|
-
} from './utils';
|
|
3
|
+
import { isNarrow, isBase } from './utils';
|
|
4
|
+
import { isHeadingLevelValid } from 'lightning/utilsPrivate';
|
|
9
5
|
|
|
10
6
|
/**
|
|
11
7
|
* Cards apply a container around a related grouping of information.
|
|
@@ -81,15 +77,7 @@ export default class LightningCard extends LightningElement {
|
|
|
81
77
|
}
|
|
82
78
|
}
|
|
83
79
|
|
|
84
|
-
_privateHeadingAriaLevel
|
|
85
|
-
|
|
86
|
-
set headingLevel(value) {
|
|
87
|
-
if (isHeadingLevelValid(value)) {
|
|
88
|
-
this._privateHeadingAriaLevel = value;
|
|
89
|
-
} else {
|
|
90
|
-
this._privateHeadingAriaLevel = DEFAULT_HEADING_LEVEL;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
80
|
+
_privateHeadingAriaLevel;
|
|
93
81
|
|
|
94
82
|
/**
|
|
95
83
|
* The headingLevel changes the 'aria-level' attribute value of
|
|
@@ -104,6 +92,12 @@ export default class LightningCard extends LightningElement {
|
|
|
104
92
|
return this._privateHeadingAriaLevel;
|
|
105
93
|
}
|
|
106
94
|
|
|
95
|
+
set headingLevel(value) {
|
|
96
|
+
if (isHeadingLevelValid(value)) {
|
|
97
|
+
this._privateHeadingAriaLevel = value;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
107
101
|
get titleSlot() {
|
|
108
102
|
return this.template.querySelector('slot[name=title]');
|
|
109
103
|
}
|
|
@@ -125,4 +119,46 @@ export default class LightningCard extends LightningElement {
|
|
|
125
119
|
get hasStringTitle() {
|
|
126
120
|
return !!this.title;
|
|
127
121
|
}
|
|
122
|
+
|
|
123
|
+
privateHeaderLabel;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Assistive label for the card header. Only shown if `hideHeader` attribute is set to `true`.
|
|
127
|
+
* @type {string}
|
|
128
|
+
*/
|
|
129
|
+
@api
|
|
130
|
+
get label() {
|
|
131
|
+
if (!this._hasTitle || this.hideHeader) {
|
|
132
|
+
return this.privateHeaderLabel;
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
set label(value) {
|
|
137
|
+
this.privateHeaderLabel = value;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
get computedHidden() {
|
|
141
|
+
if (!this.label && this.hideHeader) {
|
|
142
|
+
console.warn(
|
|
143
|
+
'Setting header without a label can cause accessibility issues'
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
return !this.hideHeader;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
hiddenHeader = false;
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Hides the header chunk of the card when set to `true`.
|
|
153
|
+
* Requires you to set the `label` attribute to supplement a non-rendered header. If `label` isn't set, you get a `console.warn` error.
|
|
154
|
+
* @type {boolean}
|
|
155
|
+
* @default {false}
|
|
156
|
+
*/
|
|
157
|
+
@api
|
|
158
|
+
get hideHeader() {
|
|
159
|
+
return this.hiddenHeader;
|
|
160
|
+
}
|
|
161
|
+
set hideHeader(value) {
|
|
162
|
+
this.hiddenHeader = value;
|
|
163
|
+
}
|
|
128
164
|
}
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* These are all values that can be set to "aria-level" attribute of h2 tag for the card's title.
|
|
3
|
-
*/
|
|
4
|
-
export const VALID_HEADING_LEVELS = ['1', '2', '3', '4', '5', '6'];
|
|
5
|
-
|
|
6
|
-
export const DEFAULT_HEADING_LEVEL = '2';
|
|
7
|
-
|
|
8
1
|
export function isNarrow(variant) {
|
|
9
2
|
return typeof variant === 'string' && variant.toLowerCase() === 'narrow';
|
|
10
3
|
}
|
|
@@ -12,10 +5,3 @@ export function isNarrow(variant) {
|
|
|
12
5
|
export function isBase(variant) {
|
|
13
6
|
return typeof variant === 'string' && variant.toLowerCase() === 'base';
|
|
14
7
|
}
|
|
15
|
-
|
|
16
|
-
export function isHeadingLevelValid(level) {
|
|
17
|
-
return (
|
|
18
|
-
(typeof level === 'string' || typeof level === 'number') &&
|
|
19
|
-
VALID_HEADING_LEVELS.includes(String(level))
|
|
20
|
-
);
|
|
21
|
-
}
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
</div>
|
|
31
31
|
|
|
32
32
|
<template if:true={_helpMessage}>
|
|
33
|
-
<div id="helptext" data-helptext class="slds-form-element__help">{_helpMessage}</div>
|
|
33
|
+
<div id="helptext" data-helptext role="alert" class="slds-form-element__help">{_helpMessage}</div>
|
|
34
34
|
</template>
|
|
35
35
|
|
|
36
36
|
</fieldset>
|
|
@@ -83,9 +83,11 @@ export class RenderManager {
|
|
|
83
83
|
if (normalizeBoolean(viewportRendering) || state.virtualize) {
|
|
84
84
|
this.initializeResizeObserver(state, getWrapperHeight);
|
|
85
85
|
}
|
|
86
|
+
let computedBufferSize =
|
|
87
|
+
typeof bufferSize != 'undefined' ? bufferSize : DEFAULT_BUFFER_SIZE;
|
|
86
88
|
state.bufferSize = normalizeNumberAttribute(
|
|
87
89
|
'bufferSize',
|
|
88
|
-
|
|
90
|
+
computedBufferSize,
|
|
89
91
|
'non-negative',
|
|
90
92
|
DEFAULT_BUFFER_SIZE
|
|
91
93
|
);
|
|
@@ -213,10 +215,17 @@ export class RenderManager {
|
|
|
213
215
|
const normalizedRowCount = rowCount
|
|
214
216
|
? Math.min(rowCount, totalRows)
|
|
215
217
|
: totalRows;
|
|
216
|
-
state
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
218
|
+
if (isViewportRenderingEnabled(state)) {
|
|
219
|
+
if (state.renderedRowCount < normalizedRowCount) {
|
|
220
|
+
state.renderedRowCount = normalizedRowCount;
|
|
221
|
+
// Update our internal cache
|
|
222
|
+
this.previousCache.renderedRowCount = normalizedRowCount;
|
|
223
|
+
}
|
|
224
|
+
} else {
|
|
225
|
+
state.renderedRowCount = normalizedRowCount;
|
|
226
|
+
// Update our internal cache
|
|
227
|
+
this.previousCache.renderedRowCount = normalizedRowCount;
|
|
228
|
+
}
|
|
220
229
|
this.previousCache.totalRowCount = totalRows;
|
|
221
230
|
|
|
222
231
|
if (rows.length > 0) {
|
|
@@ -51,7 +51,7 @@ export function handleSelectAllRows(event) {
|
|
|
51
51
|
event.stopPropagation();
|
|
52
52
|
markAllRowsSelected(this.state);
|
|
53
53
|
this.fireSelectedRowsChange(this.getSelectedRows(), {
|
|
54
|
-
|
|
54
|
+
action: ROWS_ACTION.SELECT_ALL_ROWS,
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -64,7 +64,7 @@ export function handleDeselectAllRows(event) {
|
|
|
64
64
|
event.stopPropagation();
|
|
65
65
|
markAllRowsDeselected(this.state);
|
|
66
66
|
this.fireSelectedRowsChange(this.getSelectedRows(), {
|
|
67
|
-
|
|
67
|
+
action: ROWS_ACTION.DESELECT_ALL_ROWS,
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
70
|
|
|
@@ -89,7 +89,7 @@ export function handleSelectRow(event) {
|
|
|
89
89
|
markSelectedRowsInterval(this.state, fromRowKey, rowKeyValue);
|
|
90
90
|
setLastRowSelection(this.state, rowKeyValue);
|
|
91
91
|
this.fireSelectedRowsChange(this.getSelectedRows(), {
|
|
92
|
-
|
|
92
|
+
action: ROWS_ACTION.ROW_SELECT,
|
|
93
93
|
value: rowKeyValue,
|
|
94
94
|
});
|
|
95
95
|
}
|
|
@@ -115,7 +115,7 @@ export function handleDeselectRow(event) {
|
|
|
115
115
|
markDeselectedRowsInterval(this.state, fromRowKey, rowKeyValue);
|
|
116
116
|
setLastRowSelection(this.state, rowKeyValue);
|
|
117
117
|
this.fireSelectedRowsChange(this.getSelectedRows(), {
|
|
118
|
-
|
|
118
|
+
action: ROWS_ACTION.ROW_DESELECT,
|
|
119
119
|
value: rowKeyValue,
|
|
120
120
|
});
|
|
121
121
|
}
|
|
@@ -173,6 +173,7 @@ export function updateRowsAndCellIndexes() {
|
|
|
173
173
|
: undefined,
|
|
174
174
|
dataLabel: colData.label,
|
|
175
175
|
value: computedCellValue, // value based on the fieldName
|
|
176
|
+
displayValue: rowData.displayValue ? rowData.displayValue : '',
|
|
176
177
|
rowKeyValue: row.key, // unique row key value
|
|
177
178
|
colKeyValue, // unique column key value
|
|
178
179
|
tabIndex: -1, // tabindex
|
|
@@ -167,6 +167,7 @@
|
|
|
167
167
|
row-key-value={row.key}
|
|
168
168
|
col-key-value={cell.colKeyValue}
|
|
169
169
|
value={cell.value}
|
|
170
|
+
display-value={cell.displayValue}
|
|
170
171
|
icon-name={cell.iconName}
|
|
171
172
|
icon-label={cell.iconLabel}
|
|
172
173
|
icon-position={cell.iconPosition}
|
|
@@ -216,6 +217,7 @@
|
|
|
216
217
|
row-key-value={row.key}
|
|
217
218
|
col-key-value={cell.colKeyValue}
|
|
218
219
|
value={cell.value}
|
|
220
|
+
display-value={cell.displayValue}
|
|
219
221
|
icon-name={cell.iconName}
|
|
220
222
|
icon-label={cell.iconLabel}
|
|
221
223
|
icon-position={cell.iconPosition}
|
|
@@ -81,6 +81,48 @@ export function getElementWithFocus() {
|
|
|
81
81
|
return undefined;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Return the focus to an element if it is still attached to the DOM.
|
|
86
|
+
* @param {Element} element - element which will receive the focus.
|
|
87
|
+
* @returns {boolean} - true if the element is focused.
|
|
88
|
+
*/
|
|
89
|
+
export function returnFocusToElement(element) {
|
|
90
|
+
const isSavedElemInDOM = document.body.contains(element);
|
|
91
|
+
if (element) {
|
|
92
|
+
if (isSavedElemInDOM) {
|
|
93
|
+
element.focus();
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
const isElementInDOM = isElementInDocument(element);
|
|
97
|
+
if (isElementInDOM) {
|
|
98
|
+
element.focus();
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Return true if the given element is in document (rather it is in shadow or not)
|
|
107
|
+
* @param {Element} element - element to be inspected
|
|
108
|
+
* @returns {boolean} - true if the element is in document, otherwise false
|
|
109
|
+
*/
|
|
110
|
+
function isElementInDocument(element) {
|
|
111
|
+
let currentElement = element;
|
|
112
|
+
// traverse all the way up to the document, to make sure
|
|
113
|
+
// the element is inside of the document.
|
|
114
|
+
while (currentElement && currentElement.parentNode) {
|
|
115
|
+
if (currentElement.parentNode === document) {
|
|
116
|
+
return true;
|
|
117
|
+
} else if (currentElement.parentNode instanceof DocumentFragment) {
|
|
118
|
+
currentElement = currentElement.parentNode.host;
|
|
119
|
+
} else {
|
|
120
|
+
currentElement = currentElement.parentNode;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
|
|
84
126
|
/**
|
|
85
127
|
* Recursively traverse an active tree and run callback on each non-inert node element.
|
|
86
128
|
*
|
|
@@ -220,7 +220,7 @@ export default class LightningFormattedAddress extends LightningElement {
|
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
get mapUrl() {
|
|
223
|
-
return encodeURI(MAP_HOST + this.mapQuery);
|
|
223
|
+
return encodeURI(MAP_HOST) + encodeURIComponent(this.mapQuery);
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
get addressLink() {
|
|
@@ -75,6 +75,7 @@
|
|
|
75
75
|
onblur={handleBlur}
|
|
76
76
|
onfocus={handleFocus}
|
|
77
77
|
onchange={handleChange}
|
|
78
|
+
onclick={handleCheckboxClick}
|
|
78
79
|
name={name}
|
|
79
80
|
required={required}
|
|
80
81
|
readonly={readOnly}
|
|
@@ -105,7 +106,7 @@
|
|
|
105
106
|
<abbr class="slds-required" title={i18n.required}>*</abbr>
|
|
106
107
|
</template>
|
|
107
108
|
</template>
|
|
108
|
-
<input type="checkbox"
|
|
109
|
+
<input type="checkbox"
|
|
109
110
|
part="checkbox"
|
|
110
111
|
id="checkbox"
|
|
111
112
|
aria-label={computedAriaLabel}
|
|
@@ -114,6 +115,7 @@
|
|
|
114
115
|
onblur={handleBlur}
|
|
115
116
|
onfocus={handleFocus}
|
|
116
117
|
onchange={handleChange}
|
|
118
|
+
onclick={handleCheckboxClick}
|
|
117
119
|
name={name}
|
|
118
120
|
required={required}
|
|
119
121
|
readonly={readOnly}
|
|
@@ -142,6 +144,7 @@
|
|
|
142
144
|
onblur={handleBlur}
|
|
143
145
|
onfocus={handleFocus}
|
|
144
146
|
onchange={handleChange}
|
|
147
|
+
onclick={handleCheckboxClick}
|
|
145
148
|
name={name}
|
|
146
149
|
required={required}
|
|
147
150
|
readonly={readOnly}
|
|
@@ -341,6 +344,6 @@
|
|
|
341
344
|
</template>
|
|
342
345
|
|
|
343
346
|
<template if:true={_helpMessage}>
|
|
344
|
-
<div id="help-message" class=
|
|
347
|
+
<div id="help-message" class={computedHelpMessageClass} data-help-message role="alert" part="help-text">{_helpMessage}</div>
|
|
345
348
|
</template>
|
|
346
349
|
</template>
|
|
@@ -533,7 +533,7 @@ export default class LightningInput extends LightningElement {
|
|
|
533
533
|
@api
|
|
534
534
|
get ariaLabelledBy() {
|
|
535
535
|
// native version returns the auto linked value
|
|
536
|
-
if (this.isNative) {
|
|
536
|
+
if (this.isNative && this._rendered) {
|
|
537
537
|
const ariaValues = this._inputElement.getAttribute(ARIA_LABELLEDBY);
|
|
538
538
|
return filterNonAutoLink(ariaValues);
|
|
539
539
|
}
|
|
@@ -1306,6 +1306,12 @@ export default class LightningInput extends LightningElement {
|
|
|
1306
1306
|
.toString();
|
|
1307
1307
|
}
|
|
1308
1308
|
|
|
1309
|
+
get computedHelpMessageClass() {
|
|
1310
|
+
return classSet('slds-form-element__help')
|
|
1311
|
+
.add({ 'slds-m-left_none': this.variant !== VARIANT.LABEL_INLINE })
|
|
1312
|
+
.toString();
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1309
1315
|
get normalizedMax() {
|
|
1310
1316
|
return this._normalizeDateTimeString(this.max);
|
|
1311
1317
|
}
|
|
@@ -1750,6 +1756,12 @@ export default class LightningInput extends LightningElement {
|
|
|
1750
1756
|
}
|
|
1751
1757
|
}
|
|
1752
1758
|
|
|
1759
|
+
handleCheckboxClick() {
|
|
1760
|
+
if (this.template.activeElement === null) {
|
|
1761
|
+
this.template.querySelector("[type='checkbox']").focus();
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1753
1765
|
handleChange(event) {
|
|
1754
1766
|
event.stopPropagation();
|
|
1755
1767
|
|
|
@@ -10,7 +10,10 @@ import {
|
|
|
10
10
|
isAriaDescriptionSupported,
|
|
11
11
|
} from 'lightning/utilsPrivate';
|
|
12
12
|
import { instanceName, secure } from 'lightning/overlayUtils';
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
getElementWithFocus,
|
|
15
|
+
returnFocusToElement,
|
|
16
|
+
} from 'lightning/focusUtils';
|
|
14
17
|
import closeButtonAltText from '@salesforce/label/LightningModalBase.cancelandclose';
|
|
15
18
|
import disableCloseBtnMessage from '@salesforce/label/LightningModalBase.waitstate';
|
|
16
19
|
|
|
@@ -147,7 +150,7 @@ export default class LightningModalBase extends LightningElement {
|
|
|
147
150
|
// we track both in order to handle transition correctly
|
|
148
151
|
const isSwitchingToDisabled =
|
|
149
152
|
!this.disableCloseButton && this.disableClose;
|
|
150
|
-
/* Future enhancement possibility - trigger setInterval to remove and
|
|
153
|
+
/* Future enhancement possibility - trigger setInterval to remove and
|
|
151
154
|
again add back 'Processing' text, as this will indicate to the screen
|
|
152
155
|
reader user that the interface continues to be busy
|
|
153
156
|
*/
|
|
@@ -349,10 +352,8 @@ export default class LightningModalBase extends LightningElement {
|
|
|
349
352
|
*/
|
|
350
353
|
returnFocusToBackground() {
|
|
351
354
|
const { savedActiveElement } = this;
|
|
352
|
-
const
|
|
353
|
-
if (
|
|
354
|
-
savedActiveElement.focus();
|
|
355
|
-
} else {
|
|
355
|
+
const elementWasFocused = returnFocusToElement(savedActiveElement);
|
|
356
|
+
if (!elementWasFocused) {
|
|
356
357
|
// eslint-disable-next-line no-console
|
|
357
358
|
console.warn('Modal :: Nothing to return focus to');
|
|
358
359
|
}
|
|
@@ -1,2 +1,11 @@
|
|
|
1
1
|
/* @import 'lightning/sldsCommon';
|
|
2
2
|
@import './tooltip.slds.css'; */
|
|
3
|
+
|
|
4
|
+
/* Fix for tooltip alignment issue, for details see: W-11677142
|
|
5
|
+
*
|
|
6
|
+
* fix-tooltip_alignment - the custom class that edits min-width
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
.fix-popover_tooltip_alignment {
|
|
10
|
+
min-width: inherit;
|
|
11
|
+
}
|
|
@@ -102,7 +102,9 @@ export default class LightningPrimitiveBubble extends LightningElement {
|
|
|
102
102
|
|
|
103
103
|
// compute class value for this bubble
|
|
104
104
|
get computedPopoverClass() {
|
|
105
|
-
const classes = classSet('slds-popover')
|
|
105
|
+
const classes = classSet('slds-popover')
|
|
106
|
+
.add('slds-popover_tooltip')
|
|
107
|
+
.add('fix-popover_tooltip_alignment'); // fix for W-11677142
|
|
106
108
|
|
|
107
109
|
// show or hide bubble
|
|
108
110
|
classes.add({
|
|
@@ -33,13 +33,13 @@ export default class PrimitiveCellActions extends LightningElement {
|
|
|
33
33
|
static delegatesFocus = true;
|
|
34
34
|
_isLoadingActions;
|
|
35
35
|
_menuAlignment = DEFAULT_MENU_ALIGNMENT;
|
|
36
|
-
_internalTabIndex = false;
|
|
37
36
|
|
|
38
37
|
/************************** PUBLIC ATTRIBUTES ***************************/
|
|
39
38
|
|
|
40
39
|
@api rowKeyValue;
|
|
41
40
|
@api colKeyValue;
|
|
42
41
|
@api rowActions;
|
|
42
|
+
@api internalTabIndex;
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
45
|
* Defines the current menu alignment
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
<template if:true={hasTreeData}>
|
|
9
9
|
<lightning-primitive-treegrid-cell-toggle row-key-value={rowKeyValue}
|
|
10
10
|
col-key-value={colKeyValue}
|
|
11
|
+
display-value={displayValue}
|
|
11
12
|
value={value}
|
|
12
13
|
has-children={typeAttribute21}
|
|
13
14
|
is-expanded={typeAttribute22}
|
|
@@ -33,6 +34,7 @@
|
|
|
33
34
|
row-key-value={rowKeyValue}
|
|
34
35
|
col-key-value={colKeyValue}
|
|
35
36
|
tabindex={internalTabIndex}
|
|
37
|
+
internal-tab-index={internalTabIndex}
|
|
36
38
|
menu-alignment={typeAttribute0}
|
|
37
39
|
row-actions={typeAttribute1}>
|
|
38
40
|
</lightning-primitive-cell-actions>
|
|
@@ -278,7 +280,7 @@
|
|
|
278
280
|
</button>
|
|
279
281
|
</template>
|
|
280
282
|
<!-- TODO: displayReadOnlyIcon is true only when the cell's "editable" property is false and its "displayReadOnlyIcon"
|
|
281
|
-
property is true. The markup in this template therefore cannot be rendered concurrently with the template above that checks
|
|
283
|
+
property is true. The markup in this template therefore cannot be rendered concurrently with the template above that checks
|
|
282
284
|
the editable property. -->
|
|
283
285
|
<template if:true={shouldDisplayReadOnlyIcon}>
|
|
284
286
|
<!-- TODO: Update the svg-classes once the SLDS team updates their read only icon design to not use classes that have the word 'button'
|
|
@@ -2,7 +2,7 @@ import labelCollapseBranch from '@salesforce/label/LightningPrimitiveCellTree.co
|
|
|
2
2
|
import labelExpandBranch from '@salesforce/label/LightningPrimitiveCellTree.expandBranch';
|
|
3
3
|
import { LightningElement, api } from 'lwc';
|
|
4
4
|
import { classSet, formatLabel } from 'lightning/utils';
|
|
5
|
-
import { normalizeBoolean } from 'lightning/utilsPrivate';
|
|
5
|
+
import { normalizeString, normalizeBoolean } from 'lightning/utilsPrivate';
|
|
6
6
|
|
|
7
7
|
const i18n = {
|
|
8
8
|
collapseBranch: labelCollapseBranch,
|
|
@@ -13,6 +13,7 @@ export default class PrivateTreeGridCellToggle extends LightningElement {
|
|
|
13
13
|
@api rowKeyValue;
|
|
14
14
|
@api colKeyValue;
|
|
15
15
|
@api value;
|
|
16
|
+
@api displayValue;
|
|
16
17
|
|
|
17
18
|
_expanded = false;
|
|
18
19
|
_hasChildren = false;
|
|
@@ -60,10 +61,14 @@ export default class PrivateTreeGridCellToggle extends LightningElement {
|
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
get buttonTitle() {
|
|
64
|
+
let title =
|
|
65
|
+
normalizeString(this.displayValue) !== ''
|
|
66
|
+
? this.displayValue
|
|
67
|
+
: this.value;
|
|
63
68
|
if (this.isExpanded) {
|
|
64
|
-
return formatLabel(i18n.collapseBranch,
|
|
69
|
+
return formatLabel(i18n.collapseBranch, title);
|
|
65
70
|
}
|
|
66
|
-
return formatLabel(i18n.expandBranch,
|
|
71
|
+
return formatLabel(i18n.expandBranch, title);
|
|
67
72
|
}
|
|
68
73
|
|
|
69
74
|
handleChevronClick() {
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
</div>
|
|
59
59
|
|
|
60
60
|
<template if:true={_helpMessage}>
|
|
61
|
-
<div data-help-message id="help-message" class="slds-form-element__help">{_helpMessage}</div>
|
|
61
|
+
<div data-help-message id="help-message" role="alert" class="slds-form-element__help">{_helpMessage}</div>
|
|
62
62
|
</template>
|
|
63
63
|
|
|
64
64
|
</fieldset>
|
|
@@ -102,6 +102,12 @@ export default class LightningTextarea extends LightningElement {
|
|
|
102
102
|
@track _helpMessage;
|
|
103
103
|
@track _fieldLevelHelp;
|
|
104
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Aria Described by value on parent lighting-textarea
|
|
107
|
+
* @type {string}
|
|
108
|
+
*/
|
|
109
|
+
@api ariaDescribedBy;
|
|
110
|
+
|
|
105
111
|
connectedCallback() {
|
|
106
112
|
this.classList.add('slds-form-element');
|
|
107
113
|
this.updateClassList();
|
|
@@ -433,7 +439,13 @@ export default class LightningTextarea extends LightningElement {
|
|
|
433
439
|
|
|
434
440
|
get computedUniqueHelpElementId() {
|
|
435
441
|
const helpMessage = this.template.querySelector('[data-help-message]');
|
|
436
|
-
|
|
442
|
+
let spaceSeperatedDescribedByIds = getRealDOMId(helpMessage);
|
|
443
|
+
if (this.ariaDescribedBy && spaceSeperatedDescribedByIds) {
|
|
444
|
+
spaceSeperatedDescribedByIds += ` ${this.ariaDescribedBy}`;
|
|
445
|
+
} else if (this.ariaDescribedBy) {
|
|
446
|
+
spaceSeperatedDescribedByIds = this.ariaDescribedBy;
|
|
447
|
+
}
|
|
448
|
+
return spaceSeperatedDescribedByIds;
|
|
437
449
|
}
|
|
438
450
|
|
|
439
451
|
_setInputValue(value) {
|
|
@@ -222,6 +222,13 @@ export class Tooltip {
|
|
|
222
222
|
this.hideIfNotSelfCover(event)
|
|
223
223
|
)
|
|
224
224
|
);
|
|
225
|
+
target.addEventListener('keydown', (event) => {
|
|
226
|
+
if (event.keyCode === 13 && !this._visible) {
|
|
227
|
+
this.toggle();
|
|
228
|
+
} else {
|
|
229
|
+
this.hide();
|
|
230
|
+
}
|
|
231
|
+
});
|
|
225
232
|
}
|
|
226
233
|
}
|
|
227
234
|
handleEscape(e) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="slds-tree_container">
|
|
3
3
|
<template if:true={header}>
|
|
4
|
-
<h4 class="slds-tree__group-header" id="treeheading">{header}</h4>
|
|
4
|
+
<h4 class="slds-tree__group-header" id="treeheading" aria-level={_privateHeadingAriaLevel}>{header}</h4>
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<lightning-tree-item if:true={hasChildren} class="slds-tree" role="tree" aria-labelledby={computedLabelledBy}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { LightningElement, api, track } from 'lwc';
|
|
2
2
|
import { TreeData } from './treeData';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
keyCodes,
|
|
5
|
+
deepCopy,
|
|
6
|
+
isHeadingLevelValid,
|
|
7
|
+
} from 'lightning/utilsPrivate';
|
|
4
8
|
|
|
5
9
|
/**
|
|
6
10
|
* Displays a nested tree.
|
|
@@ -41,6 +45,26 @@ export default class LightningTree extends LightningElement {
|
|
|
41
45
|
);
|
|
42
46
|
}
|
|
43
47
|
|
|
48
|
+
_privateHeadingAriaLevel;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Changes the 'aria-level' attribute value for the
|
|
52
|
+
* <h2> markup tag in the card's title element. Supported values
|
|
53
|
+
* are (1, 2, 3, 4, 5, 6).
|
|
54
|
+
*
|
|
55
|
+
* @type {string | number}
|
|
56
|
+
* @default 2
|
|
57
|
+
*/
|
|
58
|
+
@api
|
|
59
|
+
get headingLevel() {
|
|
60
|
+
return this._privateHeadingAriaLevel;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
set headingLevel(value) {
|
|
64
|
+
if (isHeadingLevelValid(value)) {
|
|
65
|
+
this._privateHeadingAriaLevel = value;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
44
68
|
/**
|
|
45
69
|
* An array of key-value pairs that describe the tree. See the Documentation tab for more information.
|
|
46
70
|
* @type {array}
|
|
@@ -507,6 +507,18 @@ Use the following `aria` attributes on `lightning-tree-grid` to provide a captio
|
|
|
507
507
|
| aria-label | string | Provides an assistive label to identify a table from other tables on a page. |
|
|
508
508
|
| aria-labelledby | ID reference list | Specifies the ID or list of IDs of the element or elements that contain visible descriptive text to caption or describe the table. |
|
|
509
509
|
|
|
510
|
+
You can add a `displayValue` on the dropdown arrow for a row. This `displayValue` replaces the default row `title` for the dropdown arrow's label.
|
|
511
|
+
|
|
512
|
+
```javascript
|
|
513
|
+
{
|
|
514
|
+
name: '125313-7j',
|
|
515
|
+
accountName: 'Dach-Welch',
|
|
516
|
+
displayValue: 'Display Value One',
|
|
517
|
+
phone: '995-523-7024',
|
|
518
|
+
}
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
|
|
510
522
|
##### Provide an Accessible Label for the Table
|
|
511
523
|
|
|
512
524
|
Use the `aria-label` attribute to provide a more descriptive label for the table for assistive technology. The `aria-label` attribute and its value are passed down to the rendered `table` element.
|
|
@@ -272,31 +272,39 @@ export default class LightningTreeGrid extends LightningElement {
|
|
|
272
272
|
|
|
273
273
|
handleRowSelection(event) {
|
|
274
274
|
event.stopPropagation();
|
|
275
|
+
let selectedRowKeys;
|
|
275
276
|
// pass the event through
|
|
276
|
-
switch (event.detail.config.
|
|
277
|
+
switch (event.detail.config.action) {
|
|
277
278
|
case ROWS_ACTION.ROW_SELECT:
|
|
279
|
+
selectedRowKeys = this._selectedRowKeys.slice();
|
|
278
280
|
this._selectedRowKeys.push(event.detail.config.value);
|
|
279
281
|
break;
|
|
280
282
|
case ROWS_ACTION.ROW_DESELECT: {
|
|
281
283
|
const index = this._selectedRowKeys.indexOf(
|
|
282
284
|
event.detail.config.value
|
|
283
285
|
);
|
|
286
|
+
selectedRowKeys = this._selectedRowKeys.slice();
|
|
284
287
|
this._selectedRowKeys.splice(index, 1);
|
|
285
|
-
|
|
286
288
|
break;
|
|
287
289
|
}
|
|
288
290
|
case ROWS_ACTION.SELECT_ALL_ROWS:
|
|
291
|
+
selectedRowKeys = this._selectedRowKeys.slice();
|
|
292
|
+
this._selectedRowKeys = this.getSelectedRowKeys(
|
|
293
|
+
event.detail.selectedRows
|
|
294
|
+
);
|
|
295
|
+
break;
|
|
289
296
|
case ROWS_ACTION.DESELECT_ALL_ROWS:
|
|
297
|
+
selectedRowKeys = this._selectedRowKeys.slice();
|
|
290
298
|
this._selectedRowKeys = this.getSelectedRowKeys(
|
|
291
299
|
event.detail.selectedRows
|
|
292
300
|
);
|
|
293
301
|
break;
|
|
294
302
|
default:
|
|
295
303
|
this._selectedRowKeys.push(event.detail.config.value);
|
|
304
|
+
selectedRowKeys = this._selectedRowKeys.slice();
|
|
296
305
|
break;
|
|
297
306
|
}
|
|
298
|
-
|
|
299
|
-
|
|
307
|
+
event.detail.config.selectedRowKeys = selectedRowKeys;
|
|
300
308
|
this.fireSelectedRowsChange(event.detail);
|
|
301
309
|
}
|
|
302
310
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* These are all values that can be set to "aria-level" attribute of h2 tag for the card's title.
|
|
3
|
+
*/
|
|
4
|
+
export const VALID_HEADING_LEVELS = ['1', '2', '3', '4', '5', '6'];
|
|
5
|
+
|
|
6
|
+
export function isHeadingLevelValid(level) {
|
|
7
|
+
return (
|
|
8
|
+
(typeof level === 'string' || typeof level === 'number') &&
|
|
9
|
+
VALID_HEADING_LEVELS.includes(level.toString())
|
|
10
|
+
);
|
|
11
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verify if user is using MAC OS or not
|
|
3
|
+
* @returns {boolean} - true if Mac OS
|
|
4
|
+
*/
|
|
5
|
+
export const isMacOSTest = ({ userAgent }) => {
|
|
6
|
+
return /(macintosh|macintel|macppc|mac68k|macos)/i.test(userAgent);
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Verify if user is using iOS or not
|
|
11
|
+
* @returns {boolean} - true, if iOS
|
|
12
|
+
*/
|
|
13
|
+
export const isiOSTest = ({ userAgent }) => {
|
|
14
|
+
return /(iphone|ipad|ipod)/i.test(userAgent);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Verify if user is using Windows OS or not
|
|
19
|
+
* @returns {boolean} - true, if Windows OS
|
|
20
|
+
*/
|
|
21
|
+
export const isWindowsOSTest = ({ userAgent }) => {
|
|
22
|
+
return /(win32|win64|windows)/i.test(userAgent);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Verify if user is using Android OS or not
|
|
27
|
+
* @returns {boolean} - true, if Android OS
|
|
28
|
+
*/
|
|
29
|
+
export const isAndroidOSTest = ({ userAgent }) => {
|
|
30
|
+
return /android/i.test(userAgent);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const isMacOS = isMacOSTest(navigator);
|
|
34
|
+
export const isWindowsOS = isWindowsOSTest(navigator);
|
|
35
|
+
export const isiOS = isiOSTest(navigator);
|
|
36
|
+
export const isAndroidOS = isAndroidOSTest(navigator);
|
|
@@ -42,8 +42,15 @@ export {
|
|
|
42
42
|
parseToFormattedParts,
|
|
43
43
|
} from './linkify';
|
|
44
44
|
export { isValidPageReference } from './pageReference';
|
|
45
|
+
export { isMacOS, isWindowsOS, isiOS, isAndroidOS } from './os';
|
|
46
|
+
|
|
45
47
|
import { smartSetAttribute } from './smartSetAttribute';
|
|
46
48
|
|
|
49
|
+
export {
|
|
50
|
+
VALID_HEADING_LEVELS,
|
|
51
|
+
isHeadingLevelValid,
|
|
52
|
+
} from './ariaLevelHeadingUtils.js';
|
|
53
|
+
|
|
47
54
|
/**
|
|
48
55
|
* @param {HTMLElement} element Element to act on
|
|
49
56
|
* @param {Object} values values and attributes to set, if the value is
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="slds-nav-vertical__section" onprivateoverflowregister={handleOverflowRegister}>
|
|
3
|
-
<h2 id="vertical-navigation-section-heading" class="slds-nav-vertical__title">{label}</h2>
|
|
3
|
+
<h2 id="vertical-navigation-section-heading" class="slds-nav-vertical__title" aria-level={_privateHeadingAriaLevel}>{label}</h2>
|
|
4
4
|
<div role="list" aria-describedby="vertical-navigation-section-heading">
|
|
5
5
|
<slot></slot>
|
|
6
6
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LightningElement, api, track } from 'lwc';
|
|
2
|
-
import { guid } from 'lightning/utilsPrivate';
|
|
2
|
+
import { guid, isHeadingLevelValid } from 'lightning/utilsPrivate';
|
|
3
3
|
|
|
4
4
|
export default class LightningVerticalNavigationSection extends LightningElement {
|
|
5
5
|
headingId = guid();
|
|
@@ -28,4 +28,25 @@ export default class LightningVerticalNavigationSection extends LightningElement
|
|
|
28
28
|
const item = event.detail;
|
|
29
29
|
item.callbacks.updateAssistiveText(this.label);
|
|
30
30
|
}
|
|
31
|
+
|
|
32
|
+
_privateHeadingAriaLevel;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Changes the 'aria-level' attribute value for the
|
|
36
|
+
* <h2> markup tag in the card's title element. Supported values
|
|
37
|
+
* are (1, 2, 3, 4, 5, 6).
|
|
38
|
+
*
|
|
39
|
+
* @type {string | number}
|
|
40
|
+
* @default 2
|
|
41
|
+
*/
|
|
42
|
+
@api
|
|
43
|
+
get headingLevel() {
|
|
44
|
+
return this._privateHeadingAriaLevel;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
set headingLevel(value) {
|
|
48
|
+
if (isHeadingLevelValid(value)) {
|
|
49
|
+
this._privateHeadingAriaLevel = value;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
31
52
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default 'Provide at least the "label" property to show the toast.';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default 'Unable to show toast, missing toast config.';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default 'Unable to show toast, missing toast property\'s "{0}".';
|