lightning-base-components 1.13.10-alpha → 1.14.4-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 +24 -0
- package/package.json +20 -4
- package/scopedImports/@salesforce-internal-core.appVersion.js +1 -1
- package/scopedImports/@salesforce-label-LightningDualListbox.movedOptionsPlural.js +1 -0
- package/scopedImports/@salesforce-label-LightningDualListbox.movedOptionsSingular.js +1 -0
- package/scopedImports/@salesforce-label-LightningErrorMessage.validitySelectAtleastOne.js +1 -0
- package/scopedImports/@salesforce-label-LightningMap.titleWithAddress.js +1 -0
- package/scopedImports/@salesforce-label-LightningModalBase.cancelandclose.js +1 -0
- package/src/lightning/ariaObserver/__component__/ariaObserver.spec.js +112 -0
- package/src/lightning/ariaObserver/__docs__/ariaObserver.md +142 -0
- package/src/lightning/{utilsPrivate/contentMutation.js → ariaObserver/ariaObserver.js} +60 -98
- package/src/lightning/buttonMenu/keyboard.js +0 -10
- package/src/lightning/card/card.html +6 -0
- package/src/lightning/checkboxGroup/checkboxGroup.html +2 -2
- package/src/lightning/checkboxGroup/checkboxGroup.js +6 -1
- package/src/lightning/colorPickerCustom/colorPickerCustom.js +20 -1
- package/src/lightning/datatable/__docs__/datatable.md +55 -0
- package/src/lightning/datatable/__examples__/basic/basic.html +1 -1
- package/src/lightning/datatable/columns-shared.js +1 -1
- package/src/lightning/datatable/datatable.js +98 -30
- package/src/lightning/datatable/errors.js +20 -9
- package/src/lightning/datatable/headerActions.js +77 -49
- package/src/lightning/datatable/infiniteLoading.js +100 -28
- package/src/lightning/datatable/inlineEdit.js +505 -379
- package/src/lightning/datatable/inlineEditShared.js +24 -0
- package/src/lightning/datatable/keyboard.js +162 -127
- package/src/lightning/datatable/renderManager.js +201 -133
- package/src/lightning/datatable/rowLevelActions.js +17 -13
- package/src/lightning/datatable/rowNumber.js +54 -20
- package/src/lightning/datatable/rowSelection.js +760 -0
- package/src/lightning/datatable/rowSelectionShared.js +79 -0
- package/src/lightning/datatable/rows.js +17 -6
- package/src/lightning/datatable/state.js +16 -2
- package/src/lightning/datatable/templates/div/div.css +4 -0
- package/src/lightning/datatable/templates/div/div.html +6 -0
- package/src/lightning/datatable/templates/table/table.html +5 -0
- package/src/lightning/datatable/utils.js +14 -0
- package/src/lightning/datatable/wrapText.js +77 -47
- package/src/lightning/dualListbox/dualListbox.html +1 -1
- package/src/lightning/dualListbox/dualListbox.js +42 -0
- package/src/lightning/formattedDateTime/__docs__/formattedDateTime.md +36 -3
- package/src/lightning/formattedDateTime/__examples__/datetime/datetime.html +2 -2
- package/src/lightning/formattedDateTime/__examples__/datetime/datetime.js +3 -1
- package/src/lightning/formattedDateTime/__examples__/time/time.html +1 -1
- package/src/lightning/formattedDateTime/__examples__/time/time.js +3 -1
- package/src/lightning/formattedDateTime/formattedDateTime.js +1 -0
- package/src/lightning/input/input.html +1 -5
- package/src/lightning/input/input.js +69 -48
- package/src/lightning/inputUtils/validity.js +12 -1
- package/src/lightning/pillContainer/__docs__/pillContainer.md +45 -1
- package/src/lightning/primitiveCellActions/primitiveCellActions.js +69 -12
- package/src/lightning/primitiveCellFactory/cellWithStandardLayout.html +13 -11
- package/src/lightning/primitiveCellFactory/primitiveCellFactory.js +13 -8
- package/src/lightning/primitiveDatatableIeditPanel/primitiveDatatableIeditPanel.html +17 -14
- package/src/lightning/primitiveDatatableIeditPanel/primitiveDatatableIeditPanel.js +167 -98
- package/src/lightning/primitiveDatatableIeditTypeFactory/primitiveDatatableIeditTypeFactory.js +94 -69
- package/src/lightning/primitiveDatatableStatusBar/primitiveDatatableStatusBar.html +4 -4
- package/src/lightning/primitiveDatatableStatusBar/primitiveDatatableStatusBar.js +4 -4
- package/src/lightning/primitiveHeaderActions/primitiveHeaderActions.js +99 -37
- package/src/lightning/progressIndicator/progressIndicator.js +1 -1
- package/src/lightning/progressStep/progressStep.js +30 -22
- package/src/lightning/staticMap/staticMap.html +1 -0
- package/src/lightning/staticMap/staticMap.js +39 -2
- package/src/lightning/utils/classSet.js +4 -1
- package/src/lightning/utilsPrivate/utilsPrivate.js +12 -1
- package/scopedImports/@salesforce-label-LightningModalBase.close.js +0 -1
- package/src/lightning/datatable/inlineEdit-shared.js +0 -14
- package/src/lightning/datatable/selector-shared.js +0 -38
- package/src/lightning/datatable/selector.js +0 -527
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<p><lightning-formatted-date-time value="1547250828000" hour="2-digit" second="2-digit"></lightning-formatted-date-time></p>
|
|
6
6
|
<p><lightning-formatted-date-time value="1547250828000" hour="2-digit" minute="2-digit" time-zone="UTC"
|
|
7
7
|
time-zone-name="short"></lightning-formatted-date-time></p>
|
|
8
|
-
<p><lightning-formatted-date-time value="1547250828000" hour="2-digit" minute="2-digit" second="2-digit" hour12=
|
|
8
|
+
<p><lightning-formatted-date-time value="1547250828000" hour="2-digit" minute="2-digit" second="2-digit" hour12={ampm}
|
|
9
9
|
time-zone-name="long"></lightning-formatted-date-time></p>
|
|
10
10
|
</div>
|
|
11
11
|
</template>
|
|
@@ -92,6 +92,7 @@ export default class LightningFormattedDateTime extends LightningElement {
|
|
|
92
92
|
|
|
93
93
|
/**
|
|
94
94
|
* Determines whether time is displayed as 12-hour. If false, time displays as 24-hour. The default setting is determined by the user's locale.
|
|
95
|
+
* Set the value using a variable. If set to any string directly, the component interprets its value as true.
|
|
95
96
|
* @type {boolean}
|
|
96
97
|
*
|
|
97
98
|
*/
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<span data-aria class="slds-assistive-text"></span>
|
|
3
2
|
<template if:true={isTypeSimple}>
|
|
4
3
|
<template if:false={hasExternalLabel}>
|
|
5
4
|
<label class={computedLabelClass} for="input">
|
|
@@ -203,7 +202,6 @@
|
|
|
203
202
|
</div>
|
|
204
203
|
</template>
|
|
205
204
|
|
|
206
|
-
|
|
207
205
|
<template if:true={isTypeColor}>
|
|
208
206
|
<div class="slds-color-picker">
|
|
209
207
|
<div class="slds-form-element slds-color-picker__summary">
|
|
@@ -214,6 +212,7 @@
|
|
|
214
212
|
</template>
|
|
215
213
|
{label}
|
|
216
214
|
</label>
|
|
215
|
+
<lightning-helptext if:true={fieldLevelHelp} content={fieldLevelHelp} alternative-text={helptextAlternativeText}></lightning-helptext>
|
|
217
216
|
</template>
|
|
218
217
|
<div class="slds-form-element__control">
|
|
219
218
|
<lightning-primitive-colorpicker-button
|
|
@@ -240,9 +239,6 @@
|
|
|
240
239
|
oninput={handleInput}>
|
|
241
240
|
</div>
|
|
242
241
|
</div>
|
|
243
|
-
<template if:false={hasExternalLabel}>
|
|
244
|
-
<lightning-helptext if:true={fieldLevelHelp} content={fieldLevelHelp} alternative-text={helptextAlternativeText}></lightning-helptext>
|
|
245
|
-
</template>
|
|
246
242
|
</div>
|
|
247
243
|
</div>
|
|
248
244
|
</template>
|
|
@@ -18,9 +18,9 @@ import { classSet, formatLabel } from 'lightning/utils';
|
|
|
18
18
|
import {
|
|
19
19
|
assert,
|
|
20
20
|
classListMutation,
|
|
21
|
-
ContentMutation,
|
|
22
21
|
getRealDOMId,
|
|
23
22
|
isSafari,
|
|
23
|
+
isNativeComponent,
|
|
24
24
|
isNotUndefinedOrNull,
|
|
25
25
|
isUndefinedOrNull,
|
|
26
26
|
normalizeAriaAttribute,
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
decorateInputForDragon,
|
|
32
32
|
setDecoratedDragonInputValueWithoutEvent,
|
|
33
33
|
} from 'lightning/utilsPrivate';
|
|
34
|
+
import AriaObserver from 'lightning/ariaObserver';
|
|
34
35
|
import { normalizeInput } from './normalize';
|
|
35
36
|
import {
|
|
36
37
|
normalizeDate,
|
|
@@ -76,7 +77,7 @@ const i18n = {
|
|
|
76
77
|
|
|
77
78
|
const ARIA_CONTROLS = 'aria-controls';
|
|
78
79
|
const ARIA_LABEL = 'aria-label';
|
|
79
|
-
const
|
|
80
|
+
const ARIA_LABELLEDBY = 'aria-labelledby';
|
|
80
81
|
const ARIA_DESCRIBEDBY = 'aria-describedby';
|
|
81
82
|
|
|
82
83
|
/*
|
|
@@ -306,13 +307,11 @@ export default class LightningInput extends LightningElement {
|
|
|
306
307
|
|
|
307
308
|
constructor() {
|
|
308
309
|
super();
|
|
309
|
-
this.ariaObserver = new
|
|
310
|
+
this.ariaObserver = new AriaObserver(this);
|
|
310
311
|
|
|
311
312
|
// Native Shadow Root will return [native code].
|
|
312
313
|
// Our synthetic method will return the function source.
|
|
313
|
-
this.isNative = this
|
|
314
|
-
.toString()
|
|
315
|
-
.match(/\[native code\]/);
|
|
314
|
+
this.isNative = isNativeComponent(this);
|
|
316
315
|
|
|
317
316
|
// The selection cache allows us an input to remember what text was selected
|
|
318
317
|
// in cases where we change the text on blur or in browsers (Safari) that
|
|
@@ -322,12 +321,12 @@ export default class LightningInput extends LightningElement {
|
|
|
322
321
|
|
|
323
322
|
connectedCallback() {
|
|
324
323
|
if (!this.ariaObserver) {
|
|
325
|
-
this.ariaObserver = new
|
|
324
|
+
this.ariaObserver = new AriaObserver(this);
|
|
326
325
|
}
|
|
327
326
|
// Manually track connected state because this.template.isConnected can be false
|
|
328
327
|
// when input is created using createElement and inserted into dom manually.
|
|
329
328
|
// i.e. create an input element and pass it to showCustomOverlay
|
|
330
|
-
// Remove this state and the one in
|
|
329
|
+
// Remove this state and the one in AriaObserver once the issue is fixed.
|
|
331
330
|
// PR: https://github.com/salesforce/lwc/pull/1798
|
|
332
331
|
this.isConnected = true;
|
|
333
332
|
|
|
@@ -523,12 +522,11 @@ export default class LightningInput extends LightningElement {
|
|
|
523
522
|
|
|
524
523
|
set ariaControls(references) {
|
|
525
524
|
this._ariaControls = references;
|
|
526
|
-
this.ariaObserver.
|
|
527
|
-
'input',
|
|
528
|
-
|
|
529
|
-
references,
|
|
530
|
-
|
|
531
|
-
);
|
|
525
|
+
this.ariaObserver.connect({
|
|
526
|
+
targetSelector: 'input',
|
|
527
|
+
attribute: ARIA_CONTROLS,
|
|
528
|
+
ids: references,
|
|
529
|
+
});
|
|
532
530
|
}
|
|
533
531
|
|
|
534
532
|
/**
|
|
@@ -539,8 +537,7 @@ export default class LightningInput extends LightningElement {
|
|
|
539
537
|
get ariaLabelledBy() {
|
|
540
538
|
// native version returns the auto linked value
|
|
541
539
|
if (this.isNative) {
|
|
542
|
-
const ariaValues =
|
|
543
|
-
this._inputElement.getAttribute('aria-labelledby');
|
|
540
|
+
const ariaValues = this._inputElement.getAttribute(ARIA_LABELLEDBY);
|
|
544
541
|
return filterNonAutoLink(ariaValues);
|
|
545
542
|
}
|
|
546
543
|
return this._ariaLabelledBy;
|
|
@@ -548,12 +545,11 @@ export default class LightningInput extends LightningElement {
|
|
|
548
545
|
|
|
549
546
|
set ariaLabelledBy(references) {
|
|
550
547
|
this._ariaLabelledBy = references;
|
|
551
|
-
this.ariaObserver.
|
|
552
|
-
'input',
|
|
553
|
-
|
|
554
|
-
references,
|
|
555
|
-
|
|
556
|
-
);
|
|
548
|
+
this.ariaObserver.connect({
|
|
549
|
+
targetSelector: 'input',
|
|
550
|
+
attribute: ARIA_LABELLEDBY,
|
|
551
|
+
ids: references,
|
|
552
|
+
});
|
|
557
553
|
}
|
|
558
554
|
|
|
559
555
|
/**
|
|
@@ -565,7 +561,7 @@ export default class LightningInput extends LightningElement {
|
|
|
565
561
|
if (this.isNative) {
|
|
566
562
|
// in native case return the linked value
|
|
567
563
|
const ariaValues =
|
|
568
|
-
this._inputElement.getAttribute(
|
|
564
|
+
this._inputElement.getAttribute(ARIA_DESCRIBEDBY);
|
|
569
565
|
return filterNonAutoLink(ariaValues);
|
|
570
566
|
}
|
|
571
567
|
return this._ariaDescribedBy;
|
|
@@ -573,12 +569,11 @@ export default class LightningInput extends LightningElement {
|
|
|
573
569
|
|
|
574
570
|
set ariaDescribedBy(references) {
|
|
575
571
|
this._ariaDescribedBy = references;
|
|
576
|
-
this.ariaObserver.
|
|
577
|
-
'input',
|
|
578
|
-
|
|
579
|
-
references,
|
|
580
|
-
|
|
581
|
-
);
|
|
572
|
+
this.ariaObserver.connect({
|
|
573
|
+
targetSelector: 'input',
|
|
574
|
+
attribute: ARIA_DESCRIBEDBY,
|
|
575
|
+
ids: references,
|
|
576
|
+
});
|
|
582
577
|
}
|
|
583
578
|
|
|
584
579
|
/**
|
|
@@ -2037,32 +2032,58 @@ export default class LightningInput extends LightningElement {
|
|
|
2037
2032
|
return result;
|
|
2038
2033
|
}
|
|
2039
2034
|
|
|
2035
|
+
_updateInputA11y(elem) {
|
|
2036
|
+
synchronizeAttrs(elem, {
|
|
2037
|
+
[ARIA_LABELLEDBY]: this.computedAriaLabelledBy,
|
|
2038
|
+
[ARIA_DESCRIBEDBY]: this.computedAriaDescribedBy,
|
|
2039
|
+
[ARIA_CONTROLS]: this.computedAriaControls,
|
|
2040
|
+
[ARIA_LABEL]: this.computedAriaLabel,
|
|
2041
|
+
});
|
|
2042
|
+
}
|
|
2043
|
+
|
|
2044
|
+
_updateDateOrTimePickerA11y(elem) {
|
|
2045
|
+
synchronizeAttrs(elem, {
|
|
2046
|
+
ariaLabelledByElement: this.ariaLabelledBy,
|
|
2047
|
+
ariaDescribedByElements: this.ariaDescribedBy,
|
|
2048
|
+
ariaControlsElement: this.ariaControls,
|
|
2049
|
+
[ARIA_LABEL]: this.computedAriaLabel,
|
|
2050
|
+
});
|
|
2051
|
+
}
|
|
2052
|
+
|
|
2053
|
+
_updateDateTimePickerA11y(elem) {
|
|
2054
|
+
synchronizeAttrs(elem, {
|
|
2055
|
+
// datepicker aria attributes
|
|
2056
|
+
dateAriaLabelledBy: this.dateAriaLabelledBy,
|
|
2057
|
+
dateAriaDescribedBy: this.dateAriaDescribedBy,
|
|
2058
|
+
dateAriaControls: this.dateAriaControls,
|
|
2059
|
+
dateAriaLabel: this.dateAriaLabel,
|
|
2060
|
+
// timepicker aria attributes
|
|
2061
|
+
timeAriaLabelledBy: this.timeAriaLabelledBy,
|
|
2062
|
+
timeAriaDescribedBy: this.timeAriaDescribedBy,
|
|
2063
|
+
timeAriaControls: this.timeAriaControls,
|
|
2064
|
+
timeAriaLabel: this.timeAriaLabel,
|
|
2065
|
+
});
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2040
2068
|
_synchronizeA11y() {
|
|
2069
|
+
// each of these templates are mutually exclusive and are selected
|
|
2070
|
+
// depending on the [type] of input.
|
|
2041
2071
|
const input = this.template.querySelector('input');
|
|
2042
2072
|
const datepicker = this.template.querySelector('lightning-datepicker');
|
|
2043
2073
|
const timepicker = this.template.querySelector('lightning-timepicker');
|
|
2044
|
-
|
|
2074
|
+
const datetimepicker = this.template.querySelector(
|
|
2075
|
+
'lightning-datetimepicker'
|
|
2076
|
+
);
|
|
2077
|
+
// determine which template type is present,
|
|
2078
|
+
// and update a11y props accordingly
|
|
2045
2079
|
if (input) {
|
|
2046
|
-
|
|
2047
|
-
[ARIA_LABELEDBY]: this.computedAriaLabelledBy,
|
|
2048
|
-
[ARIA_DESCRIBEDBY]: this.computedAriaDescribedBy,
|
|
2049
|
-
[ARIA_CONTROLS]: this.computedAriaControls,
|
|
2050
|
-
[ARIA_LABEL]: this.computedAriaLabel,
|
|
2051
|
-
});
|
|
2080
|
+
this._updateInputA11y(input);
|
|
2052
2081
|
} else if (datepicker) {
|
|
2053
|
-
|
|
2054
|
-
ariaLabelledByElement: this.ariaLabelledBy,
|
|
2055
|
-
ariaDescribedByElements: this.ariaDescribedBy,
|
|
2056
|
-
ariaControlsElement: this.ariaControls,
|
|
2057
|
-
[ARIA_LABEL]: this.computedAriaLabel,
|
|
2058
|
-
});
|
|
2082
|
+
this._updateDateOrTimePickerA11y(datepicker);
|
|
2059
2083
|
} else if (timepicker) {
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
ariaControlsElement: this.ariaControls,
|
|
2064
|
-
[ARIA_LABEL]: this.computedAriaLabel,
|
|
2065
|
-
});
|
|
2084
|
+
this._updateDateOrTimePickerA11y(timepicker);
|
|
2085
|
+
} else if (datetimepicker) {
|
|
2086
|
+
this._updateDateTimePickerA11y(datetimepicker);
|
|
2066
2087
|
}
|
|
2067
2088
|
}
|
|
2068
2089
|
}
|
|
@@ -7,6 +7,7 @@ import labelTooLong from '@salesforce/label/LightningErrorMessage.validityTooLon
|
|
|
7
7
|
import labelTooShort from '@salesforce/label/LightningErrorMessage.validityTooShort';
|
|
8
8
|
import labelTypeMismatch from '@salesforce/label/LightningErrorMessage.validityTypeMismatch';
|
|
9
9
|
import labelValueMissing from '@salesforce/label/LightningErrorMessage.validityValueMissing';
|
|
10
|
+
import labelSelectAtleastOneValue from '@salesforce/label/LightningErrorMessage.validitySelectAtleastOne';
|
|
10
11
|
import { assert } from 'lightning/utilsPrivate';
|
|
11
12
|
|
|
12
13
|
const constraintsSortedByPriority = [
|
|
@@ -20,6 +21,7 @@ const constraintsSortedByPriority = [
|
|
|
20
21
|
'tooShort',
|
|
21
22
|
'typeMismatch',
|
|
22
23
|
'valueMissing',
|
|
24
|
+
'selectAtleastOneValue',
|
|
23
25
|
];
|
|
24
26
|
|
|
25
27
|
const defaultLabels = {
|
|
@@ -33,6 +35,7 @@ const defaultLabels = {
|
|
|
33
35
|
tooShort: labelTooShort,
|
|
34
36
|
typeMismatch: labelTypeMismatch,
|
|
35
37
|
valueMissing: labelValueMissing,
|
|
38
|
+
selectAtleastOneValue: labelSelectAtleastOneValue,
|
|
36
39
|
};
|
|
37
40
|
|
|
38
41
|
function resolveBestMatch(validity) {
|
|
@@ -103,6 +106,12 @@ function newValidityState(constraintsProvider) {
|
|
|
103
106
|
get badInput() {
|
|
104
107
|
return computeConstraint(constraintsProvider, 'badInput');
|
|
105
108
|
}
|
|
109
|
+
get selectAtleastOneValue() {
|
|
110
|
+
return computeConstraint(
|
|
111
|
+
constraintsProvider,
|
|
112
|
+
'validitySelectAtleastOneValue'
|
|
113
|
+
);
|
|
114
|
+
}
|
|
106
115
|
|
|
107
116
|
get valid() {
|
|
108
117
|
return !(
|
|
@@ -115,7 +124,8 @@ function newValidityState(constraintsProvider) {
|
|
|
115
124
|
this.rangeOverflow ||
|
|
116
125
|
this.stepMismatch ||
|
|
117
126
|
this.customError ||
|
|
118
|
-
this.badInput
|
|
127
|
+
this.badInput ||
|
|
128
|
+
this.selectAtleastOneValue
|
|
119
129
|
);
|
|
120
130
|
}
|
|
121
131
|
}
|
|
@@ -200,6 +210,7 @@ export class FieldConstraintApi {
|
|
|
200
210
|
tooLong: this.inputComponent.messageWhenTooLong,
|
|
201
211
|
typeMismatch: this.inputComponent.messageWhenTypeMismatch,
|
|
202
212
|
valueMissing: this.inputComponent.messageWhenValueMissing,
|
|
213
|
+
selectAtleastOneValue: this.inputComponent.messageWhenValueMissing,
|
|
203
214
|
});
|
|
204
215
|
}
|
|
205
216
|
|
|
@@ -14,6 +14,7 @@ selections when filtering a list, such as from a multi-select picklist.
|
|
|
14
14
|
To specify the pills, set the `items` attribute to an array of values in your component's JavaScript.
|
|
15
15
|
|
|
16
16
|
By default, all pills in the container are displayed and wrap to additional lines if they can't fit on one line.
|
|
17
|
+
For information about changing the behavior, see **Managing Pill Layout in the Container**.
|
|
17
18
|
|
|
18
19
|
This example creates three pills: a text-only pill, a pill with an avatar, and
|
|
19
20
|
a pill with an icon.
|
|
@@ -70,7 +71,7 @@ To create a pill with an avatar, use the following attributes.
|
|
|
70
71
|
To create a pill with an icon, use the following attributes.
|
|
71
72
|
|
|
72
73
|
- `type`: The media type. Use `icon`.
|
|
73
|
-
- `iconName`: Required. The Lightning Design System name of the icon. Names are written in the format '
|
|
74
|
+
- `iconName`: Required. The Lightning Design System name of the icon. Names are written in the format 'utility:down' where 'utility' is the category, and 'down' is the specific icon to be displayed. Only utility icons can be used for the `iconName`.
|
|
74
75
|
- `alternativeText`: The alternative text used to describe the icon. Describe what happens when you click the button, for example 'Upload File', not what the icon looks like, 'Paperclip'.
|
|
75
76
|
|
|
76
77
|
`lightning-pill-container` provides two variants: `bare` and `standard` (default). They are visually the same. However, the `standard` variant renders pills in an unordered list element. For more information, see the **Accessibility** section.
|
|
@@ -135,9 +136,12 @@ set to false by default, which makes all pills display and wrap to multiple line
|
|
|
135
136
|
- `single-line`: Specifies that the pill container can display one line of pills. By default, if pills can't fit on one line, they are wrapped to additional lines to fit the container. Set `single-line` to true to limit pill display to one line. This attribute overrides `is-collapsible` and `is-expanded`.
|
|
136
137
|
|
|
137
138
|
If all pills aren't displayed, the component shows a text button indicating how many more pills there are.
|
|
139
|
+
For example, if there are five more pills that aren’t displayed, the text button shows `+5 more`. The text button fires the `focus` event when you click it.
|
|
138
140
|
|
|
139
141
|
To display a long list of pills as collapsed, set `is-collapsible` to true and optionally set `is-expanded` to false. Otherwise, pills are displayed expanded.
|
|
140
142
|
|
|
143
|
+
##### Expand and Collapse Pills Programmatically
|
|
144
|
+
|
|
141
145
|
Use `is-collapsible` and `is-expanded` to programmatically expand and collapse the pills.
|
|
142
146
|
|
|
143
147
|
This example sets `is-collapsible` and uses a button to change the value of `is-expanded`.
|
|
@@ -175,6 +179,46 @@ export default class PillContainerCanCollapse extends LightningElement {
|
|
|
175
179
|
];
|
|
176
180
|
}
|
|
177
181
|
```
|
|
182
|
+
##### Display All Pills With the `+n more` Button
|
|
183
|
+
|
|
184
|
+
If all pills aren't displayed, the component shows a text button labeled `+n more` to indicate more pills can be displayed. By default, `lightning-pill-container` doesn’t handle the `focus` event that’s fired when you click the button. You can handle the event to display more pills or write logic to do something else when the button is clicked.
|
|
185
|
+
|
|
186
|
+
This example sets the pills to be collapsible but not expanded and handles the focus event.
|
|
187
|
+
|
|
188
|
+
```html
|
|
189
|
+
<template>
|
|
190
|
+
<div style="width: 600px">
|
|
191
|
+
<lightning-pill-container
|
|
192
|
+
items={items}
|
|
193
|
+
is-collapsible={collapsible}
|
|
194
|
+
is-expanded={expanded}
|
|
195
|
+
onfocus={handlePillExpansion}
|
|
196
|
+
>
|
|
197
|
+
</lightning-pill-container>
|
|
198
|
+
</div>
|
|
199
|
+
</template>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The list of pills is initially collapsed. When there are too many pills to be displayed, the text button labeled `+n more` displays. The handler for the `focus` event enables all the pills to display.
|
|
203
|
+
|
|
204
|
+
```javascript
|
|
205
|
+
import { LightningElement } from 'lwc';
|
|
206
|
+
|
|
207
|
+
export default class PillContainerMoreButtonExpands extends LightningElement {
|
|
208
|
+
collapsible = true;
|
|
209
|
+
expanded = false;
|
|
210
|
+
|
|
211
|
+
handlePillExpansion(){
|
|
212
|
+
this.expanded = true;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
items = [
|
|
216
|
+
{
|
|
217
|
+
//define the pills
|
|
218
|
+
}
|
|
219
|
+
];
|
|
220
|
+
}
|
|
221
|
+
```
|
|
178
222
|
|
|
179
223
|
#### Component Styling
|
|
180
224
|
|
|
@@ -21,28 +21,33 @@ const i18n = {
|
|
|
21
21
|
showActions: labelShowActions,
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
+
/**
|
|
25
|
+
* A cell-level action.
|
|
26
|
+
*/
|
|
24
27
|
export default class PrimitiveCellActions extends LightningElement {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
@api rowKeyValue;
|
|
28
|
-
@api colKeyValue;
|
|
29
|
-
@api rowActions;
|
|
30
|
-
|
|
28
|
+
// Tracked objects
|
|
31
29
|
@track containerRect;
|
|
32
30
|
@track _actions = [];
|
|
33
31
|
|
|
32
|
+
// Private variables
|
|
33
|
+
static delegatesFocus = true;
|
|
34
34
|
_isLoadingActions;
|
|
35
35
|
_menuAlignment = DEFAULT_MENU_ALIGNMENT;
|
|
36
36
|
_internalTabIndex = false;
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
this._connected = true;
|
|
40
|
-
}
|
|
38
|
+
/************************** PUBLIC ATTRIBUTES ***************************/
|
|
41
39
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
@api rowKeyValue;
|
|
41
|
+
@api colKeyValue;
|
|
42
|
+
@api rowActions;
|
|
45
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Defines the current menu alignment
|
|
46
|
+
* See `VALID_MENU_ALIGNMENT` for valid menu alignment values
|
|
47
|
+
* See `DEFAULT_MENU_ALIGNMENT` for the default menu alignment
|
|
48
|
+
*
|
|
49
|
+
* @type {string}
|
|
50
|
+
*/
|
|
46
51
|
@api
|
|
47
52
|
get menuAlignment() {
|
|
48
53
|
return this._menuAlignment;
|
|
@@ -55,6 +60,11 @@ export default class PrimitiveCellActions extends LightningElement {
|
|
|
55
60
|
});
|
|
56
61
|
}
|
|
57
62
|
|
|
63
|
+
/************************** PUBLIC METHODS ***************************/
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Sets focus on a lightning-button-menu
|
|
67
|
+
*/
|
|
58
68
|
@api
|
|
59
69
|
focus() {
|
|
60
70
|
if (this._connected) {
|
|
@@ -62,6 +72,9 @@ export default class PrimitiveCellActions extends LightningElement {
|
|
|
62
72
|
}
|
|
63
73
|
}
|
|
64
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Clicks a lightning-button-menu
|
|
77
|
+
*/
|
|
65
78
|
@api
|
|
66
79
|
click() {
|
|
67
80
|
if (this._connected) {
|
|
@@ -73,18 +86,42 @@ export default class PrimitiveCellActions extends LightningElement {
|
|
|
73
86
|
}
|
|
74
87
|
}
|
|
75
88
|
|
|
89
|
+
/************************** PRIVATE GETTERS **************************/
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Returns the computed menu alignment value
|
|
93
|
+
*
|
|
94
|
+
* @return {string} Current computed menu alignment
|
|
95
|
+
*/
|
|
76
96
|
get computedMenuAlignment() {
|
|
77
97
|
return this.menuAlignment;
|
|
78
98
|
}
|
|
79
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Returns the button alternative text in the appropriate language
|
|
102
|
+
*
|
|
103
|
+
* @return {string} Language-specific button alternative text
|
|
104
|
+
*/
|
|
80
105
|
get buttonAlternateText() {
|
|
81
106
|
return `${i18n.showActions}`;
|
|
82
107
|
}
|
|
83
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Returns the spinner alternative text in the appropriate language
|
|
111
|
+
*
|
|
112
|
+
* @return {string} Language-specific spinner alternative text
|
|
113
|
+
*/
|
|
84
114
|
get spinnerAlternateText() {
|
|
85
115
|
return `${i18n.loadingActions}`;
|
|
86
116
|
}
|
|
87
117
|
|
|
118
|
+
/************************ EVENT DISPATCHERS **************************/
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Handles selecting an action
|
|
122
|
+
*
|
|
123
|
+
* @param {Event} event
|
|
124
|
+
*/
|
|
88
125
|
handleActionSelect(event) {
|
|
89
126
|
this.dispatchEvent(
|
|
90
127
|
new CustomEvent('privatecellactiontriggered', {
|
|
@@ -100,6 +137,9 @@ export default class PrimitiveCellActions extends LightningElement {
|
|
|
100
137
|
);
|
|
101
138
|
}
|
|
102
139
|
|
|
140
|
+
/**
|
|
141
|
+
* Handles the opening of an action menu
|
|
142
|
+
*/
|
|
103
143
|
handleMenuOpen() {
|
|
104
144
|
this.elementRect = this.template
|
|
105
145
|
.querySelector('lightning-button-menu')
|
|
@@ -135,6 +175,23 @@ export default class PrimitiveCellActions extends LightningElement {
|
|
|
135
175
|
}
|
|
136
176
|
}
|
|
137
177
|
|
|
178
|
+
/************************** LIFECYCLE HOOKS **************************/
|
|
179
|
+
|
|
180
|
+
connectedCallback() {
|
|
181
|
+
this._connected = true;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
disconnectedCallback() {
|
|
185
|
+
this._connected = false;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/************************* HELPER FUNCTIONS **************************/
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Resets loading state when all actions have been loaded
|
|
192
|
+
*
|
|
193
|
+
* @param {object} actions - Actions displayed in the menu
|
|
194
|
+
*/
|
|
138
195
|
finishLoadingActions(actions) {
|
|
139
196
|
this._isLoadingActions = false;
|
|
140
197
|
this._actions = actions;
|
|
@@ -215,18 +215,20 @@
|
|
|
215
215
|
|
|
216
216
|
<!-- row number -->
|
|
217
217
|
<template if:true={isRowNumber}>
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
218
|
+
<template if:true={_rowHasError}>
|
|
219
|
+
<lightning-primitive-datatable-tooltip data-navigation="enable"
|
|
220
|
+
data-action-triggers="enter,space"
|
|
221
|
+
class="slds-m-horizontal_xxx-small"
|
|
222
|
+
size="xx-small"
|
|
223
|
+
header={typeAttribute0.title}
|
|
224
|
+
content={typeAttribute0.messages}
|
|
225
|
+
variant='error'
|
|
226
|
+
internal-tab-index={internalTabIndex}
|
|
227
|
+
alternative-text={typeAttribute0.alternativeText}>
|
|
227
228
|
|
|
228
|
-
|
|
229
|
-
|
|
229
|
+
</lightning-primitive-datatable-tooltip>
|
|
230
|
+
</template>
|
|
231
|
+
<span class="slds-row-number slds-text-body_small slds-text-color_weak" style={computedRowNumberStyle}></span>
|
|
230
232
|
</template>
|
|
231
233
|
|
|
232
234
|
<!-- text -->
|
|
@@ -8,6 +8,9 @@ import labelEditHasError from '@salesforce/label/LightningDatatable.editHasError
|
|
|
8
8
|
import labelTrue from '@salesforce/label/LightningDatatable.true';
|
|
9
9
|
import labelFalse from '@salesforce/label/LightningDatatable.false';
|
|
10
10
|
|
|
11
|
+
// Same constant (TOOLTIP_ALLOWANCE) as used in lightning/datatable/rowNumber.js
|
|
12
|
+
// If making change to this, make sure to modify in rowNumber.js as well
|
|
13
|
+
const TOOLTIP_ALLOWANCE = 20;
|
|
11
14
|
const i18n = {
|
|
12
15
|
edit: labelEdit,
|
|
13
16
|
editHasError: labelEditHasError,
|
|
@@ -58,6 +61,7 @@ export default class PrivateCellFactory extends PrimitiveDatatableCell {
|
|
|
58
61
|
@api wrapTextMaxLines;
|
|
59
62
|
|
|
60
63
|
_wrapText = false;
|
|
64
|
+
_rowHasError = false;
|
|
61
65
|
|
|
62
66
|
@api
|
|
63
67
|
get wrapText() {
|
|
@@ -153,7 +157,13 @@ export default class PrivateCellFactory extends PrimitiveDatatableCell {
|
|
|
153
157
|
}
|
|
154
158
|
|
|
155
159
|
get isRowNumber() {
|
|
156
|
-
|
|
160
|
+
if (this.isType('rowNumber')) {
|
|
161
|
+
const error = this.typeAttribute0;
|
|
162
|
+
this._rowHasError = error && error.title && error.messages;
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return false;
|
|
157
167
|
}
|
|
158
168
|
|
|
159
169
|
get isAction() {
|
|
@@ -285,13 +295,8 @@ export default class PrivateCellFactory extends PrimitiveDatatableCell {
|
|
|
285
295
|
.toString();
|
|
286
296
|
}
|
|
287
297
|
|
|
288
|
-
get
|
|
289
|
-
|
|
290
|
-
const error = this.typeAttribute0;
|
|
291
|
-
if (error) {
|
|
292
|
-
classes.add({ 'slds-hidden': !error.title && !error.messages });
|
|
293
|
-
}
|
|
294
|
-
return classes.toString();
|
|
298
|
+
get computedRowNumberStyle() {
|
|
299
|
+
return this._rowHasError ? '' : `padding-left: ${TOOLTIP_ALLOWANCE}px;`;
|
|
295
300
|
}
|
|
296
301
|
|
|
297
302
|
get editIconAssistiveText() {
|