lightning-base-components 1.20.1-alpha → 1.21.0-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 (50) hide show
  1. package/metadata/raptor.json +1 -0
  2. package/package.json +2 -1
  3. package/src/lightning/ariaObserver/ariaObserver.js-meta.xml +4 -0
  4. package/src/lightning/datatable/__examples__/customDatatableWrapper/customDatatableWrapper.html +11 -0
  5. package/src/lightning/datatable/__examples__/customDatatableWrapper/customDatatableWrapper.js +158 -0
  6. package/src/lightning/datatable/__examples__/customDatatypeDeleteRowBtn/customDatatypeDeleteRowBtn.html +6 -0
  7. package/src/lightning/datatable/__examples__/customDatatypeDeleteRowBtn/customDatatypeDeleteRowBtn.js +28 -0
  8. package/src/lightning/datatable/__examples__/customDatatypeLink/customDatatypeLink.html +9 -0
  9. package/src/lightning/datatable/__examples__/customDatatypeLink/customDatatypeLink.js +15 -0
  10. package/src/lightning/datatable/__examples__/customDatatypeNumber/customDatatypeNumber.html +10 -0
  11. package/src/lightning/datatable/__examples__/customDatatypeNumber/customDatatypeNumber.js +21 -0
  12. package/src/lightning/datatable/__examples__/customDatatypeRowOrderingBtn/customDatatypeRowOrderingBtn.html +10 -0
  13. package/src/lightning/datatable/__examples__/customDatatypeRowOrderingBtn/customDatatypeRowOrderingBtn.js +40 -0
  14. package/src/lightning/datatable/__examples__/customDatatypeTable/customDatatypeTable.js +38 -0
  15. package/src/lightning/datatable/__examples__/customDatatypeTable/customLink.html +9 -0
  16. package/src/lightning/datatable/__examples__/customDatatypeTable/customName.html +4 -0
  17. package/src/lightning/datatable/__examples__/customDatatypeTable/customNumber.html +3 -0
  18. package/src/lightning/datatable/__examples__/customDatatypeTable/customNumberEdit.html +10 -0
  19. package/src/lightning/datatable/__examples__/customDatatypeTable/deleteRow.html +8 -0
  20. package/src/lightning/datatable/__examples__/customDatatypeTable/iconPill.html +17 -0
  21. package/src/lightning/datatable/__examples__/customDatatypeTable/orderingButtons.html +10 -0
  22. package/src/lightning/datatable/__examples__/withAllColumnTypes/generateData.js +23 -0
  23. package/src/lightning/datatable/__examples__/withAllColumnTypes/withAllColumnTypes.html +11 -0
  24. package/src/lightning/datatable/__examples__/withAllColumnTypes/withAllColumnTypes.js +71 -0
  25. package/src/lightning/datatable/__examples__/withColResizing/generateData.js +14 -0
  26. package/src/lightning/datatable/__examples__/withColResizing/withColResizing.html +47 -0
  27. package/src/lightning/datatable/__examples__/withColResizing/withColResizing.js +42 -0
  28. package/src/lightning/datatable/__examples__/withErrors/generateData.js +14 -0
  29. package/src/lightning/datatable/__examples__/withErrors/withErrors.html +13 -0
  30. package/src/lightning/datatable/__examples__/withErrors/withErrors.js +44 -0
  31. package/src/lightning/datatable/__examples__/withInfiniteLoading/withInfiniteLoading.html +2 -1
  32. package/src/lightning/datatable/__examples__/withInfiniteLoading/withInfiniteLoading.js +1 -0
  33. package/src/lightning/datatable/__examples__/withInlineEdit/withInlineEdit.html +1 -0
  34. package/src/lightning/datatable/__examples__/withInlineEdit/withInlineEdit.js +1 -0
  35. package/src/lightning/datatable/__examples__/withRowSelection/generateData.js +14 -0
  36. package/src/lightning/datatable/__examples__/withRowSelection/withRowSelection.html +21 -0
  37. package/src/lightning/datatable/__examples__/withRowSelection/withRowSelection.js +34 -0
  38. package/src/lightning/datatable/__examples__/withTextWrapping/generateData.js +16 -0
  39. package/src/lightning/datatable/__examples__/withTextWrapping/withTextWrapping.html +14 -0
  40. package/src/lightning/datatable/__examples__/withTextWrapping/withTextWrapping.js +31 -0
  41. package/src/lightning/datatable/__examples__/withVirtualization/generateData.js +14 -0
  42. package/src/lightning/datatable/__examples__/withVirtualization/withVirtualization.html +12 -0
  43. package/src/lightning/datatable/__examples__/withVirtualization/withVirtualization.js +27 -0
  44. package/src/lightning/datatable/__examples__/withoutTableHeader/generateData.js +14 -0
  45. package/src/lightning/datatable/__examples__/withoutTableHeader/withoutTableHeader.html +10 -0
  46. package/src/lightning/datatable/__examples__/withoutTableHeader/withoutTableHeader.js +22 -0
  47. package/src/lightning/input/__docs__/input.md +8 -2
  48. package/src/lightning/input/input.js +16 -4
  49. package/src/lightning/pill/__docs__/pill.md +6 -2
  50. package/src/lightning/pillContainer/__docs__/pillContainer.md +16 -8
@@ -80,6 +80,7 @@
80
80
  "analyticsWaveApi": {
81
81
  "minVersion": "52.0"
82
82
  },
83
+ "ariaObserver": {},
83
84
  "auraDynamic": {},
84
85
  "auraUtilsMock": {},
85
86
  "avatar": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lightning-base-components",
3
- "version": "1.20.1-alpha",
3
+ "version": "1.21.0-alpha",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "external",
@@ -1372,6 +1372,7 @@
1372
1372
  "lightning/accordion",
1373
1373
  "lightning/accordionSection",
1374
1374
  "lightning/alert",
1375
+ "lightning/ariaObserver",
1375
1376
  "lightning/avatar",
1376
1377
  "lightning/badge",
1377
1378
  "lightning/barcodeScanner",
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <isExposed>true</isExposed>
4
+ </LightningComponentBundle>
@@ -0,0 +1,11 @@
1
+ <template>
2
+ <datatable-custom-datatype-table
3
+ key-field="id"
4
+ data={data}
5
+ columns={columns}
6
+ onprivatemoverowup={moveRowUp}
7
+ onprivatemoverowdown={moveRowDown}
8
+ onprivatedeleterow={deleteRow}
9
+ hide-checkbox-column>
10
+ </datatable-custom-datatype-table>
11
+ </template>
@@ -0,0 +1,158 @@
1
+ import { LightningElement, track } from 'lwc';
2
+
3
+ // Add <datatable-custom-datatable-wrapper></datatable-custom-datatable-wrapper> to the lwr-playground to see the table
4
+
5
+ const columns = [
6
+ {
7
+ label: 'Reorder',
8
+ type: 'orderingButtons',
9
+ fixedWidth: 90,
10
+ fieldName: 'id',
11
+ typeAttributes: {
12
+ isFirstRow: { fieldName: 'isFirstRow' },
13
+ isLastRow: { fieldName: 'isLastRow' },
14
+ },
15
+ },
16
+ {
17
+ label: 'Account Name',
18
+ type: 'customName',
19
+ typeAttributes: {
20
+ accountName: { fieldName: 'name' },
21
+ },
22
+ },
23
+ {
24
+ label: 'Website',
25
+ fieldName: 'website',
26
+ type: 'customLink',
27
+ typeAttributes: {
28
+ label: { fieldName: 'name' },
29
+ tooltip: { fieldName: 'name' },
30
+ },
31
+ hideDefaultActions: true,
32
+ actions: [
33
+ { label: 'Action 1', name: 'action1' },
34
+ { label: 'Action 2', name: 'action2' },
35
+ ],
36
+ },
37
+ {
38
+ label: 'Amount',
39
+ type: 'customNumber',
40
+ fieldName: 'amount',
41
+ editable: true,
42
+ typeAttributes: {
43
+ min: 0,
44
+ },
45
+ },
46
+ { label: 'Icon', type: 'iconPill' },
47
+ {
48
+ label: '',
49
+ type: 'deleteRowButton',
50
+ fieldName: 'id',
51
+ fixedWidth: 70,
52
+ typeAttributes: {
53
+ attrA: { fieldName: 'attrA' },
54
+ attrB: { fieldName: 'attrB' },
55
+ },
56
+ },
57
+ ];
58
+
59
+ const exampleData = [
60
+ {
61
+ id: 1,
62
+ name: 'Name 1',
63
+ website: 'https://www.google.com',
64
+ amount: 200.0,
65
+ isFirstRow: true,
66
+ isLastRow: false,
67
+ },
68
+ {
69
+ id: 2,
70
+ name: 'Name 2',
71
+ website: 'https://www.salesforce.com',
72
+ amount: 500000.0,
73
+ isFirstRow: false,
74
+ isLastRow: false,
75
+ },
76
+ {
77
+ id: 3,
78
+ name: 'Name 3',
79
+ website: 'https://www.quora.com',
80
+ amount: 600.0,
81
+ isFirstRow: false,
82
+ isLastRow: true,
83
+ },
84
+ ];
85
+
86
+ export default class CustomDatatableWrapper extends LightningElement {
87
+ @track data = exampleData;
88
+ @track columns = columns;
89
+
90
+ moveRowUp(event) {
91
+ const { rowId } = event.detail;
92
+ const index = findRowIndex(this.data, rowId);
93
+ if (index > 0) {
94
+ const row = this.data[index];
95
+ const previous = this.data[index - 1];
96
+ this.data = this.data
97
+ .slice(0, index - 1)
98
+ .concat([row, previous])
99
+ .concat(this.data.slice(index + 1));
100
+ if (index - 1 === 0) {
101
+ this.data[0].isFirstRow = true;
102
+ this.data[1].isFirstRow = false;
103
+ } else if (index === this.data.length - 1) {
104
+ this.data[index].isLastRow = true;
105
+ this.data[index - 1].isLastRow = false;
106
+ }
107
+ }
108
+ }
109
+
110
+ moveRowDown(event) {
111
+ const { rowId } = event.detail;
112
+ const index = findRowIndex(this.data, rowId);
113
+ const length = this.data.length;
114
+ if (index < length - 1) {
115
+ const row = this.data[index];
116
+ const next = this.data[index + 1];
117
+ this.data = this.data
118
+ .slice(0, index)
119
+ .concat([next, row])
120
+ .concat(this.data.slice(index + 2));
121
+ if (index === 0) {
122
+ this.data[0].isFirstRow = true;
123
+ this.data[1].isFirstRow = false;
124
+ } else if (index === this.data.length - 2) {
125
+ this.data[index].isLastRow = false;
126
+ this.data[index + 1].isLastRow = true;
127
+ }
128
+ }
129
+ }
130
+
131
+ deleteRow(event) {
132
+ const { rowId } = event.detail;
133
+ const index = findRowIndex(this.data, rowId);
134
+ const length = this.data.length;
135
+ if (index >= 0) {
136
+ this.data = this.data
137
+ .slice(0, index)
138
+ .concat(this.data.slice(index + 1));
139
+ if (index === 0) {
140
+ this.data[0].isFirstRow = true;
141
+ } else if (index === length - 1) {
142
+ this.data[length - 2].isLastRow = true;
143
+ }
144
+ }
145
+ }
146
+ }
147
+
148
+ function findRowIndex(data, rowId) {
149
+ let index = -1;
150
+ data.some((row, i) => {
151
+ if (row.id === rowId) {
152
+ index = i;
153
+ return true;
154
+ }
155
+ return false;
156
+ });
157
+ return index;
158
+ }
@@ -0,0 +1,6 @@
1
+ <template>
2
+ <div style="text-align: center;">
3
+ <lightning-button-icon icon-name="utility:delete" onclick={fireDeleteRow}>
4
+ </lightning-button-icon>
5
+ </div>
6
+ </template>
@@ -0,0 +1,28 @@
1
+ import { LightningElement, api } from 'lwc';
2
+ import { baseNavigation } from 'lightning/datatableKeyboardMixins';
3
+ import template from './customDatatypeDeleteRowBtn.html';
4
+
5
+ export default class CustomDatatypeDeleteRowBtn extends baseNavigation(
6
+ LightningElement
7
+ ) {
8
+ @api rowId;
9
+ @api attrA;
10
+ @api attrB;
11
+
12
+ // Required for mixins
13
+ render() {
14
+ return template;
15
+ }
16
+
17
+ fireDeleteRow() {
18
+ const event = CustomEvent('privatedeleterow', {
19
+ composed: true,
20
+ bubbles: true,
21
+ cancelable: true,
22
+ detail: {
23
+ rowId: this.rowId,
24
+ },
25
+ });
26
+ this.dispatchEvent(event);
27
+ }
28
+ }
@@ -0,0 +1,9 @@
1
+ <template>
2
+ <div>
3
+ <p><lightning-formatted-url value={url} tooltip="Omit leading slash" label={label} target="_blank"></lightning-formatted-url></p>
4
+ <p><lightning-formatted-url value={url} tooltip="Use full domain name" label={label}
5
+ target="_blank"></lightning-formatted-url></p>
6
+ <p><lightning-formatted-url value={url} tooltip="Use https://domain-name"
7
+ label={label} target="_blank"></lightning-formatted-url></p>
8
+ </div>
9
+ </template>
@@ -0,0 +1,15 @@
1
+ import { LightningElement, api } from 'lwc';
2
+ import mix from 'lightning/mixinBuilder';
3
+ import { baseNavigation } from 'lightning/datatableKeyboardMixins';
4
+ import template from './customDatatypeLink.html';
5
+
6
+ export default class CustomDatatypeLink extends mix(LightningElement).with(
7
+ baseNavigation
8
+ ) {
9
+ @api url;
10
+ @api label;
11
+
12
+ render() {
13
+ return template;
14
+ }
15
+ }
@@ -0,0 +1,10 @@
1
+ <template>
2
+ <div class={computedClass}>
3
+ <lightning-formatted-number format-style="currency" value={value}>
4
+ </lightning-formatted-number>
5
+ <lightning-icon class="slds-p-horizontal_xx-small" icon-name={computedIcon} size="xx-small"
6
+ variant={iconVariant}>
7
+ </lightning-icon>
8
+ ({range})
9
+ </div>
10
+ </template>
@@ -0,0 +1,21 @@
1
+ import { LightningElement, api } from 'lwc';
2
+
3
+ export default class CustomDatatypeNumber extends LightningElement {
4
+ @api value;
5
+ get range() {
6
+ return this.value > 50000 ? 'High' : 'Low';
7
+ }
8
+ get computedClass() {
9
+ return this.value > 50000
10
+ ? 'slds-text-color_success'
11
+ : 'slds-text-color_error';
12
+ }
13
+
14
+ get computedIcon() {
15
+ return this.value > 50000 ? 'utility:arrowup' : 'utility:arrowdown';
16
+ }
17
+
18
+ get iconVariant() {
19
+ return this.value > 50000 ? 'success' : 'error';
20
+ }
21
+ }
@@ -0,0 +1,10 @@
1
+ <template>
2
+ <div style="text-align: center; padding: 4px;">
3
+ <div class="slds-button-group" role="group">
4
+ <lightning-button-icon icon-name="utility:up" alternative-text="up" title="up" size="x-small"
5
+ onclick={fireMoveRowUp} disabled={isFirstRow}></lightning-button-icon>
6
+ <lightning-button-icon icon-name="utility:down" alternative-text="down" title="down" size="x-small"
7
+ onclick={fireMoveRowDown} disabled={isLastRow}></lightning-button-icon>
8
+ </div>
9
+ </div>
10
+ </template>
@@ -0,0 +1,40 @@
1
+ import { LightningElement, api } from 'lwc';
2
+ import mix from 'lightning/mixinBuilder';
3
+ import { baseNavigation } from 'lightning/datatableKeyboardMixins';
4
+ import template from './customDatatypeRowOrderingBtn.html';
5
+
6
+ export default class CustomDatatypeRowOrderingBtn extends mix(
7
+ LightningElement
8
+ ).with(baseNavigation) {
9
+ @api rowId;
10
+ @api isFirstRow;
11
+ @api isLastRow;
12
+
13
+ render() {
14
+ return template;
15
+ }
16
+
17
+ fireMoveRowUp() {
18
+ const event = new CustomEvent('privatemoverowup', {
19
+ composed: true,
20
+ bubbles: true,
21
+ cancelable: true,
22
+ detail: {
23
+ rowId: this.rowId,
24
+ },
25
+ });
26
+ this.dispatchEvent(event);
27
+ }
28
+
29
+ fireMoveRowDown() {
30
+ const event = new CustomEvent('privatemoverowdown', {
31
+ composed: true,
32
+ bubbles: true,
33
+ cancelable: true,
34
+ detail: {
35
+ rowId: this.rowId,
36
+ },
37
+ });
38
+ this.dispatchEvent(event);
39
+ }
40
+ }
@@ -0,0 +1,38 @@
1
+ import LightningDatatable from 'lightning/datatable';
2
+ import deleteRow from './deleteRow.html';
3
+ import orderingButtons from './orderingButtons.html';
4
+ import iconPill from './iconPill.html';
5
+ import customName from './customName.html';
6
+ import customNumber from './customNumber.html';
7
+ import customLink from './customLink.html';
8
+ import customNumberEdit from './customNumberEdit.html';
9
+
10
+ export default class CustomDatatypeTable extends LightningDatatable {
11
+ static customTypes = {
12
+ deleteRowButton: {
13
+ template: deleteRow,
14
+ typeAttributes: ['attrA', 'attrB'],
15
+ },
16
+ orderingButtons: {
17
+ template: orderingButtons,
18
+ typeAttributes: ['isFirstRow', 'isLastRow'],
19
+ },
20
+ customLink: {
21
+ template: customLink,
22
+ typeAttributes: ['label', 'tooltip'],
23
+ },
24
+ iconPill: {
25
+ template: iconPill,
26
+ },
27
+ customName: {
28
+ template: customName,
29
+ typeAttributes: ['accountName'],
30
+ },
31
+ customNumber: {
32
+ template: customNumber,
33
+ editTemplate: customNumberEdit,
34
+ standardCellLayout: true,
35
+ typeAttributes: ['min'],
36
+ },
37
+ };
38
+ }
@@ -0,0 +1,9 @@
1
+ <template>
2
+ <datatable-custom-datatype-link
3
+ data-navigation="enable"
4
+ url={value}
5
+ label={typeAttributes.label}
6
+ tabindex={internalTabIndex}
7
+ keyboard-mode={keyboardMode}>
8
+ </datatable-custom-datatype-link>
9
+ </template>
@@ -0,0 +1,4 @@
1
+ <template>
2
+ <lightning-badge label={typeAttributes.accountName} icon-name="standard:account">
3
+ </lightning-badge>
4
+ </template>
@@ -0,0 +1,3 @@
1
+ <template>
2
+ <datatable-custom-datatype-number value={value}></datatable-custom-datatype-number>
3
+ </template>
@@ -0,0 +1,10 @@
1
+ <template>
2
+ <lightning-input
3
+ type="number"
4
+ value={editedValue}
5
+ required={required}
6
+ label={columnLabel}
7
+ data-inputable="true"
8
+ min={typeAttributes.min}>
9
+ </lightning-input>
10
+ </template>
@@ -0,0 +1,8 @@
1
+ <template>
2
+ <datatable-custom-datatype-delete-row-btn
3
+ data-navigation="enable"
4
+ row-id={value}
5
+ attr-a={typeAttributes.attrA}
6
+ attr-b={typeAttributes.attrB}>
7
+ </datatable-custom-datatype-delete-row-btn>
8
+ </template>
@@ -0,0 +1,17 @@
1
+ <template>
2
+ <div style="padding: 0 10px;">
3
+ <span class="slds-pill slds-pill_link">
4
+ <span class="slds-pill__icon_container">
5
+ <span class="slds-icon_container slds-icon-standard-account" title="Account">
6
+ <lightning-icon class="slds-icon" icon-name="standard:account" alternative-text="Account" title="Account"></lightning-icon>
7
+ </span>
8
+ </span>
9
+ <a href="javascript:void(0);" class="slds-pill__action" title="Full pill label verbiage mirrored here"
10
+ tabindex={internalTabIndex}>
11
+ <span class="slds-pill__label">Pill Label</span>
12
+ </a>
13
+ <lightning-button-icon class="slds-button slds-button_icon slds-button_icon slds-pill__remove" icon-name="utility:close" size="x-small" alternative-text="close"
14
+ title="close" variant="bare"></lightning-button-icon>
15
+ </span>
16
+ </div>
17
+ </template>
@@ -0,0 +1,10 @@
1
+ <template>
2
+ <datatable-custom-datatype-row-ordering-btn
3
+ row-id={value}
4
+ is-first-row={typeAttributes.isFirstRow}
5
+ is-last-row={typeAttributes.isLastRow}
6
+ data-navigation="enable"
7
+ tabindex={internalTabIndex}
8
+ keyboard-mode={keyboardMode}>
9
+ </datatable-custom-datatype-row-ordering-btn>
10
+ </template>
@@ -0,0 +1,23 @@
1
+ export default function generateData({ amountOfRecords }) {
2
+ return [...Array(amountOfRecords)].map((_, index) => {
3
+ return {
4
+ name: `Name (${index})`,
5
+ boolean: Math.random() < 0.5,
6
+ website: 'www.salesforce.com',
7
+ phone: `${Math.floor(Math.random() * 9000000000) + 1000000000}`,
8
+ currency: Math.floor(Math.random() * 100),
9
+ date: new Date(
10
+ Date.now() + 86400000 * Math.ceil(Math.random() * 20)
11
+ ),
12
+ dateLocal: new Date(Date.now()),
13
+ email: 'test@salesforce.com',
14
+ location: {
15
+ latitude: (Math.random() * 90).toFixed(2),
16
+ longitude: (Math.random() * 180).toFixed(2),
17
+ },
18
+ number: Math.floor(Math.random() * 100),
19
+ percent: Math.random(),
20
+ iconName: 'action:approval',
21
+ };
22
+ });
23
+ }
@@ -0,0 +1,11 @@
1
+ <template>
2
+ <div style="height: 300px;">
3
+ <lightning-datatable
4
+ key-field="id"
5
+ hide-checkbox-column
6
+ data={data}
7
+ columns={columns}
8
+ column-widths-mode="auto">
9
+ </lightning-datatable>
10
+ </div>
11
+ </template>
@@ -0,0 +1,71 @@
1
+ import { LightningElement } from 'lwc';
2
+ import generateData from './generateData';
3
+
4
+ // Add <datatable-with-all-column-types></datatable-with-all-column-types> to the lwr-playground to see the table
5
+
6
+ const columns = [
7
+ { label: 'Name', fieldName: 'name' },
8
+ { label: 'Boolean', fieldName: 'boolean', type: 'boolean' },
9
+ { label: 'Url', fieldName: 'url', type: 'url' },
10
+ { label: 'Phone', fieldName: 'phone', type: 'phone' },
11
+ {
12
+ label: 'Currency',
13
+ fieldName: 'currency',
14
+ type: 'currency',
15
+ typeAttributes: {
16
+ currencyCode: 'EUR',
17
+ },
18
+ },
19
+ { label: 'Date', fieldName: 'date', type: 'date' },
20
+ {
21
+ label: 'Date-local',
22
+ fieldName: 'dateLocal',
23
+ type: 'date-local',
24
+ typeAttributes: {
25
+ month: '2-digit',
26
+ day: '2-digit',
27
+ },
28
+ },
29
+ { label: 'Email', fieldName: 'email', type: 'email' },
30
+ { label: 'Location', fieldName: 'location', type: 'location' },
31
+ { label: 'Number', fieldName: 'number', type: 'number' },
32
+ { label: 'Percent', fieldName: 'percent', type: 'percent' },
33
+ {
34
+ label: 'Action',
35
+ type: 'action',
36
+ typeAttributes: {
37
+ rowActions: [
38
+ { label: 'action 1', name: 'action1' },
39
+ { label: 'action 2', name: 'action2' },
40
+ ],
41
+ },
42
+ },
43
+ {
44
+ label: 'Button',
45
+ type: 'button',
46
+ typeAttributes: {
47
+ label: 'Submit',
48
+ name: 'submitAction',
49
+ iconName: { fieldName: 'iconName' },
50
+ },
51
+ },
52
+ {
53
+ label: 'Button-icon',
54
+ type: 'button-icon',
55
+ typeAttributes: {
56
+ label: 'Submit',
57
+ name: 'submitAction',
58
+ iconName: { fieldName: 'iconName' },
59
+ },
60
+ },
61
+ ];
62
+
63
+ export default class DatatableWithAllColumnTypes extends LightningElement {
64
+ data = [];
65
+ columns = columns;
66
+
67
+ connectedCallback() {
68
+ const data = generateData({ amountOfRecords: 100 });
69
+ this.data = data;
70
+ }
71
+ }
@@ -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,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
+ }
@@ -59,7 +59,7 @@ supports the following input types:
59
59
  - `checkbox`
60
60
  - `checkbox-button`
61
61
  - `date`
62
- - `datetime`
62
+ - `datetime`/`datetime-local`
63
63
  - `time`
64
64
  - `email`
65
65
  - `file`
@@ -71,7 +71,9 @@ supports the following input types:
71
71
  - `text` (default)
72
72
  - `toggle`
73
73
 
74
- The following HTML input types are not supported.
74
+ There is no behavioral difference between the `datetime` and `datetime-local` types.
75
+
76
+ The following HTML input types aren't supported.
75
77
 
76
78
  - `button`
77
79
  - `hidden`
@@ -79,6 +81,8 @@ The following HTML input types are not supported.
79
81
  - `radio`
80
82
  - `reset`
81
83
  - `submit`
84
+ - `week`
85
+ - `month`
82
86
 
83
87
  Use [`lightning-button`](bundle/lightning-button/documentation)
84
88
  instead for input types `button`, `reset`, and
@@ -87,6 +91,8 @@ instead for input types `button`, `reset`, and
87
91
  Use [`lightning-radio-group`](bundle/lightning-radio-group/documentation)
88
92
  instead of input type `radio` for radio buttons.
89
93
 
94
+ Use [`lightning-combobox`](bundle/lightning-combobox/documentation) or input type `number` instead of input types `week` and `month`. The `week` and `month` types are browser-dependent and may cause issues with styling, accessibility, and general functionality in specific browsers.
95
+
90
96
  When working with forms that interact with Salesforce records, consider using the record form components. The `lightning-record-form`, `lightning-record-view-form`, and `lightning-record-edit-form` components provide a form-based UI that's metadata-driven. The components are automatically wired up to your record data, labels, and field-level help text. For more information, see [Work with Records Using Base Components](https://developer.salesforce.com/docs/platform/lwc/guide/data-get-user-input-intro).
91
97
 
92
98
  Alternatively, to create your own custom UI to work with Salesforce records, use `lightning-input` with the `lightning/ui*Api` wire adapters and functions, such as `getRecord` and `updateRecord`. For more information, see [Use the Wire Service with Base Components](https://developer.salesforce.com/docs/platform/lwc/guide/data-wire-base-components).
@@ -1815,16 +1815,21 @@ export default class LightningInput extends LightningElement {
1815
1815
  * @returns {boolean} - wether the value is valid or not
1816
1816
  */
1817
1817
  _validateType(type) {
1818
+ if (VALID_INPUT_TYPES.includes(type)) {
1819
+ return true;
1820
+ }
1821
+
1822
+ const invalidMsg = `<lightning-input> The type attribute value "${type}" is invalid.`;
1818
1823
  assert(
1819
1824
  type !== 'hidden',
1820
- `<lightning-input> The type attribute value "hidden" is invalid. Use a regular <input type="hidden"> instead.`
1825
+ `${invalidMsg} Use a regular <input type="hidden"> instead.`
1821
1826
  );
1822
1827
  assert(
1823
1828
  type !== 'submit' &&
1824
1829
  type !== 'reset' &&
1825
1830
  type !== 'image' &&
1826
1831
  type !== 'button',
1827
- `<lightning-input> The type attribute value "${type}" is invalid. Use <lightning:button> instead.`
1832
+ `${invalidMsg} Use <lightning:button> instead.`
1828
1833
  );
1829
1834
  if (this.isTypeRadio) {
1830
1835
  assert(
@@ -1832,12 +1837,19 @@ export default class LightningInput extends LightningElement {
1832
1837
  `<lightning-input> The required attribute is not supported on radio inputs directly. It should be implemented at the radio group level.`
1833
1838
  );
1834
1839
  }
1840
+
1835
1841
  if (type === 'phone') {
1836
1842
  console.warn(
1837
- `<lightning-input> The type attribute value "phone" is invalid. Please use <lightning-input type="tel"> instead. Defaulting to text type.`
1843
+ `${invalidMsg} Please use <lightning-input type="tel"> instead. Defaulting to text type.`
1838
1844
  );
1845
+ } else if (type === 'week' || type === 'month') {
1846
+ console.warn(
1847
+ `${invalidMsg} Please use <lightning-combobox> and/or <lightning-input type="number"> instead to avoid inconsistencies and breakages across browsers.`
1848
+ );
1849
+ } else {
1850
+ console.warn(`${invalidMsg} Defaulting to text type.`);
1839
1851
  }
1840
- return VALID_INPUT_TYPES.includes(type);
1852
+ return false;
1841
1853
  }
1842
1854
 
1843
1855
  /**
@@ -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
 
@@ -16,7 +16,7 @@ To specify the pills, set the `items` attribute to an array of values in your co
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
17
  For information about changing the behavior, see **Managing Pill Layout in the Container**.
18
18
 
19
- This example creates three pills: a text-only pill, a pill with an avatar, and
19
+ This example creates three pills: a text-only pill, a pill with a link and an avatar, and
20
20
  a pill with an icon.
21
21
 
22
22
  ```html
@@ -37,6 +37,7 @@ export default class PillContainerExample extends LightningElement {
37
37
  {
38
38
  type: 'avatar',
39
39
  label: 'Avatar Pill',
40
+ href: 'https://www.example.com',
40
41
  name: 'avatarpill',
41
42
  src: '/my/path/avatar.jpg',
42
43
  fallbackIconName: 'standard:user',
@@ -60,11 +61,15 @@ be used to create a pill with an avatar or icon.
60
61
  - `label`: Required. The text label that displays in the pill.
61
62
  - `name`: The name for the pill. This value is optional and can be used to identify the pill in a callback.
62
63
 
64
+ To create a pill with a link, use the following attribute.
65
+
66
+ - `href`: Required. The URL for the link.
67
+
63
68
  To create a pill with an avatar, use the following attributes.
64
69
 
65
70
  - `type`: The media type. Use `avatar`.
66
71
  - `src`: Required. The URL of the avatar.
67
- - `fallbackIconName`: The Lightning Design System name of the icon used as a fallback when the image fails to load. The initials fallback relies on this icon for its background color. Names are written in the format 'standard:account' where 'standard' is the category, and 'account' is the specific icon to be displayed. Only icons from the standard and custom categories are allowed.
72
+ - `fallbackIconName`: The Lightning Design System name of the icon to use as a fallback when the image fails to load. Names are written in the format 'standard:account' where 'standard' is the category, and 'account' is the specific icon to be displayed. Only icons from the standard and custom categories are allowed.
68
73
  - `variant`: Changes the shape of the avatar. Valid values are empty, circle, and square. This value defaults to square.
69
74
  - `alternativeText`: The alternative text used to describe the avatar, which is displayed as hover text on the image.
70
75
 
@@ -74,7 +79,7 @@ To create a pill with an icon, use the following attributes.
74
79
  - `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`.
75
80
  - `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'.
76
81
 
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.
82
+ `lightning-pill-container` provides two variants: `bare` and `standard` (default). They’re visually the same. However, the `standard` variant renders pills in an unordered list element. For more information, see the **Accessibility** section.
78
83
 
79
84
  #### Removing Pills
80
85
 
@@ -133,7 +138,7 @@ set to false by default, which makes all pills display and wrap to multiple line
133
138
 
134
139
  - `is-collapsible`: Determines whether the list of pills can be expanded and collapsed. If `is-collapsible` is true, `is-expanded` can determine whether a pill list displays all the pills or one line of pills. If `is-collapsible` is false or not specified, the `is-expanded` attribute has no effect regardless of its value.
135
140
  - `is-expanded`: Determines whether the full list of pills is shown. Set `is-collapsible` to true if you want to set `is-expanded` to expand and collapse the list. If you set `is-expanded` to false and don't set `is-collapsible` to true, the list is expanded.
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`.
141
+ - `single-line`: Specifies that the pill container can display one line of pills. By default, if pills can't fit on one line, they’re 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`.
137
142
 
138
143
  If all pills aren't displayed, the component shows a text button indicating how many more pills there are.
139
144
  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.
@@ -255,13 +260,16 @@ To understand how we implemented SLDS in `lightning-pill-container`, see the **S
255
260
 
256
261
  #### Accessibility
257
262
 
258
- By default, `lightning-pill-container` renders pills using the `standard` variant, which uses an unordered list element to display pills. Press the Tab key to focus on the first pill and use the Left Arrow and Right Arrow keys to navigate through the pills. Tabbing and navigating with arrow keys puts focus only on the pill borders, not on the remove buttons. The `standard` variant renders `aria` and `role` attributes in the list elements.
263
+ By default, `lightning-pill-container` renders pills using the `standard` variant, which uses an unordered list element to display pills. Press the Tab key to focus on the first pill and use the Left Arrow and Right Arrow keys to navigate through the pills. Use the Tab key to navigate to the remove button in a pill with a link. Use arrow keys to navigate between pills.
264
+ The focus goes to a link if present, otherwise focus goes to the remove button.
265
+
266
+ The `bare` variant only supports the Tab key for navigating between focusable elements in the container's pills. The arrow keys aren't supported.
259
267
 
260
- The `bare` variant provides a focusable remove button. Tab to focus on the pill and tab again to focus on the remove button. The `bare` variant doesn't render `aria` and `role` attributes.
268
+ On mobile devices, both container variants display pills with the close button as a focusable element for accessibility.
261
269
 
262
- On mobile devices, both variants display the close button as a focusable element for accessibility.
270
+ To remove a pill, press Enter or the space bar when the pill's remove button receives focus. On mobile devices, you can tap the remove button to remove a pill.
263
271
 
264
- To remove a pill, press the Delete or Backspace key when the pill receives focus. On mobile devices, you can tap the remove button to remove a pill.
272
+ For pills with links, use the Tab key or arrow keys to focus on the pill's link, then press Enter to navigate to the link target. If you don't navigate away from the pill, tabbing again puts focus on the remove button.
265
273
 
266
274
  #### Custom Events
267
275