lightning-base-components 1.13.8-alpha → 1.14.2-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/metadata/raptor.json +7 -0
  2. package/package.json +5 -1
  3. package/scopedImports/@salesforce-internal-core.appVersion.js +1 -1
  4. package/scopedImports/@salesforce-label-LightningLookup.recentItems.js +1 -0
  5. package/src/lightning/ariaObserver/__component__/ariaObserver.spec.js +103 -0
  6. package/src/lightning/{utilsPrivate/contentMutation.js → ariaObserver/ariaObserver.js} +51 -78
  7. package/src/lightning/baseCombobox/baseCombobox.html +1 -0
  8. package/src/lightning/baseCombobox/baseCombobox.js +14 -1
  9. package/src/lightning/combobox/combobox.css +12 -0
  10. package/src/lightning/combobox/combobox.html +1 -0
  11. package/src/lightning/datatable/columnWidthManager.js +7 -3
  12. package/src/lightning/datatable/datatable.js +27 -25
  13. package/src/lightning/datatable/inlineEdit.js +15 -3
  14. package/src/lightning/datatable/keyboard.js +1077 -933
  15. package/src/lightning/datatable/resizer.js +91 -108
  16. package/src/lightning/datatable/state.js +0 -9
  17. package/src/lightning/datatable/templates/div/div.css +19 -0
  18. package/src/lightning/datatable/templates/div/div.html +10 -8
  19. package/src/lightning/datatable/templates/table/table.html +8 -6
  20. package/src/lightning/datatable/widthManagerShared.js +1 -1
  21. package/src/lightning/formattedRichText/__docs__/formattedRichText.md +1 -0
  22. package/src/lightning/helptext/helptext.js +8 -0
  23. package/src/lightning/iconSvgTemplates/buildTemplates/templates.js +2 -1
  24. package/src/lightning/iconSvgTemplates/buildTemplates/utility/contract_alt.html +1 -2
  25. package/src/lightning/iconSvgTemplates/buildTemplates/utility/contract_doc.html +8 -0
  26. package/src/lightning/iconSvgTemplatesRtl/buildTemplates/templates.js +2 -1
  27. package/src/lightning/iconSvgTemplatesRtl/buildTemplates/utility/contract_alt.html +1 -2
  28. package/src/lightning/iconSvgTemplatesRtl/buildTemplates/utility/contract_doc.html +8 -0
  29. package/src/lightning/iconSvgTemplatesUtility/buildTemplates/templates.js +2 -1
  30. package/src/lightning/iconSvgTemplatesUtility/buildTemplates/utility/contract_alt.html +1 -2
  31. package/src/lightning/iconSvgTemplatesUtility/buildTemplates/utility/contract_doc.html +8 -0
  32. package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/templates.js +2 -1
  33. package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/utility/contract_alt.html +1 -2
  34. package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/utility/contract_doc.html +8 -0
  35. package/src/lightning/input/input.html +0 -1
  36. package/src/lightning/input/input.js +69 -48
  37. package/src/lightning/positionLibrary/positionLibrary.js +43 -31
  38. package/src/lightning/primitiveDatatableIeditPanel/primitiveDatatableIeditPanel.js +20 -0
  39. package/src/lightning/primitiveDatatableIeditTypeFactory/primitiveDatatableIeditTypeFactory.js +10 -0
  40. package/src/lightning/primitiveHeaderFactory/nonsortableHeader.html +5 -4
  41. package/src/lightning/primitiveHeaderFactory/primitiveHeaderFactory.js +64 -47
  42. package/src/lightning/primitiveHeaderFactory/selectableHeader.html +25 -23
  43. package/src/lightning/primitiveHeaderFactory/sortableHeader.html +13 -9
  44. package/src/lightning/progressIndicator/progressIndicator.js +3 -5
  45. package/src/lightning/progressStep/progressStep.js +31 -22
  46. package/src/lightning/utilsPrivate/utilsPrivate.js +12 -1
@@ -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 ARIA_LABELEDBY = 'aria-labelledby';
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 ContentMutation(this);
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.template.querySelector
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 ContentMutation(this);
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 ContentMutation once the issue is fixed.
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.link(
527
- 'input',
528
- 'aria-controls',
529
- references,
530
- '[data-aria]'
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.link(
552
- 'input',
553
- 'aria-labelledby',
554
- references,
555
- '[data-aria]'
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('aria-describedby');
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.link(
577
- 'input',
578
- 'aria-describedby',
579
- references,
580
- '[data-aria]'
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
- synchronizeAttrs(input, {
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
- synchronizeAttrs(datepicker, {
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
- synchronizeAttrs(timepicker, {
2061
- ariaLabelledByElement: this.ariaLabelledBy,
2062
- ariaDescribedByElements: this.ariaDescribedBy,
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
  }
@@ -131,38 +131,50 @@ function createRelationship(
131
131
  );
132
132
 
133
133
  const autoShrink = config.autoShrink.height || config.autoShrink.width;
134
- if (config.scrollableParentBound && scrollableParent) {
135
- const parent = normalizeElement(scrollableParent);
136
- const boxConfig = {
137
- element: config.element,
138
- enabled: config.enabled,
139
- target: createProxy(parent),
140
- align: {},
141
- targetAlign: {},
142
- pad: 3,
143
- boxDirections: {
144
- top: true,
145
- bottom: true,
146
- left: true,
147
- right: true,
148
- },
149
- };
150
- if (autoShrink) {
151
- const style = boxConfig.element.getNode().style;
152
- if (!style.minHeight) {
153
- style.minHeight = config.minHeight;
154
- boxConfig.element._removeMinHeight = true;
155
- }
156
-
157
- boxConfig.boxDirections = {
158
- top: !!config.autoShrink.height,
159
- bottom: !!config.autoShrink.height,
160
- left: !!config.autoShrink.width,
161
- right: !!config.autoShrink.width,
134
+ const modal = new OverlayDetector(originalConfig.target);
135
+ if (
136
+ (config.scrollableParentBound && scrollableParent) ||
137
+ (modal.isInsideModal && modal.overlay && autoShrink)
138
+ ) {
139
+ let parent;
140
+ if (config.scrollableParentBound && scrollableParent) {
141
+ parent = normalizeElement(scrollableParent);
142
+ } else if (modal.isInsideModal && modal.overlay) {
143
+ parent = normalizeElement(modal.overlay);
144
+ }
145
+ if (parent) {
146
+ const boxConfig = {
147
+ element: config.element,
148
+ enabled: config.enabled,
149
+ target: createProxy(parent),
150
+ align: {},
151
+ targetAlign: {},
152
+ pad: 3,
153
+ boxDirections: {
154
+ top: true,
155
+ bottom: true,
156
+ left: true,
157
+ right: true,
158
+ },
162
159
  };
163
- constraintList.push(new Constraint('shrinking box', boxConfig));
164
- } else {
165
- constraintList.push(new Constraint('bounding box', boxConfig));
160
+
161
+ if (autoShrink) {
162
+ const style = boxConfig.element.getNode().style;
163
+ if (!style.minHeight) {
164
+ style.minHeight = config.minHeight;
165
+ boxConfig.element._removeMinHeight = true;
166
+ }
167
+
168
+ boxConfig.boxDirections = {
169
+ top: !!config.autoShrink.height,
170
+ bottom: !!config.autoShrink.height,
171
+ left: !!config.autoShrink.width,
172
+ right: !!config.autoShrink.width,
173
+ };
174
+ constraintList.push(new Constraint('shrinking box', boxConfig));
175
+ } else {
176
+ constraintList.push(new Constraint('bounding box', boxConfig));
177
+ }
166
178
  }
167
179
  }
168
180
 
@@ -116,6 +116,26 @@ export default class PrimitiveDatatableIeditPanel extends LightningElement {
116
116
  return this.template.querySelector('.dt-type-edit-factory');
117
117
  }
118
118
 
119
+ /**
120
+ * Checked when opening an edit panel to see if it's valid
121
+ * Logs an error if type is custom but does not have the
122
+ * required editTemplate with [data-inputable="true"] element
123
+ */
124
+ @api
125
+ get isEditableValid() {
126
+ if (
127
+ !this.columnDef.editableCustomType ||
128
+ this.inputableElement.isEditableCustomValid
129
+ ) {
130
+ return true;
131
+ } else if (this.columnDef.editableCustomType) {
132
+ console.error(
133
+ 'Editable custom types must define an editTemplate that includes an element with attribute data-inputable set to "true"'
134
+ );
135
+ }
136
+ return false;
137
+ }
138
+
119
139
  @api
120
140
  get value() {
121
141
  return this.inputableElement ? this.inputableElement.value : null;
@@ -159,4 +159,14 @@ export default class LightningPrimitiveDatatableIeditTypeFactory extends Lightni
159
159
  this._columnDef.editableCustomType && this._columnDef.editTemplate
160
160
  );
161
161
  }
162
+
163
+ /**
164
+ * Checks if type is an custom type that is editable and
165
+ * has an editTemplate that contains [data-inputable="true"]
166
+ * Used when checking if cell can actually be edited
167
+ */
168
+ @api
169
+ get isEditableCustomValid() {
170
+ return this.isValidCustomType && this.concreteComponent;
171
+ }
162
172
  }
@@ -1,8 +1,7 @@
1
1
  <template>
2
- <div
3
- class={computedClass}
4
- style={columnStyles}
5
- >
2
+ <div class={computedClass} style={columnStyles}>
3
+
4
+ <!-- Header Content -->
6
5
  <span class="slds-th__action">
7
6
  <template if:true={def.iconName}>
8
7
  <div class="slds-grid slds-grid_vertical-align-center slds-has-flexi-truncate">
@@ -17,6 +16,7 @@
17
16
  <span class="slds-truncate" if:false={def.label} title={def.ariaLabel}></span>
18
17
  </template>
19
18
 
19
+ <!-- Header Actions -->
20
20
  <template if:true={hasActions}>
21
21
  <lightning-primitive-header-actions
22
22
  col-key-value={def.colKeyValue}
@@ -26,6 +26,7 @@
26
26
  ></lightning-primitive-header-actions>
27
27
  </template>
28
28
 
29
+ <!-- Resize Handler -->
29
30
  <template if:true={isResizable}>
30
31
  <lightning-primitive-resize-handler
31
32
  value={columnWidth}
@@ -32,6 +32,7 @@ export default class PrimitiveHeaderFactory extends PrimitiveDatatableCell {
32
32
  // Private variables
33
33
  _resizable;
34
34
  _sortable = false;
35
+ _hideHeader = false;
35
36
 
36
37
  /************************** PUBLIC ATTRIBUTES ***************************/
37
38
 
@@ -70,6 +71,21 @@ export default class PrimitiveHeaderFactory extends PrimitiveDatatableCell {
70
71
  this.updateElementClasses();
71
72
  }
72
73
 
74
+ /**
75
+ * Defines whether the table header is hidden
76
+ *
77
+ * @type {boolean}
78
+ */
79
+ @api
80
+ get hideHeader() {
81
+ return this._hideHeader;
82
+ }
83
+
84
+ set hideHeader(value) {
85
+ this._hideHeader = value;
86
+ this.updateElementClasses();
87
+ }
88
+
73
89
  /**
74
90
  * Defines whether the column is resizable
75
91
  *
@@ -165,44 +181,51 @@ export default class PrimitiveHeaderFactory extends PrimitiveDatatableCell {
165
181
  }
166
182
 
167
183
  /**
168
- * Determines if sort direction is set to ascending
184
+ * Computes an option name
169
185
  *
170
- * @return {boolean} Whether the sort direction is ascending
186
+ * @return {string} The computed option name
171
187
  */
172
- get isAscSorted() {
173
- return this.sortedDirection === 'asc';
188
+ get computedOptionName() {
189
+ return `${this.dtContextId}-options`;
174
190
  }
175
191
 
176
192
  /**
177
- * Determines if sort direction is set to descending
193
+ * Determines if the header has actions available
178
194
  *
179
- * @return {boolean} Whether the sort direction is descending
195
+ * @return {boolean} Whether the header has available actions
180
196
  */
181
- get isDescSorted() {
182
- return this.sortedDirection === 'desc';
197
+ get hasActions() {
198
+ return (
199
+ this.actions.customerActions.length > 0 ||
200
+ this.actions.internalActions.length > 0
201
+ );
183
202
  }
184
203
 
185
204
  /**
186
- * Returns the sort order label in the appropriate language
205
+ * Returns the header's aria role
187
206
  *
188
- * @return {string} Language-specific sort order label
207
+ * @return {string|boolean} The aria role for the header
189
208
  */
190
- get sortedOrderLabel() {
191
- if (this.sorted) {
192
- return this.sortedDirection === 'desc'
193
- ? i18n.sortDesc
194
- : i18n.sortAsc;
195
- }
196
- return i18n.sortNone;
209
+ get headerRole() {
210
+ return this.isResizable || this.sortable ? 'button' : false;
197
211
  }
198
212
 
199
213
  /**
200
- * Determines if the header is selectable
214
+ * Determines if sort direction is set to ascending
201
215
  *
202
- * @return {boolean} Whether the header is selectable
216
+ * @return {boolean} Whether the sort direction is ascending
203
217
  */
204
- get isSelectableHeader() {
205
- return this.def.type === 'SELECTABLE_CHECKBOX';
218
+ get isAscSorted() {
219
+ return this.sortedDirection === 'asc';
220
+ }
221
+
222
+ /**
223
+ * Determines if sort direction is set to descending
224
+ *
225
+ * @return {boolean} Whether the sort direction is descending
226
+ */
227
+ get isDescSorted() {
228
+ return this.sortedDirection === 'desc';
206
229
  }
207
230
 
208
231
  /**
@@ -223,6 +246,15 @@ export default class PrimitiveHeaderFactory extends PrimitiveDatatableCell {
223
246
  return this.resizable && this.def.resizable !== false;
224
247
  }
225
248
 
249
+ /**
250
+ * Determines if the header is selectable
251
+ *
252
+ * @return {boolean} Whether the header is selectable
253
+ */
254
+ get isSelectableHeader() {
255
+ return this.def.type === 'SELECTABLE_CHECKBOX';
256
+ }
257
+
226
258
  /**
227
259
  * Determines if the header is sortable
228
260
  *
@@ -241,15 +273,6 @@ export default class PrimitiveHeaderFactory extends PrimitiveDatatableCell {
241
273
  return i18n;
242
274
  }
243
275
 
244
- /**
245
- * Returns the header's aria role
246
- *
247
- * @return {string|boolean} The aria role for the header
248
- */
249
- get headerRole() {
250
- return this.isResizable || this.sortable ? 'button' : false;
251
- }
252
-
253
276
  /**
254
277
  * Returns the header's resize step
255
278
  *
@@ -260,24 +283,17 @@ export default class PrimitiveHeaderFactory extends PrimitiveDatatableCell {
260
283
  }
261
284
 
262
285
  /**
263
- * Computes an option name
264
- *
265
- * @return {string} The computed option name
266
- */
267
- get computedOptionName() {
268
- return `${this.dtContextId}-options`;
269
- }
270
-
271
- /**
272
- * Determines if the header has actions available
286
+ * Returns the sort order label in the appropriate language
273
287
  *
274
- * @return {boolean} Whether the header has available actions
288
+ * @return {string} Language-specific sort order label
275
289
  */
276
- get hasActions() {
277
- return (
278
- this.actions.customerActions.length > 0 ||
279
- this.actions.internalActions.length > 0
280
- );
290
+ get sortedOrderLabel() {
291
+ if (this.sorted) {
292
+ return this.sortedDirection === 'desc'
293
+ ? i18n.sortDesc
294
+ : i18n.sortAsc;
295
+ }
296
+ return i18n.sortNone;
281
297
  }
282
298
 
283
299
  /************************** LIFECYCLE HOOKS **************************/
@@ -364,12 +380,13 @@ export default class PrimitiveHeaderFactory extends PrimitiveDatatableCell {
364
380
  /************************* HELPER FUNCTIONS **************************/
365
381
 
366
382
  /**
367
- * Updates classes based on sort and resize eligibility
383
+ * Updates classes based on sort, resize and header eligibility
368
384
  */
369
385
  updateElementClasses() {
370
386
  classListMutation(this.classList, {
371
387
  'slds-is-sortable': this.isSortable,
372
388
  'slds-is-resizable': this.isResizable,
389
+ 'slds-assistive-text': this.hideHeader,
373
390
  });
374
391
  }
375
392
 
@@ -1,30 +1,32 @@
1
1
  <template>
2
- <div class="slds-th__action slds-th__action_form slds-cell-fixed"
3
- style={columnStyles}>
2
+ <!-- Header Content -->
3
+ <div class="slds-th__action slds-th__action_form slds-cell-fixed" style={columnStyles}>
4
4
  <template if:true={showCheckbox}>
5
- <span class="slds-checkbox">
6
- <input
7
- type="checkbox"
8
- class="datatable-select-all"
9
- name={computedOptionName}
10
- id="lgt-dt-header-factory-id"
11
- onclick={handleSelectAllRows}
12
- tabindex={internalTabIndex}
13
- data-navigation="enable"
14
- disabled={def.isBulkSelectionDisabled}
15
- >
16
- <label class="slds-checkbox__label" for="lgt-dt-header-factory-id">
17
- <span class="slds-checkbox_faux"></span>
18
- <span class="slds-form-element__label slds-assistive-text">
19
- {i18n.selectAll}
20
- </span>
21
- </label>
22
- </span>
5
+ <span class="slds-checkbox">
6
+
7
+ <!-- Selectable Checkbox -->
8
+ <input
9
+ type="checkbox"
10
+ class="datatable-select-all"
11
+ name={computedOptionName}
12
+ id="lgt-dt-header-factory-id"
13
+ onclick={handleSelectAllRows}
14
+ tabindex={internalTabIndex}
15
+ data-navigation="enable"
16
+ disabled={def.isBulkSelectionDisabled}>
17
+
18
+ <label class="slds-checkbox__label" for="lgt-dt-header-factory-id">
19
+ <span class="slds-checkbox_faux"></span>
20
+ <span class="slds-form-element__label slds-assistive-text">
21
+ {i18n.selectAll}
22
+ </span>
23
+ </label>
24
+ </span>
23
25
  </template>
24
26
  <template if:false={showCheckbox}>
25
- <span id="column-group-header" class="slds-assistive-text" data-column-header>
26
- {i18n.chooseARow}
27
- </span>
27
+ <span id="column-group-header" class="slds-assistive-text" data-column-header>
28
+ {i18n.chooseARow}
29
+ </span>
28
30
  </template>
29
31
  </div>
30
32
  </template>
@@ -1,19 +1,19 @@
1
1
  <template>
2
- <span
3
- class={computedClass}
4
- tabindex={internalTabIndex}
5
- style={columnStyles}
6
- >
2
+ <!-- Header Content -->
3
+ <span class={computedClass} tabindex={internalTabIndex} style={columnStyles}>
4
+
7
5
  <a href="javascript:void(0);"
8
6
  class={computedSortClass}
9
7
  role={headerRole}
10
8
  tabindex={internalTabIndex}
11
9
  data-navigation="enable"
12
10
  onclick={handleSortingClick}
13
- style={columnStyles} data-action-triggers="enter">
11
+ style={columnStyles}
12
+ data-action-triggers="enter">
14
13
 
15
14
  <span class="slds-assistive-text">{i18n.sort}</span>
16
15
 
16
+ <!-- Icon to display to the left/start of the header text -->
17
17
  <template if:true={def.iconName}>
18
18
  <div class="slds-grid slds-grid_vertical-align-center slds-has-flexi-truncate">
19
19
  <lightning-icon icon-name={def.iconName} size="x-small" class="slds-icon_container slds-m-right_xx-small" alternative-text={def.label} title={def.label}></lightning-icon>
@@ -21,17 +21,18 @@
21
21
  <span class="slds-truncate">{def.label}</span>
22
22
  </template>
23
23
 
24
+ <!-- Arrow Icon - Rotates based on sorting direction -->
24
25
  <lightning-primitive-icon
25
26
  class="slds-icon_container"
26
27
  svg-class="slds-icon slds-icon-text-default slds-is-sortable__icon"
27
28
  icon-name="utility:arrowdown"
28
29
  size="x-small">
29
30
  </lightning-primitive-icon>
30
-
31
31
  </div>
32
32
  </template>
33
33
  <template if:false={def.iconName}>
34
34
  <span class="slds-truncate" title={def.label}>{def.label}</span>
35
+ <!-- Arrow Icon - Rotates based on sorting direction -->
35
36
  <lightning-primitive-icon
36
37
  class="slds-icon_container"
37
38
  svg-class="slds-icon slds-icon-text-default slds-is-sortable__icon"
@@ -41,17 +42,20 @@
41
42
  </template>
42
43
  </a>
43
44
 
45
+ <!-- Aria Live Region to announce sorting order -->
44
46
  <span class="slds-assistive-text" aria-live="polite" aria-atomic="true">{sortedOrderLabel}</span>
45
47
 
48
+ <!-- Header Actions -->
46
49
  <template if:true={hasActions}>
47
50
  <lightning-primitive-header-actions
48
51
  col-key-value={def.colKeyValue}
49
52
  actions={actions}
50
53
  tabindex={internalTabIndex}
51
- data-navigation="enable"
52
- ></lightning-primitive-header-actions>
54
+ data-navigation="enable">
55
+ </lightning-primitive-header-actions>
53
56
  </template>
54
57
 
58
+ <!-- Resize Handler -->
55
59
  <template if:true={isResizable}>
56
60
  <lightning-primitive-resize-handler
57
61
  value={columnWidth}