lightning-base-components 1.14.4-alpha → 1.14.6-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.
@@ -1,44 +1,25 @@
1
1
  import { LightningResizeObserver } from 'lightning/resizeObserver';
2
- import { isTableRenderedVisible } from './resizer';
2
+ import { isTableRenderedVisible } from './columnResizer';
3
3
  import { ResizeSensor } from './resizeSensor';
4
4
  import { debounce } from 'lightning/inputUtils';
5
5
  import { getColumns } from './columns';
6
6
 
7
7
  const WIDTH_OBSERVER_SELECTOR = '.dt-width-observer';
8
8
 
9
- function createResizeSensor(
10
- dtObserver,
11
- columnWidthManager,
12
- template,
13
- state,
14
- widthsData,
15
- resizeTarget
16
- ) {
17
- return new ResizeSensor(
18
- resizeTarget,
19
- debounce(() => {
20
- // since this event handler is debounced, it might be the case that at the time the handler is called,
21
- // the element is disconnected (this.hasDetachedListeners)
22
- // the scroll event which the ResizeSensor uses can happen when table is hidden (as in console when switching tabs)
23
- // and hence the need for isTableRenderedVisible check
24
- if (dtObserver.isConnected() && isTableRenderedVisible(template)) {
25
- columnWidthManager.adjustColumnsSizeAfterResize(
26
- template,
27
- getColumns(state),
28
- widthsData
29
- );
30
- }
31
- }, 200)
32
- );
33
- }
34
-
35
9
  export class LightningDatatableResizeObserver {
36
10
  _connected = false;
37
11
  _resizeObserverAvailable = typeof ResizeObserver === 'function';
38
12
 
13
+ /**
14
+ * Depending on the browser/availability, this will create either a (standard)
15
+ * ResizeObserver via LightningResizeObserver or fallback to the ResizeSensor
16
+ */
39
17
  constructor(template, state, widthsData, columnWidthManager) {
40
18
  const resizeTarget = template.querySelector(WIDTH_OBSERVER_SELECTOR);
41
19
 
20
+ // If ResizeObserver is available on the browser, create one and begin observing for changes
21
+ // Calculate and modify the column widths when there are changes to the dimensions
22
+ // and when the table is rendered and visible on screen
42
23
  if (this._resizeObserverAvailable) {
43
24
  this._resizeObserver = new LightningResizeObserver(() => {
44
25
  if (this._connected && isTableRenderedVisible(template)) {
@@ -51,8 +32,8 @@ export class LightningDatatableResizeObserver {
51
32
  });
52
33
  this._resizeObserver.observe(resizeTarget);
53
34
  } else {
54
- // fallback behavior for IE11 and Safari using existing resize sensor functionality (less performant)
55
- this._resizeSensor = createResizeSensor(
35
+ // fallback behavior for IE11 using existing resize sensor functionality (less performant)
36
+ this._resizeSensor = createResizeSensorForIE11(
56
37
  this,
57
38
  columnWidthManager,
58
39
  template,
@@ -65,6 +46,7 @@ export class LightningDatatableResizeObserver {
65
46
  this._connected = true;
66
47
  }
67
48
 
49
+ // Begins observing the specified element for changes in dimension
68
50
  observe(template) {
69
51
  const targetElement = template.querySelector(WIDTH_OBSERVER_SELECTOR);
70
52
 
@@ -77,6 +59,7 @@ export class LightningDatatableResizeObserver {
77
59
  this._connected = true;
78
60
  }
79
61
 
62
+ // Stops observing any/all observed elements for changes in dimension
80
63
  disconnect() {
81
64
  if (this._resizeObserver) {
82
65
  this._resizeObserver.disconnect();
@@ -92,3 +75,37 @@ export class LightningDatatableResizeObserver {
92
75
  return this._connected;
93
76
  }
94
77
  }
78
+
79
+ /**
80
+ * Creates a ResizeSensor which is used to observe the dimensions of an element.
81
+ *
82
+ * This ResizeSensor is only used in the event that the standard ResizeObserver
83
+ * is NOT available on the browser.
84
+ * Currently only IE11 does not support the ResizeObserver. We should be able to
85
+ * remove this once we fully drop support of IE11.
86
+ */
87
+ function createResizeSensorForIE11(
88
+ dtObserver,
89
+ columnWidthManager,
90
+ template,
91
+ state,
92
+ widthsData,
93
+ resizeTarget
94
+ ) {
95
+ return new ResizeSensor(
96
+ resizeTarget,
97
+ debounce(() => {
98
+ // since this event handler is debounced, it might be the case that at the time the handler is called,
99
+ // the element is disconnected (this.hasDetachedListeners)
100
+ // the scroll event which the ResizeSensor uses can happen when table is hidden (as in console when switching tabs)
101
+ // and hence the need for isTableRenderedVisible check
102
+ if (dtObserver.isConnected() && isTableRenderedVisible(template)) {
103
+ columnWidthManager.adjustColumnsSizeAfterResize(
104
+ template,
105
+ getColumns(state),
106
+ widthsData
107
+ );
108
+ }
109
+ }, 200)
110
+ );
111
+ }
@@ -1,3 +1,11 @@
1
+ /**
2
+ * IMPORTANT: This ResizeSensor is only used in the event that the standard ResizeObserver
3
+ * is NOT available on the browser.
4
+ *
5
+ * Currently only IE11 does not support the ResizeObserver. We should be able to
6
+ * remove this once we fully drop support of IE11.
7
+ */
8
+
1
9
  /**
2
10
  * Based on Marc J. Schmidt library: https://github.com/marcj/css-element-queries/blob/master
3
11
  */
@@ -18,7 +18,6 @@ import {
18
18
  import { isRowNumberColumn, getRowNumberErrorColumnDef } from './rowNumber';
19
19
  import { getRowError } from './errors';
20
20
  import { getDirtyValueFromCell } from './inlineEditShared';
21
- import { DEFAULT_ROW_HEIGHT } from './renderManager';
22
21
 
23
22
  export function getData(state) {
24
23
  return state.data;
@@ -116,7 +115,7 @@ export function uniqueRowKeyGenerator(keyField) {
116
115
  */
117
116
  export function updateRowsAndCellIndexes() {
118
117
  const { state, privateTypes: types } = this;
119
- const { keyField, renderModeRoleBased, virtualize } = state;
118
+ const { keyField, renderModeRoleBased, virtualize, rowHeight } = state;
120
119
  const data = getData(state);
121
120
  const columns = getColumns(state);
122
121
  const computeUniqueRowKey = uniqueRowKeyGenerator(keyField);
@@ -135,6 +134,7 @@ export function updateRowsAndCellIndexes() {
135
134
 
136
135
  state.indexes[row.key] = { rowIndex };
137
136
 
137
+ row.rowIndex = rowIndex;
138
138
  row.inputType = getRowSelectionInputType(state);
139
139
  row.isSelected = isSelectedRow(state, row.key);
140
140
  row.ariaSelected = row.isSelected ? 'true' : false;
@@ -145,7 +145,7 @@ export function updateRowsAndCellIndexes() {
145
145
  if (virtualize) {
146
146
  row.style = styleToString({
147
147
  position: 'absolute',
148
- top: `${rowIndex * DEFAULT_ROW_HEIGHT}px`,
148
+ top: `${rowIndex * rowHeight}px`,
149
149
  });
150
150
  }
151
151
 
@@ -41,7 +41,9 @@
41
41
  </template>
42
42
  <template if:true={hasValidKeyField}>
43
43
  <!-- Corresponds to <thead> -->
44
- <div role="rowgroup">
44
+ <div
45
+ data-rowgroup-header
46
+ role="rowgroup">
45
47
  <!-- TODO: Fix aria-rowindex to not be hardcoded -->
46
48
  <!-- TODO: might need to move the table-header class out or rename -->
47
49
  <!-- Column Header Row -->
@@ -108,8 +110,11 @@
108
110
  </div>
109
111
  </div>
110
112
  <!-- Corresponds to <tbody> -->
111
- <div style={computedTbodyStyle} role="rowgroup">
112
- <template for:each={renderedRows} for:item="row" for:index="rowIndex">
113
+ <div
114
+ data-rowgroup-body
115
+ role="rowgroup"
116
+ style={computedTbodyStyle}>
117
+ <template for:each={renderedRows} for:item="row">
113
118
  <!-- Data Rows -->
114
119
  <div class={row.classnames}
115
120
  role="row"
@@ -124,128 +129,128 @@
124
129
  aria-rowindex={row.ariaRowIndex}
125
130
  style={row.style}
126
131
  tabindex={row.tabIndex}>
127
- <template for:each={row.cells} for:item="cell">
128
- <template if:true={cell.isCheckbox}>
129
- <!-- Checkbox Cell -->
130
- <div class={cell.class}
131
- style={cell.style}
132
- role="gridcell"
133
- tabindex={cell.tabIndex}
134
- data-label={cell.dataLabel}
135
- data-col-key-value={cell.colKeyValue}
136
- key={cell.colKeyValue}>
137
- <lightning-primitive-cell-checkbox
138
- dt-context-id={_datatableId}
139
- has-focus={cell.hasFocus}
132
+ <template for:each={row.cells} for:item="cell">
133
+ <template if:true={cell.isCheckbox}>
134
+ <!-- Checkbox Cell -->
135
+ <div class={cell.class}
136
+ style={cell.style}
137
+ role="gridcell"
138
+ tabindex={cell.tabIndex}
140
139
  data-label={cell.dataLabel}
141
- key={cell.key}
142
- row-key-value={row.key}
143
- col-key-value={cell.colKeyValue}
144
- row-index={rowIndex}
145
- type={row.inputType}
146
- is-selected={row.isSelected}
147
- is-disabled={row.isDisabled}
148
- column-header-id={computedCheckboxColumnHeaderId}>
149
- </lightning-primitive-cell-checkbox>
150
- </div>
151
- </template>
152
- <template if:true={cell.isDataTypeScope}>
153
- <!-- Row Header Cell -->
154
- <div class={cell.class}
155
- role="rowheader"
156
- style={cell.style}
157
- aria-selected={cell.ariaSelected}
158
- aria-readonly={cell.ariaReadOnly}
159
- tabindex={cell.tabIndex}
160
- data-label={cell.dataLabel}
161
- data-col-key-value={cell.colKeyValue}
162
- key={cell.colKeyValue}>
163
- <lightning-primitive-cell-factory
164
- types={privateTypes}
140
+ data-col-key-value={cell.colKeyValue}
141
+ key={cell.colKeyValue}>
142
+ <lightning-primitive-cell-checkbox
143
+ dt-context-id={_datatableId}
144
+ has-focus={cell.hasFocus}
145
+ data-label={cell.dataLabel}
146
+ key={cell.key}
147
+ row-key-value={row.key}
148
+ col-key-value={cell.colKeyValue}
149
+ row-index={row.rowIndex}
150
+ type={row.inputType}
151
+ is-selected={row.isSelected}
152
+ is-disabled={row.isDisabled}
153
+ column-header-id={computedCheckboxColumnHeaderId}>
154
+ </lightning-primitive-cell-checkbox>
155
+ </div>
156
+ </template>
157
+ <template if:true={cell.isDataTypeScope}>
158
+ <!-- Row Header Cell -->
159
+ <div class={cell.class}
160
+ role="rowheader"
161
+ style={cell.style}
165
162
  aria-selected={cell.ariaSelected}
163
+ aria-readonly={cell.ariaReadOnly}
164
+ tabindex={cell.tabIndex}
166
165
  data-label={cell.dataLabel}
167
- alignment={cell.alignment}
168
- has-error={cell.hasError}
169
- has-focus={cell.hasFocus}
170
- column-label={cell.dataLabel}
171
- column-type={cell.columnType}
172
- column-sub-type={cell.columnSubType}
173
- wrap-text={cell.wrapText}
174
- wrap-text-max-lines={cell.wrapTextMaxLines}
175
- key={cell.columnType}
176
- row-key-value={row.key}
177
- col-key-value={cell.colKeyValue}
178
- value={cell.value}
179
- icon-name={cell.iconName}
180
- icon-label={cell.iconLabel}
181
- icon-position={cell.iconPosition}
182
- icon-alternative-text={cell.iconAlternativeText}
183
- editable={cell.editable}
184
- display-read-only-icon={cell.displayReadOnlyIcon}
185
- type-attribute-0={cell.typeAttribute0}
186
- type-attribute-1={cell.typeAttribute1}
187
- type-attribute-2={cell.typeAttribute2}
188
- type-attribute-3={cell.typeAttribute3}
189
- type-attribute-4={cell.typeAttribute4}
190
- type-attribute-5={cell.typeAttribute5}
191
- type-attribute-6={cell.typeAttribute6}
192
- type-attribute-7={cell.typeAttribute7}
193
- type-attribute-8={cell.typeAttribute8}
194
- type-attribute-9={cell.typeAttribute9}
195
- type-attribute-10={cell.typeAttribute10}
196
- type-attribute-21={cell.typeAttribute21}
197
- type-attribute-22={cell.typeAttribute22}>
198
- </lightning-primitive-cell-factory>
199
- </div>
200
- </template>
201
- <template if:true={cell.isDataType}>
202
- <!-- Non-Header Cells (Regular Data Cells) -->
203
- <div class={cell.class}
204
- role="gridcell"
205
- style={cell.style}
206
- aria-selected={cell.ariaSelected}
207
- aria-readonly={cell.ariaReadOnly}
208
- tabindex={cell.tabIndex}
209
- data-label={cell.dataLabel}
210
- data-col-key-value={cell.colKeyValue}
211
- key={cell.colKeyValue}>
212
- <lightning-primitive-cell-factory
213
- types={privateTypes}
166
+ data-col-key-value={cell.colKeyValue}
167
+ key={cell.colKeyValue}>
168
+ <lightning-primitive-cell-factory
169
+ types={privateTypes}
170
+ aria-selected={cell.ariaSelected}
171
+ data-label={cell.dataLabel}
172
+ alignment={cell.alignment}
173
+ has-error={cell.hasError}
174
+ has-focus={cell.hasFocus}
175
+ column-label={cell.dataLabel}
176
+ column-type={cell.columnType}
177
+ column-sub-type={cell.columnSubType}
178
+ wrap-text={cell.wrapText}
179
+ wrap-text-max-lines={cell.wrapTextMaxLines}
180
+ key={cell.columnType}
181
+ row-key-value={row.key}
182
+ col-key-value={cell.colKeyValue}
183
+ value={cell.value}
184
+ icon-name={cell.iconName}
185
+ icon-label={cell.iconLabel}
186
+ icon-position={cell.iconPosition}
187
+ icon-alternative-text={cell.iconAlternativeText}
188
+ editable={cell.editable}
189
+ display-read-only-icon={cell.displayReadOnlyIcon}
190
+ type-attribute-0={cell.typeAttribute0}
191
+ type-attribute-1={cell.typeAttribute1}
192
+ type-attribute-2={cell.typeAttribute2}
193
+ type-attribute-3={cell.typeAttribute3}
194
+ type-attribute-4={cell.typeAttribute4}
195
+ type-attribute-5={cell.typeAttribute5}
196
+ type-attribute-6={cell.typeAttribute6}
197
+ type-attribute-7={cell.typeAttribute7}
198
+ type-attribute-8={cell.typeAttribute8}
199
+ type-attribute-9={cell.typeAttribute9}
200
+ type-attribute-10={cell.typeAttribute10}
201
+ type-attribute-21={cell.typeAttribute21}
202
+ type-attribute-22={cell.typeAttribute22}>
203
+ </lightning-primitive-cell-factory>
204
+ </div>
205
+ </template>
206
+ <template if:true={cell.isDataType}>
207
+ <!-- Non-Header Cells (Regular Data Cells) -->
208
+ <div class={cell.class}
209
+ role="gridcell"
210
+ style={cell.style}
214
211
  aria-selected={cell.ariaSelected}
212
+ aria-readonly={cell.ariaReadOnly}
213
+ tabindex={cell.tabIndex}
215
214
  data-label={cell.dataLabel}
216
- alignment={cell.alignment}
217
- has-focus={cell.hasFocus}
218
- has-error={cell.hasError}
219
- column-label={cell.dataLabel}
220
- column-type={cell.columnType}
221
- column-sub-type={cell.columnSubType}
222
- wrap-text={cell.wrapText}
223
- wrap-text-max-lines={cell.wrapTextMaxLines}
224
- key={cell.columnType}
225
- row-key-value={row.key}
226
- col-key-value={cell.colKeyValue}
227
- value={cell.value}
228
- icon-name={cell.iconName}
229
- icon-label={cell.iconLabel}
230
- icon-position={cell.iconPosition}
231
- icon-alternative-text={cell.iconAlternativeText}
232
- editable={cell.editable}
233
- display-read-only-icon={cell.displayReadOnlyIcon}
234
- type-attribute-0={cell.typeAttribute0}
235
- type-attribute-1={cell.typeAttribute1}
236
- type-attribute-2={cell.typeAttribute2}
237
- type-attribute-3={cell.typeAttribute3}
238
- type-attribute-4={cell.typeAttribute4}
239
- type-attribute-5={cell.typeAttribute5}
240
- type-attribute-6={cell.typeAttribute6}
241
- type-attribute-7={cell.typeAttribute7}
242
- type-attribute-8={cell.typeAttribute8}
243
- type-attribute-9={cell.typeAttribute9}
244
- type-attribute-10={cell.typeAttribute10}
245
- type-attribute-21={cell.typeAttribute21}
246
- type-attribute-22={cell.typeAttribute22}>
247
- </lightning-primitive-cell-factory>
248
- </div>
215
+ data-col-key-value={cell.colKeyValue}
216
+ key={cell.colKeyValue}>
217
+ <lightning-primitive-cell-factory
218
+ types={privateTypes}
219
+ aria-selected={cell.ariaSelected}
220
+ data-label={cell.dataLabel}
221
+ alignment={cell.alignment}
222
+ has-focus={cell.hasFocus}
223
+ has-error={cell.hasError}
224
+ column-label={cell.dataLabel}
225
+ column-type={cell.columnType}
226
+ column-sub-type={cell.columnSubType}
227
+ wrap-text={cell.wrapText}
228
+ wrap-text-max-lines={cell.wrapTextMaxLines}
229
+ key={cell.columnType}
230
+ row-key-value={row.key}
231
+ col-key-value={cell.colKeyValue}
232
+ value={cell.value}
233
+ icon-name={cell.iconName}
234
+ icon-label={cell.iconLabel}
235
+ icon-position={cell.iconPosition}
236
+ icon-alternative-text={cell.iconAlternativeText}
237
+ editable={cell.editable}
238
+ display-read-only-icon={cell.displayReadOnlyIcon}
239
+ type-attribute-0={cell.typeAttribute0}
240
+ type-attribute-1={cell.typeAttribute1}
241
+ type-attribute-2={cell.typeAttribute2}
242
+ type-attribute-3={cell.typeAttribute3}
243
+ type-attribute-4={cell.typeAttribute4}
244
+ type-attribute-5={cell.typeAttribute5}
245
+ type-attribute-6={cell.typeAttribute6}
246
+ type-attribute-7={cell.typeAttribute7}
247
+ type-attribute-8={cell.typeAttribute8}
248
+ type-attribute-9={cell.typeAttribute9}
249
+ type-attribute-10={cell.typeAttribute10}
250
+ type-attribute-21={cell.typeAttribute21}
251
+ type-attribute-22={cell.typeAttribute22}>
252
+ </lightning-primitive-cell-factory>
253
+ </div>
249
254
  </template>
250
255
  </template>
251
256
  </div>
@@ -1,3 +1,11 @@
1
+ /**
2
+ * Creates and returns a metadata object the contains information about the
3
+ * number of fixed, flexible, and resized columns in the table
4
+ *
5
+ * @param {Object} columnWidthMetaData The initial column widths metadata
6
+ * @param {Object} columnDefs The column definition object
7
+ * @returns {Object} The computed metadata
8
+ */
1
9
  export function getTotalWidthsMetadata(columnWidthMetaData, columnDefs) {
2
10
  const initial = {
3
11
  totalFixedWidth: 0,
@@ -28,14 +36,24 @@ export function getTotalWidthsMetadata(columnWidthMetaData, columnDefs) {
28
36
  }
29
37
 
30
38
  /**
31
- * Get width of dom element.
32
- * @param {node} element - target dom element
33
- * @returns {number} - integer width of element
39
+ * Gets the width of a DOM element.
40
+ *
41
+ * @param {Node} element Target DOM element
42
+ * @returns {Number} The width of the DOM element
34
43
  */
35
44
  export function getDomWidth(element) {
36
45
  return element.offsetWidth;
37
46
  }
38
47
 
48
+ /**
49
+ * Gets the width of a column. If the column has a fixed width,
50
+ * it will always return that value. If the column does not have a fixed
51
+ * width, it will return the resized value (if applicable), otherwise
52
+ * the initial width.
53
+ *
54
+ * @param {Object} column The column object
55
+ * @returns {Number} The fixed width, resized width, or initial width of the column (in that priority order)
56
+ */
39
57
  export function getColumnWidthFromDef(column) {
40
58
  let resizedWidth;
41
59
  if (column.isResized) {
@@ -44,6 +62,12 @@ export function getColumnWidthFromDef(column) {
44
62
  return column.fixedWidth || resizedWidth || column.initialWidth;
45
63
  }
46
64
 
65
+ /**
66
+ * Creates a width CSS style string from a numeric value
67
+ *
68
+ * @param {Number} pixels Number of pixels
69
+ * @returns {String} The CSS width definition
70
+ */
47
71
  export function buildCSSWidthStyle(pixels) {
48
72
  return pixels > 0 ? `width:${pixels}px` : '';
49
73
  }
@@ -186,7 +186,7 @@
186
186
  required={required}
187
187
  readonly={readOnly}
188
188
  disabled={disabled}>
189
- <label id="file-selector-label" data-file-selector-label for="input-file"
189
+ <label id="file-selector-label" data-file-selector-label for="input-file" aria-hidden="true"
190
190
  class="slds-file-selector__body">
191
191
  <span class="slds-file-selector__button slds-button slds-button_neutral">
192
192
  <lightning-primitive-icon icon-name="utility:upload" variant="bare" svg-class="slds-button__icon slds-button__icon_left">
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div role="status" class={computedClass}>
3
- <span if:true={validAlternativeText} class="slds-assistive-text">{alternativeText}</span>
3
+ <span if:true={validAlternativeText} class="slds-assistive-text">{_altText}</span>
4
4
  <div class="slds-spinner__dot-a"></div>
5
5
  <div class="slds-spinner__dot-b"></div>
6
6
  </div>
@@ -27,12 +27,24 @@ export default class LightningSpinner extends LightningElement {
27
27
  */
28
28
  @api variant;
29
29
 
30
+ _altText = '';
31
+
30
32
  connectedCallback() {
31
33
  this.classList.add('slds-spinner_container');
32
34
  this.template.addEventListener('mousewheel', this.stopScrolling);
33
35
  this.template.addEventListener('touchmove', this.stopScrolling);
34
36
  }
35
37
 
38
+ renderedCallback() {
39
+ // [W-10320761] We set the _altText in the next tick because screen readers are not reading out
40
+ // the text when the text along the aria-live container is inserted into the DOM together.
41
+ // It is only working when only aria-live container is setup on load and later the content changes
42
+ // eslint-disable-next-line @lwc/lwc/no-async-operation
43
+ setTimeout(() => {
44
+ this._altText = this.alternativeText;
45
+ }, 0);
46
+ }
47
+
36
48
  get normalizedVariant() {
37
49
  return normalize(this.variant, {
38
50
  fallbackValue: 'base',
@@ -3,7 +3,7 @@ import locale from '@salesforce/i18n/locale';
3
3
  const NA_PHONE_NUMBER = '($1) $2-$3';
4
4
  const IS_TEN_DIGITS = /^\d{10}$/;
5
5
  const TEN_TO_NA = /(\d{3})(\d{3})(\d{4})/;
6
- const IS_ELEVEN_DIGITS = /^1\d{10}/;
6
+ const IS_ELEVEN_DIGITS = /^1\d{10}$/;
7
7
  const ELEVEN_TO_NA = /1(\d{3})(\d{3})(\d{4})$/;
8
8
 
9
9
  // The locale argument has been added for tests since there's currently no clean way of mocking the locale