lightning-base-components 1.20.2-alpha → 1.21.1-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.
Files changed (55) hide show
  1. package/metadata/raptor.json +1 -0
  2. package/package.json +10 -1
  3. package/scopedImports/@salesforce-label-LightningCombobox.currentSelection.js +1 -1
  4. package/scopedImports/@salesforce-label-LightningDualListbox.moveToAssistiveText.js +1 -0
  5. package/scopedImports/@salesforce-label-LightningDualListbox.verticallyMovedOptions.js +1 -0
  6. package/src/lightning/ariaObserver/ariaObserver.js-meta.xml +4 -0
  7. package/src/lightning/baseCombobox/baseCombobox.js +3 -2
  8. package/src/lightning/datatable/__examples__/customDatatableWrapper/customDatatableWrapper.html +11 -0
  9. package/src/lightning/datatable/__examples__/customDatatableWrapper/customDatatableWrapper.js +158 -0
  10. package/src/lightning/datatable/__examples__/customDatatypeDeleteRowBtn/customDatatypeDeleteRowBtn.html +6 -0
  11. package/src/lightning/datatable/__examples__/customDatatypeDeleteRowBtn/customDatatypeDeleteRowBtn.js +28 -0
  12. package/src/lightning/datatable/__examples__/customDatatypeLink/customDatatypeLink.html +9 -0
  13. package/src/lightning/datatable/__examples__/customDatatypeLink/customDatatypeLink.js +15 -0
  14. package/src/lightning/datatable/__examples__/customDatatypeNumber/customDatatypeNumber.html +10 -0
  15. package/src/lightning/datatable/__examples__/customDatatypeNumber/customDatatypeNumber.js +21 -0
  16. package/src/lightning/datatable/__examples__/customDatatypeRowOrderingBtn/customDatatypeRowOrderingBtn.html +10 -0
  17. package/src/lightning/datatable/__examples__/customDatatypeRowOrderingBtn/customDatatypeRowOrderingBtn.js +40 -0
  18. package/src/lightning/datatable/__examples__/customDatatypeTable/customDatatypeTable.js +38 -0
  19. package/src/lightning/datatable/__examples__/customDatatypeTable/customLink.html +9 -0
  20. package/src/lightning/datatable/__examples__/customDatatypeTable/customName.html +4 -0
  21. package/src/lightning/datatable/__examples__/customDatatypeTable/customNumber.html +3 -0
  22. package/src/lightning/datatable/__examples__/customDatatypeTable/customNumberEdit.html +10 -0
  23. package/src/lightning/datatable/__examples__/customDatatypeTable/deleteRow.html +8 -0
  24. package/src/lightning/datatable/__examples__/customDatatypeTable/iconPill.html +17 -0
  25. package/src/lightning/datatable/__examples__/customDatatypeTable/orderingButtons.html +10 -0
  26. package/src/lightning/datatable/__examples__/withAllColumnTypes/generateData.js +23 -0
  27. package/src/lightning/datatable/__examples__/withAllColumnTypes/withAllColumnTypes.html +11 -0
  28. package/src/lightning/datatable/__examples__/withAllColumnTypes/withAllColumnTypes.js +71 -0
  29. package/src/lightning/datatable/__examples__/withColResizing/generateData.js +14 -0
  30. package/src/lightning/datatable/__examples__/withColResizing/withColResizing.html +47 -0
  31. package/src/lightning/datatable/__examples__/withColResizing/withColResizing.js +42 -0
  32. package/src/lightning/datatable/__examples__/withErrors/generateData.js +14 -0
  33. package/src/lightning/datatable/__examples__/withErrors/withErrors.html +13 -0
  34. package/src/lightning/datatable/__examples__/withErrors/withErrors.js +44 -0
  35. package/src/lightning/datatable/__examples__/withInfiniteLoading/withInfiniteLoading.html +2 -1
  36. package/src/lightning/datatable/__examples__/withInfiniteLoading/withInfiniteLoading.js +1 -0
  37. package/src/lightning/datatable/__examples__/withInlineEdit/withInlineEdit.html +1 -0
  38. package/src/lightning/datatable/__examples__/withInlineEdit/withInlineEdit.js +1 -0
  39. package/src/lightning/datatable/__examples__/withRowSelection/generateData.js +14 -0
  40. package/src/lightning/datatable/__examples__/withRowSelection/withRowSelection.html +21 -0
  41. package/src/lightning/datatable/__examples__/withRowSelection/withRowSelection.js +34 -0
  42. package/src/lightning/datatable/__examples__/withTextWrapping/generateData.js +16 -0
  43. package/src/lightning/datatable/__examples__/withTextWrapping/withTextWrapping.html +14 -0
  44. package/src/lightning/datatable/__examples__/withTextWrapping/withTextWrapping.js +31 -0
  45. package/src/lightning/datatable/__examples__/withVirtualization/generateData.js +14 -0
  46. package/src/lightning/datatable/__examples__/withVirtualization/withVirtualization.html +12 -0
  47. package/src/lightning/datatable/__examples__/withVirtualization/withVirtualization.js +27 -0
  48. package/src/lightning/datatable/__examples__/withoutTableHeader/generateData.js +14 -0
  49. package/src/lightning/datatable/__examples__/withoutTableHeader/withoutTableHeader.html +10 -0
  50. package/src/lightning/datatable/__examples__/withoutTableHeader/withoutTableHeader.js +22 -0
  51. package/src/lightning/dualListbox/dualListbox.html +2 -2
  52. package/src/lightning/dualListbox/dualListbox.js +56 -2
  53. package/src/lightning/menuDivider/menuDivider.js +1 -0
  54. package/src/lightning/pill/__docs__/pill.md +6 -2
  55. package/src/lightning/pillContainer/__docs__/pillContainer.md +16 -8
@@ -0,0 +1,47 @@
1
+ <template>
2
+ <p>Datatable with resize-column disabled</p>
3
+ <lightning-datatable
4
+ key-field="id"
5
+ data={data}
6
+ columns={columns}
7
+ resize-column-disabled>
8
+ </lightning-datatable>
9
+
10
+ <p>Datatable with min and max column widths. Resize step: {resizeStep} </p>
11
+ <lightning-button
12
+ label="Increase resize step"
13
+ class="increaseResizeStep"
14
+ onclick={increaseResizeStep}>
15
+ </lightning-button>
16
+ <lightning-button
17
+ label="Decrease resize step"
18
+ class="decreaseResizeStep"
19
+ onclick={decreaseResizeStep}>
20
+ </lightning-button>
21
+ <lightning-datatable
22
+ key-field="id"
23
+ data={data}
24
+ columns={columns}
25
+ min-column-width="100"
26
+ max-column-width="300"
27
+ resize-step={resizeStep}>
28
+ </lightning-datatable>
29
+
30
+ <p>Datatable with column-widths-mode='{mode}'</p>
31
+ <lightning-button
32
+ label="Change Widths Mode"
33
+ class="changeWidthsMode"
34
+ onclick={changeWidthsMode}>
35
+ </lightning-button>
36
+ <lightning-button
37
+ label="Add Column"
38
+ column="addColumn"
39
+ onclick={addColumn}>
40
+ </lightning-button>
41
+ <lightning-datatable
42
+ key-field="id"
43
+ data={data}
44
+ columns={columns}
45
+ column-widths-mode={mode}>
46
+ </lightning-datatable>
47
+ </template>
@@ -0,0 +1,42 @@
1
+ import { LightningElement } from 'lwc';
2
+ import generateData from './generateData';
3
+
4
+ // Add <datatable-with-col-resizing></datatable-with-col-resizing> to the lwr-playground to see table
5
+
6
+ const columns = [
7
+ { label: 'Label', fieldName: 'name' },
8
+ { label: 'Website', fieldName: 'website', type: 'url' },
9
+ { label: 'Phone', fieldName: 'phone', type: 'phone' },
10
+ { label: 'Balance', fieldName: 'amount', type: 'currency' },
11
+ { label: 'CloseAt', fieldName: 'closeAt', type: 'date' },
12
+ ];
13
+
14
+ export default class DatatableWithResize extends LightningElement {
15
+ data = [];
16
+ columns = columns;
17
+ mode = 'fixed';
18
+ resizeStep = 10;
19
+
20
+ connectedCallback() {
21
+ this.data = generateData({ amountOfRecords: 25 });
22
+ }
23
+
24
+ changeWidthsMode() {
25
+ this.mode = this.mode === 'fixed' ? 'auto' : 'fixed';
26
+ }
27
+
28
+ increaseResizeStep() {
29
+ this.resizeStep += 10;
30
+ }
31
+
32
+ decreaseResizeStep() {
33
+ this.resizeStep =
34
+ this.resizeStep > 10 ? (this.resizeStep -= 10) : this.resizeStep;
35
+ }
36
+
37
+ addColumn() {
38
+ const cols = Array.from(this.columns);
39
+ cols.push({ label: 'ID', fieldName: 'id' });
40
+ this.columns = cols;
41
+ }
42
+ }
@@ -0,0 +1,14 @@
1
+ export default function generateData({ amountOfRecords }) {
2
+ return [...Array(amountOfRecords)].map((_, index) => {
3
+ return {
4
+ id: index + 1,
5
+ name: `Name (${index})`,
6
+ website: 'www.salesforce.com',
7
+ amount: Math.floor(Math.random() * 100),
8
+ phone: `${Math.floor(Math.random() * 9000000000) + 1000000000}`,
9
+ closeAt: new Date(
10
+ Date.now() + 86400000 * Math.ceil(Math.random() * 20)
11
+ ),
12
+ };
13
+ });
14
+ }
@@ -0,0 +1,13 @@
1
+ <template>
2
+ <lightning-button
3
+ label="Trigger error"
4
+ class="triggerError"
5
+ onclick={triggerError}>
6
+ </lightning-button>
7
+ <lightning-datatable
8
+ key-field="id"
9
+ data={data}
10
+ columns={columns}
11
+ errors={errors}>
12
+ </lightning-datatable>
13
+ </template>
@@ -0,0 +1,44 @@
1
+ import { LightningElement } from 'lwc';
2
+ import generateData from './generateData';
3
+
4
+ // Add <datatable-with-errors></datatable-with-errors> to the lwr-playground to see the table
5
+
6
+ const columns = [
7
+ { label: 'Label', fieldName: 'name', editable: true },
8
+ { label: 'Website', fieldName: 'website', type: 'url', editable: true },
9
+ { label: 'Phone', fieldName: 'phone', type: 'phone', editable: true },
10
+ { label: 'Balance', fieldName: 'amount', type: 'currency' },
11
+ { label: 'CloseAt', fieldName: 'closeAt', type: 'date', editable: true },
12
+ ];
13
+
14
+ export default class DatatableWithError extends LightningElement {
15
+ data = [];
16
+ columns = columns;
17
+ errors = {};
18
+
19
+ connectedCallback() {
20
+ this.data = generateData({ amountOfRecords: 100 });
21
+ }
22
+
23
+ triggerError() {
24
+ this.errors = {
25
+ rows: {
26
+ 1: {
27
+ title: 'We found 2 errors.',
28
+ messages: [
29
+ 'Enter a valid name',
30
+ 'Verify the phone number and try again.',
31
+ ],
32
+ fieldNames: ['name', 'phone'],
33
+ },
34
+ },
35
+ table: {
36
+ title: 'Your entry cannot be saved. Fix the errors and try again.',
37
+ messages: [
38
+ 'Row 1 name must be valid text',
39
+ 'Row 1 phone number is invalid',
40
+ ],
41
+ },
42
+ };
43
+ }
44
+ }
@@ -6,7 +6,8 @@
6
6
  data={data}
7
7
  columns={columns}
8
8
  enable-infinite-loading
9
- onloadmore={handleLoadMore}>
9
+ onloadmore={handleLoadMore}
10
+ load-more-offset={loadMoreOffset}>
10
11
  </lightning-datatable>
11
12
  </div>
12
13
  <p>{loadMoreStatus}</p>
@@ -14,6 +14,7 @@ export default class DatatableWithInfiniteLoading extends LightningElement {
14
14
  columns = columns;
15
15
  loadMoreStatus;
16
16
  totalNumberOfRows = 250;
17
+ loadMoreOffset = 20;
17
18
 
18
19
  // eslint-disable-next-line @lwc/lwc/no-async-await
19
20
  async connectedCallback() {
@@ -6,6 +6,7 @@
6
6
  show-row-number-column
7
7
  row-number-offset={rowOffset}
8
8
  suppress-bottom-bar
9
+ draft-values={draftValues}
9
10
  columns={columns}>
10
11
  </lightning-datatable>
11
12
  </div>
@@ -13,6 +13,7 @@ export default class DatatableWithInlineEdit extends LightningElement {
13
13
  data = [];
14
14
  columns = columns;
15
15
  rowOffset = 0;
16
+ draftValues = [];
16
17
 
17
18
  connectedCallback() {
18
19
  this.data = generateData({ amountOfRecords: 100 });
@@ -0,0 +1,14 @@
1
+ export default function generateData({ amountOfRecords }) {
2
+ return [...Array(amountOfRecords)].map((_, index) => {
3
+ return {
4
+ id: index + 1,
5
+ name: `Name (${index})`,
6
+ website: 'www.salesforce.com',
7
+ amount: Math.floor(Math.random() * 100),
8
+ phone: `${Math.floor(Math.random() * 9000000000) + 1000000000}`,
9
+ closeAt: new Date(
10
+ Date.now() + 86400000 * Math.ceil(Math.random() * 20)
11
+ ),
12
+ };
13
+ });
14
+ }
@@ -0,0 +1,21 @@
1
+ <template>
2
+ <p>Max row selection value: {maxRowSelection}</p>
3
+ <lightning-button
4
+ label="Increase max row selection"
5
+ class="increaseMaxRowSelection"
6
+ onclick={increaseMaxRowSelection}>
7
+ </lightning-button>
8
+ <lightning-button
9
+ label="Decrease max row selection"
10
+ class="decreaseMaxRowSelection"
11
+ onclick={decreaseMaxRowSelection}>
12
+ </lightning-button>
13
+ <lightning-datatable
14
+ key-field="id"
15
+ columns={columns}
16
+ data={data}
17
+ selected-rows={selectedRows}
18
+ row-number-offset="0"
19
+ max-row-selection={maxRowSelection}>
20
+ </lightning-datatable>
21
+ </template>
@@ -0,0 +1,34 @@
1
+ import { LightningElement } from 'lwc';
2
+ import generateData from './generateData';
3
+
4
+ // Add <datatable-with-row-selection></datatable-with-row-selection> to the lwr-playground to see the table
5
+
6
+ const columns = [
7
+ { label: 'Label', fieldName: 'name' },
8
+ { label: 'Website', fieldName: 'website', type: 'url' },
9
+ { label: 'Phone', fieldName: 'phone', type: 'phone' },
10
+ { label: 'Balance', fieldName: 'amount', type: 'currency' },
11
+ { label: 'CloseAt', fieldName: 'closeAt', type: 'date' },
12
+ ];
13
+
14
+ export default class DatatableWithRowSelection extends LightningElement {
15
+ data = [];
16
+ columns = columns;
17
+ selectedRows = ['1', '2', '4'];
18
+ maxRowSelection = 4;
19
+
20
+ connectedCallback() {
21
+ this.data = generateData({ amountOfRecords: 100 });
22
+ }
23
+
24
+ increaseMaxRowSelection() {
25
+ this.maxRowSelection += 1;
26
+ }
27
+
28
+ decreaseMaxRowSelection() {
29
+ this.maxRowSelection =
30
+ this.maxRowSelection > 0
31
+ ? (this.maxRowSelection -= 1)
32
+ : this.maxRowSelection;
33
+ }
34
+ }
@@ -0,0 +1,16 @@
1
+ export default function generateData({ amountOfRecords }) {
2
+ return [...Array(amountOfRecords)].map((_, index) => {
3
+ return {
4
+ id: index + 1,
5
+ name: `Name (${index})`,
6
+ description:
7
+ 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.',
8
+ website: 'www.salesforce.com',
9
+ amount: Math.floor(Math.random() * 100),
10
+ phone: `${Math.floor(Math.random() * 9000000000) + 1000000000}`,
11
+ closeAt: new Date(
12
+ Date.now() + 86400000 * Math.ceil(Math.random() * 20)
13
+ ),
14
+ };
15
+ });
16
+ }
@@ -0,0 +1,14 @@
1
+ <template>
2
+ <lightning-button
3
+ label="Change text wrapping max lines"
4
+ class="changeTextWrappingMaxLines"
5
+ onclick={changeTextWrappingMaxLines}>
6
+ </lightning-button>
7
+ <lightning-datatable
8
+ key-field="id"
9
+ columns={columns}
10
+ data={data}
11
+ hide-checkbox-column
12
+ wrap-text-max-lines={wrapTextMaxLines}>
13
+ </lightning-datatable>
14
+ </template>
@@ -0,0 +1,31 @@
1
+ import { LightningElement } from 'lwc';
2
+ import generateData from './generateData';
3
+
4
+ // Add <datatable-with-text-wrapping></datatable-with-text-wrapping> to the lwr-playground to see the table
5
+
6
+ const columns = [
7
+ { label: 'Label', fieldName: 'name' },
8
+ {
9
+ label: 'Description',
10
+ fieldName: 'description',
11
+ wrapText: true,
12
+ },
13
+ { label: 'Website', fieldName: 'website', type: 'url' },
14
+ { label: 'Phone', fieldName: 'phone', type: 'phone' },
15
+ { label: 'Balance', fieldName: 'amount', type: 'currency' },
16
+ { label: 'CloseAt', fieldName: 'closeAt', type: 'date' },
17
+ ];
18
+
19
+ export default class DatatablewithTextWrapping extends LightningElement {
20
+ data = [];
21
+ columns = columns;
22
+ wrapTextMaxLines;
23
+
24
+ connectedCallback() {
25
+ this.data = generateData({ amountOfRecords: 25 });
26
+ }
27
+
28
+ changeTextWrappingMaxLines() {
29
+ this.wrapTextMaxLines = 3;
30
+ }
31
+ }
@@ -0,0 +1,14 @@
1
+ export default function generateData({ amountOfRecords }) {
2
+ return [...Array(amountOfRecords)].map((_, index) => {
3
+ return {
4
+ id: index + 1,
5
+ name: `Name (${index})`,
6
+ website: 'www.salesforce.com',
7
+ amount: Math.floor(Math.random() * 100),
8
+ phone: `${Math.floor(Math.random() * 9000000000) + 1000000000}`,
9
+ closeAt: new Date(
10
+ Date.now() + 86400000 * Math.ceil(Math.random() * 20)
11
+ ),
12
+ };
13
+ });
14
+ }
@@ -0,0 +1,12 @@
1
+ <template>
2
+ <div style="height:100vh;">
3
+ <lightning-datatable
4
+ data-render-mode="role-based"
5
+ key-field="id"
6
+ data={data}
7
+ columns={columns}
8
+ render-mode="role-based"
9
+ render-config={renderConfig}>
10
+ </lightning-datatable>
11
+ </div>
12
+ </template>
@@ -0,0 +1,27 @@
1
+ import { LightningElement } from 'lwc';
2
+ import generateData from './generateData';
3
+
4
+ // Add <datatable-with-virtualization></datatable-with-virtualization> to the lwr-playground to see the table
5
+
6
+ const columns = [
7
+ { label: 'Label', fieldName: 'name' },
8
+ { label: 'Website', fieldName: 'website', type: 'url' },
9
+ { label: 'Phone', fieldName: 'phone', type: 'phone' },
10
+ { label: 'Balance', fieldName: 'amount', type: 'currency' },
11
+ { label: 'CloseAt', fieldName: 'closeAt', type: 'date' },
12
+ ];
13
+
14
+ export default class DatatableWithVirtualization extends LightningElement {
15
+ data = [];
16
+ columns = columns;
17
+ renderConfig = {
18
+ virtualize: 'vertical',
19
+ bufferSize: 10,
20
+ fixedHeight: true,
21
+ };
22
+
23
+ connectedCallback() {
24
+ const data = generateData({ amountOfRecords: 100 });
25
+ this.data = data;
26
+ }
27
+ }
@@ -0,0 +1,14 @@
1
+ export default function generateData({ amountOfRecords }) {
2
+ return [...Array(amountOfRecords)].map((_, index) => {
3
+ return {
4
+ id: index + 1,
5
+ name: `Name (${index})`,
6
+ website: 'www.salesforce.com',
7
+ amount: Math.floor(Math.random() * 100),
8
+ phone: `${Math.floor(Math.random() * 9000000000) + 1000000000}`,
9
+ closeAt: new Date(
10
+ Date.now() + 86400000 * Math.ceil(Math.random() * 20)
11
+ ),
12
+ };
13
+ });
14
+ }
@@ -0,0 +1,10 @@
1
+ <template>
2
+ <div style="height: 300px;">
3
+ <lightning-datatable
4
+ key-field="id"
5
+ data={data}
6
+ columns={columns}
7
+ hide-table-header>
8
+ </lightning-datatable>
9
+ </div>
10
+ </template>
@@ -0,0 +1,22 @@
1
+ import { LightningElement } from 'lwc';
2
+ import generateData from './generateData';
3
+
4
+ // Add <datatable-without-table-header></datatable-without-table-header> to the lwr-playground to see the table
5
+
6
+ const columns = [
7
+ { label: 'Label', fieldName: 'name' },
8
+ { label: 'Website', fieldName: 'website', type: 'url' },
9
+ { label: 'Phone', fieldName: 'phone', type: 'phone' },
10
+ { label: 'Balance', fieldName: 'amount', type: 'currency' },
11
+ { label: 'CloseAt', fieldName: 'closeAt', type: 'date' },
12
+ ];
13
+
14
+ export default class DatatableWithoutTableHeader extends LightningElement {
15
+ data = [];
16
+ columns = columns;
17
+
18
+ connectedCallback() {
19
+ const data = generateData({ amountOfRecords: 100 });
20
+ this.data = data;
21
+ }
22
+ }
@@ -34,10 +34,10 @@
34
34
  </div>
35
35
  <div class="slds-dueling-list__column">
36
36
  <lightning-button-icon icon-name="utility:right" variant="container" onclick={handleRightButtonClick} disabled={moveButtonsDisabled}
37
- title={addButtonLabel} alternative-text={addButtonLabel}>
37
+ title={addButtonLabel} alternative-text={addButtonLabel} tooltip={addButtonDescription}>
38
38
  </lightning-button-icon>
39
39
  <lightning-button-icon icon-name="utility:left" variant="container" onclick={handleLeftButtonClick} disabled={moveButtonsDisabled}
40
- title={removeButtonLabel} alternative-text={removeButtonLabel}>
40
+ title={removeButtonLabel} alternative-text={removeButtonLabel} tooltip={removeButtonDescription}>
41
41
  </lightning-button-icon>
42
42
  </div>
43
43
  <div class="slds-dueling-list__column slds-dueling-list__column_responsive">
@@ -13,9 +13,11 @@ import labelRequiredError from '@salesforce/label/LightningDualListbox.requiredE
13
13
  import labelRequiredOptionError from '@salesforce/label/LightningDualListbox.requiredOptionError';
14
14
  import labelUpButtonAssistiveText from '@salesforce/label/LightningDualListbox.upButtonAssistiveText';
15
15
  import labelMoveSelectionToAssistiveText from '@salesforce/label/LightningDualListbox.moveSelectionToAssistiveText';
16
+ import labelMoveToAssistiveText from '@salesforce/label/LightningDualListbox.moveToAssistiveText';
16
17
  import labelLoadingText from '@salesforce/label/LightningCombobox.loadingText';
17
18
  import labelMovedOptionsSingular from '@salesforce/label/LightningDualListbox.movedOptionsSingular';
18
19
  import labelMovedOptionsPlural from '@salesforce/label/LightningDualListbox.movedOptionsPlural';
20
+ import labelVerticallyMovedOptionsText from '@salesforce/label/LightningDualListbox.verticallyMovedOptions';
19
21
  import labelHelpTextAlternativeText from '@salesforce/label/LightningInput.helptextAlternativeText';
20
22
  import { LightningElement, api, track } from 'lwc';
21
23
  import { handleKeyDownOnOption } from './keyboard';
@@ -50,10 +52,12 @@ const i18n = {
50
52
  requiredOptionError: labelRequiredOptionError,
51
53
  upButtonAssistiveText: labelUpButtonAssistiveText,
52
54
  moveSelectionToAssistiveText: labelMoveSelectionToAssistiveText,
55
+ moveToAssistiveText: labelMoveToAssistiveText,
53
56
  loadingText: labelLoadingText,
54
57
  movedOptionsSingular: labelMovedOptionsSingular,
55
58
  movedOptionsPlural: labelMovedOptionsPlural,
56
59
  helpTextAlternativeText: labelHelpTextAlternativeText,
60
+ verticallyMovedOptionsText: labelVerticallyMovedOptionsText,
57
61
  };
58
62
 
59
63
  /**
@@ -584,12 +588,25 @@ export default class LightningDualListbox extends LightningElement {
584
588
  * @type {string}
585
589
  * @default Move selection to {selectedLabel}
586
590
  */
591
+ get addButtonDescription() {
592
+ return this.getRightButtonAssistiveText();
593
+ }
594
+
595
+ getRightButtonAssistiveLabel() {
596
+ return formatLabel(i18n.moveToAssistiveText, this.selectedLabel);
597
+ }
598
+
599
+ /**
600
+ * Label for add button.
601
+ * @type {string}
602
+ * @default Move to {selectedLabel}
603
+ */
587
604
  @api
588
605
  get addButtonLabel() {
589
606
  if (this._addButtonLabel) {
590
607
  return this._addButtonLabel;
591
608
  }
592
- return this.getRightButtonAssistiveText();
609
+ return this.getRightButtonAssistiveLabel();
593
610
  }
594
611
 
595
612
  set addButtonLabel(value) {
@@ -600,6 +617,19 @@ export default class LightningDualListbox extends LightningElement {
600
617
  return formatLabel(i18n.moveSelectionToAssistiveText, this.sourceLabel);
601
618
  }
602
619
 
620
+ /**
621
+ * Label for remove button.
622
+ * @type {string}
623
+ * @default "Move Selection to {sourceLabel}"
624
+ */
625
+ get removeButtonDescription() {
626
+ return this.getLeftButtonAssistiveText();
627
+ }
628
+
629
+ getLeftButtonAssistiveLabel() {
630
+ return formatLabel(i18n.moveToAssistiveText, this.sourceLabel);
631
+ }
632
+
603
633
  /**
604
634
  * Label for remove button.
605
635
  * @type {string}
@@ -610,7 +640,7 @@ export default class LightningDualListbox extends LightningElement {
610
640
  if (this._removeButtonLabel) {
611
641
  return this._removeButtonLabel;
612
642
  }
613
- return this.getLeftButtonAssistiveText();
643
+ return this.getLeftButtonAssistiveLabel();
614
644
  }
615
645
 
616
646
  set removeButtonLabel(value) {
@@ -817,6 +847,7 @@ export default class LightningDualListbox extends LightningElement {
817
847
  this.updateFocusableOption(this.selectedList, toMove[0]);
818
848
  this.optionToFocus = null;
819
849
  this.dispatchChangeEvent(values);
850
+ this.selectedUpDownMovedOptions();
820
851
  }
821
852
 
822
853
  selectAllFromLastSelectedToOption(option, all) {
@@ -1098,4 +1129,27 @@ export default class LightningDualListbox extends LightningElement {
1098
1129
  get helptextAlternativeText() {
1099
1130
  return formatLabel(i18n.helpTextAlternativeText, this.label);
1100
1131
  }
1132
+
1133
+ selectedUpDownMovedOptions() {
1134
+ let strMessage = [];
1135
+ for (let i = 0; i < this.computedSelectedList.length; i++) {
1136
+ const highlightedOption = this.highlightedOptions.indexOf(
1137
+ this.computedSelectedList[i].value
1138
+ );
1139
+ if (highlightedOption !== -1) {
1140
+ strMessage.push(
1141
+ formatLabel(
1142
+ i18n.verticallyMovedOptionsText,
1143
+ this.computedSelectedList[i].label,
1144
+ i + 1
1145
+ )
1146
+ );
1147
+ }
1148
+ }
1149
+ if (strMessage.length === 0) {
1150
+ this._messageToDisplay = '';
1151
+ } else {
1152
+ this._messageToDisplay = strMessage.join(', ');
1153
+ }
1154
+ }
1101
1155
  }
@@ -10,6 +10,7 @@ export default class LightningMenuDivider extends LightningElement {
10
10
 
11
11
  connectedCallback() {
12
12
  this.setAttribute('role', 'separator');
13
+ this.setAttribute('aria-hidden', 'true');
13
14
  }
14
15
 
15
16
  /**
@@ -80,7 +80,9 @@ Clicking the remove button on the pill fires the `remove` event and then the `cl
80
80
 
81
81
  When an `href` value is present, clicking the text label navigates to a link, but clicking the icon or avatar doesn’t. To prevent your browser from navigating to a link when you click a pill's label, call `event.preventDefault()` in the `onclick` handler.
82
82
 
83
- To disable a pill's link, set `variant="plain"`, which removes the anchor element.
83
+ When an `href` value is present, the default variant is `link`. If no `href` is present, the default variant is `plain`.
84
+
85
+ To disable a pill's link, set `variant="plain"`, which removes the anchor element. The `plain` variant renders the pill without a link and ignores the `href` attribute.
84
86
 
85
87
  This example hides a pill when the remove button is clicked.
86
88
 
@@ -192,7 +194,9 @@ When using `lightning-avatar`, use the `alternative-text` attribute to describe
192
194
 
193
195
  When using `lightning-icon`, use the `alternative-text` attribute to describe the icon. For example, specify "Account" instead of "Pill icon". This description is used as assistive text on the pill.
194
196
 
195
- Press the Tab key to focus on a pill. To remove a pill, press the Delete or Backspace key on the pill when it receives focus. Alternatively, press the Enter key when you tab to the remove button. You can define your own behavior to remove the pill from view, such as using the `onremove` handler shown in **Interacting with Pills**. Press the Enter key to navigate to a link on a pill.
197
+ Press the Tab key to move focus to a pill with a link, and tab again to move focus to the remove button. To remove a pill, press the Enter key or space bar when the focus is on the remove button. You can define your own behavior to remove the pill from view, such as using the `onremove` handler shown in **Interacting with Pills**. To navigate to the target of a link on a pill, press the Enter key when the focus is on the pill.
198
+
199
+ If a pill doesn't have a link, the only focusable item is the remove button.
196
200
 
197
201
  #### Custom Events
198
202