lightning-base-components 1.19.7-alpha → 1.19.8-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/metadata/raptor.json +78 -0
- package/package.json +5 -1
- package/scopedImports/@salesforce-label-LightningProgressRing.progressRing.js +1 -0
- package/src/lightning/baseCombobox/baseCombobox.css +8 -0
- package/src/lightning/baseCombobox/baseCombobox.js +1 -0
- package/src/lightning/datatable/README.md +2 -1
- package/src/lightning/datatable/columnResizer.js +22 -18
- package/src/lightning/datatable/columnWidthManager.js +30 -22
- package/src/lightning/datatable/errors.js +2 -2
- package/src/lightning/datatable/infiniteLoading.js +13 -14
- package/src/lightning/datatable/sort.js +15 -16
- package/src/lightning/datatable/tree.js +10 -6
- package/src/lightning/datatable/types.js +158 -129
- package/src/lightning/datatable/utils.js +26 -24
- package/src/lightning/datatable/wrapText.js +15 -8
- package/src/lightning/input/input.html +23 -2
- package/src/lightning/input/input.js +54 -2
- package/src/lightning/primitiveCellFactory/primitiveCellFactory.js +74 -69
- package/src/lightning/primitiveDatatableStatusBar/primitiveDatatableStatusBar.js +8 -2
- package/src/lightning/primitiveHeaderFactory/primitiveHeaderFactory.js +62 -87
- package/src/lightning/primitiveInputCheckbox/primitiveInputCheckbox.html +3 -0
- package/src/lightning/primitiveInputCheckbox/primitiveInputCheckbox.js +3 -0
- package/src/lightning/primitiveInputCheckboxButton/primitiveInputCheckboxButton.html +3 -0
- package/src/lightning/primitiveInputCheckboxButton/primitiveInputCheckboxButton.js +3 -0
- package/src/lightning/primitiveInputFile/primitiveInputFile.html +3 -0
- package/src/lightning/primitiveInputFile/primitiveInputFile.js +3 -0
- package/src/lightning/primitiveInputRadio/primitiveInputRadio.html +3 -0
- package/src/lightning/primitiveInputRadio/primitiveInputRadio.js +3 -0
- package/src/lightning/primitiveInputSimple/primitiveInputSimple.html +6 -0
- package/src/lightning/primitiveInputSimple/primitiveInputSimple.js +7 -19
- package/src/lightning/primitiveInputToggle/primitiveInputToggle.html +4 -1
- package/src/lightning/primitiveInputToggle/primitiveInputToggle.js +3 -0
- package/src/lightning/progressRing/progressRing.html +9 -7
- package/src/lightning/progressRing/progressRing.js +15 -0
- package/src/lightning/tabBar/tabBar.html +5 -1
- package/src/lightning/tabBar/tabBar.js +25 -9
- package/src/lightning/utils/classSet.js +19 -19
- package/src/lightning/utilsPrivate/aria.js +11 -8
- package/src/lightning/utilsPrivate/classListMutation.js +5 -3
- package/src/lightning/utilsPrivate/classSet.js +11 -0
- package/src/lightning/utilsPrivate/eventEmitter.js +4 -4
- package/src/lightning/utilsPrivate/inert.js +6 -4
- package/src/lightning/utilsPrivate/utilsPrivate.js +40 -8
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
<lightning-primitive-file-droppable-zone multiple={multiple} disabled={disabled}>
|
|
11
11
|
<input type="file" id="input-file"
|
|
12
12
|
aria-label={ariaLabel}
|
|
13
|
+
aria-keyshortcuts={ariaKeyShortcuts}
|
|
14
|
+
aria-disabled={ariaDisabled}
|
|
15
|
+
aria-roledescription={ariaRoleDescription}
|
|
13
16
|
aria-invalid={ariaInvalid}
|
|
14
17
|
accesskey={accessKey}
|
|
15
18
|
class="slds-file-selector__input slds-assistive-text"
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
<div class="slds-form-element__control">
|
|
3
3
|
<span class="slds-radio">
|
|
4
4
|
<input type="radio" id="radio"
|
|
5
|
+
aria-keyshortcuts={ariaKeyShortcuts}
|
|
6
|
+
aria-disabled={ariaDisabled}
|
|
7
|
+
aria-roledescription={ariaRoleDescription}
|
|
5
8
|
aria-invalid={ariaInvalid}
|
|
6
9
|
accesskey={accessKey}
|
|
7
10
|
onblur={handleBlur}
|
|
@@ -6,6 +6,9 @@ import { isNativeComponent } from 'lightning/utilsPrivate';
|
|
|
6
6
|
export default class LightningPrimitiveInputRadio extends LightningElement {
|
|
7
7
|
@api variant;
|
|
8
8
|
@api ariaInvalid;
|
|
9
|
+
@api ariaKeyShortcuts;
|
|
10
|
+
@api ariaDisabled;
|
|
11
|
+
@api ariaRoleDescription;
|
|
9
12
|
@api accessKey;
|
|
10
13
|
@api name;
|
|
11
14
|
@api required;
|
|
@@ -16,6 +16,11 @@
|
|
|
16
16
|
aria-haspopup={ariaHasPopup}
|
|
17
17
|
aria-invalid={ariaInvalid}
|
|
18
18
|
aria-label={ariaLabel}
|
|
19
|
+
aria-keyshortcuts={ariaKeyShortcuts}
|
|
20
|
+
aria-disabled={ariaDisabled}
|
|
21
|
+
aria-roledescription={ariaRoleDescription}
|
|
22
|
+
aria-autocomplete={ariaAutoComplete}
|
|
23
|
+
aria-expanded={ariaExpanded}
|
|
19
24
|
autocomplete={autocomplete}
|
|
20
25
|
class="slds-input"
|
|
21
26
|
disabled={disabled}
|
|
@@ -31,6 +36,7 @@
|
|
|
31
36
|
onfocus={handleFocus}
|
|
32
37
|
oninput={handleInput}
|
|
33
38
|
onkeydown={handleKeyDown}
|
|
39
|
+
role={role}
|
|
34
40
|
part="input"
|
|
35
41
|
pattern={pattern}
|
|
36
42
|
placeholder={placeholder}
|
|
@@ -80,6 +80,13 @@ export default class LightningPrimitiveInputSimple extends LightningElement {
|
|
|
80
80
|
@api ariaInvalid;
|
|
81
81
|
@api timezone;
|
|
82
82
|
|
|
83
|
+
@api ariaKeyShortcuts;
|
|
84
|
+
@api ariaDisabled;
|
|
85
|
+
@api ariaRoleDescription;
|
|
86
|
+
@api ariaExpanded;
|
|
87
|
+
@api ariaAutoComplete;
|
|
88
|
+
@api role;
|
|
89
|
+
|
|
83
90
|
@api
|
|
84
91
|
get ariaDescribedByElements() {
|
|
85
92
|
return this.template.querySelector('[data-help-message]');
|
|
@@ -189,29 +196,10 @@ export default class LightningPrimitiveInputSimple extends LightningElement {
|
|
|
189
196
|
if (this._value !== previousValue) {
|
|
190
197
|
this.updateNumberValue(value);
|
|
191
198
|
}
|
|
192
|
-
|
|
193
|
-
// If updated value is invalid or not null, it should be updated
|
|
194
|
-
// Invalid numeric values should stay as-is to avoid programatically wiping a user-provided invalid
|
|
195
|
-
// value, such as '2e' from the input element. See @W-14121203
|
|
196
|
-
if (!badInput || !!value) {
|
|
197
|
-
this.setInputValueIfNeeded();
|
|
198
|
-
}
|
|
199
|
-
} else {
|
|
200
|
-
this.setInputValueIfNeeded();
|
|
201
199
|
}
|
|
202
200
|
}
|
|
203
201
|
}
|
|
204
202
|
|
|
205
|
-
setInputValueIfNeeded() {
|
|
206
|
-
// Again, due to the interop layer we need to check whether the value being set
|
|
207
|
-
// is different, otherwise we're duplicating the sets on the input, which result
|
|
208
|
-
// in different bugs like Japanese IME duplication of characters in Safari (likely a browser bug) or
|
|
209
|
-
// character position re-set in IE11.
|
|
210
|
-
if (this.inputElement.value !== this.displayedValue) {
|
|
211
|
-
this.setInputValue(this.getDisplayedValue());
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
203
|
@api
|
|
216
204
|
get inputElement() {
|
|
217
205
|
if (!this.cachedInputElement) {
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
part="checkbox"
|
|
12
12
|
accesskey={accessKey}
|
|
13
13
|
aria-label={ariaLabel}
|
|
14
|
+
aria-keyshortcuts={ariaKeyShortcuts}
|
|
15
|
+
aria-disabled={ariaDisabled}
|
|
16
|
+
aria-roledescription={ariaRoleDescription}
|
|
14
17
|
aria-invalid={ariaInvalid}
|
|
15
18
|
disabled={disabled}
|
|
16
19
|
name={name}
|
|
@@ -21,7 +24,7 @@
|
|
|
21
24
|
readonly={readOnly}
|
|
22
25
|
required={required}
|
|
23
26
|
>
|
|
24
|
-
<span id="toggle-description" data-toggle-description class="slds-checkbox_faux_container"
|
|
27
|
+
<span id="toggle-description" data-toggle-description class="slds-checkbox_faux_container">
|
|
25
28
|
<span class="slds-checkbox_faux" part="indicator"></span>
|
|
26
29
|
<span class="slds-checkbox_on">{messageToggleActive}</span>
|
|
27
30
|
<span class="slds-checkbox_off">{messageToggleInactive}</span>
|
|
@@ -30,6 +30,9 @@ export default class LightningPrimitiveInputToggle extends LightningElement {
|
|
|
30
30
|
@api readOnly;
|
|
31
31
|
@api required;
|
|
32
32
|
@api ariaInvalid;
|
|
33
|
+
@api ariaKeyShortcuts;
|
|
34
|
+
@api ariaDisabled;
|
|
35
|
+
@api ariaRoleDescription;
|
|
33
36
|
|
|
34
37
|
/**
|
|
35
38
|
* Text shown for the active state of a toggle. The default is "Active".
|
|
@@ -6,13 +6,10 @@
|
|
|
6
6
|
aria-valuemin="0"
|
|
7
7
|
aria-valuemax="100"
|
|
8
8
|
aria-valuenow={value}
|
|
9
|
+
aria-label={computeAriaLabel}
|
|
9
10
|
>
|
|
10
11
|
<svg viewBox="-1 -1 2 2">
|
|
11
|
-
<path
|
|
12
|
-
if:true={d}
|
|
13
|
-
class="slds-progress-ring__path"
|
|
14
|
-
d={d}
|
|
15
|
-
></path>
|
|
12
|
+
<path if:true={d} class="slds-progress-ring__path" d={d}></path>
|
|
16
13
|
</svg>
|
|
17
14
|
</div>
|
|
18
15
|
<div class="slds-progress-ring__content">
|
|
@@ -31,8 +28,13 @@
|
|
|
31
28
|
</div>
|
|
32
29
|
<div class="slds-progress-ring__progress-head">
|
|
33
30
|
<svg viewBox="-1 -1 2 2">
|
|
34
|
-
<circle
|
|
35
|
-
|
|
31
|
+
<circle
|
|
32
|
+
if:true={isProgressHeadVisible}
|
|
33
|
+
class="slds-progress-ring__path"
|
|
34
|
+
cx={progressHeadCenter.x}
|
|
35
|
+
cy={progressHeadCenter.y}
|
|
36
|
+
r="0.2"
|
|
37
|
+
></circle>
|
|
36
38
|
</svg>
|
|
37
39
|
</div>
|
|
38
40
|
</div>
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { LightningElement, api } from 'lwc';
|
|
2
2
|
import { classSet } from 'lightning/utils';
|
|
3
|
+
import { isUndefinedOrNull } from 'lightning/utilsPrivate';
|
|
4
|
+
import labelProgressRing from '@salesforce/label/LightningProgressRing.progressRing';
|
|
3
5
|
import labelWarningAltText from '@salesforce/label/LightningProgressRing.warning';
|
|
4
6
|
import labelExpiredAltText from '@salesforce/label/LightningProgressRing.expired';
|
|
5
7
|
import labelCompleteAltText from '@salesforce/label/LightningProgressRing.complete';
|
|
6
8
|
|
|
7
9
|
const i18n = {
|
|
10
|
+
progress: labelProgressRing,
|
|
8
11
|
warning: labelWarningAltText,
|
|
9
12
|
expired: labelExpiredAltText,
|
|
10
13
|
complete: labelCompleteAltText,
|
|
@@ -48,6 +51,12 @@ export default class progressRing extends LightningElement {
|
|
|
48
51
|
*/
|
|
49
52
|
@api direction = 'fill';
|
|
50
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Descriptive label provided for assistive technologies.
|
|
56
|
+
* @type {string}
|
|
57
|
+
*/
|
|
58
|
+
@api ariaLabel;
|
|
59
|
+
|
|
51
60
|
/**
|
|
52
61
|
* The size of the progress ring. Valid values include medium and large.
|
|
53
62
|
*
|
|
@@ -213,4 +222,10 @@ export default class progressRing extends LightningElement {
|
|
|
213
222
|
this.variant === 'base-autocomplete' && Number(this.value) === 100
|
|
214
223
|
);
|
|
215
224
|
}
|
|
225
|
+
|
|
226
|
+
get computeAriaLabel() {
|
|
227
|
+
return isUndefinedOrNull(this.ariaLabel)
|
|
228
|
+
? i18n.progress
|
|
229
|
+
: this.ariaLabel;
|
|
230
|
+
}
|
|
216
231
|
}
|
|
@@ -49,7 +49,11 @@
|
|
|
49
49
|
onselect={handleOverflowSelect}
|
|
50
50
|
icon-name="utility:chevrondown"
|
|
51
51
|
label={i18n.more}
|
|
52
|
-
menu-alignment="right"
|
|
52
|
+
menu-alignment="right"
|
|
53
|
+
onfocus={reflectOverflowFocusState}
|
|
54
|
+
onblur={reflectOverflowFocusState}
|
|
55
|
+
>
|
|
56
|
+
|
|
53
57
|
<template for:each={_allTabs} for:item="tab">
|
|
54
58
|
<template if:false={tab.visible}>
|
|
55
59
|
<lightning-menu-item key={tab.value} label={tab.label} value={tab.value} data-target-selection-name={tab.targetSelectionName}></lightning-menu-item>
|
|
@@ -70,6 +70,12 @@ export default class LightningTabBar extends LightningElement {
|
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
overflowFocused = false;
|
|
74
|
+
|
|
75
|
+
reflectOverflowFocusState(e) {
|
|
76
|
+
this.overflowFocused = e.type === 'focus';
|
|
77
|
+
}
|
|
78
|
+
|
|
73
79
|
@api
|
|
74
80
|
get variant() {
|
|
75
81
|
return this._variant;
|
|
@@ -329,22 +335,32 @@ export default class LightningTabBar extends LightningElement {
|
|
|
329
335
|
handleKeyDown(event) {
|
|
330
336
|
let currentFocusedIndex = 0;
|
|
331
337
|
|
|
332
|
-
if (this.
|
|
338
|
+
if (this._hasOverflow && this.overflowFocused) {
|
|
339
|
+
currentFocusedIndex = this._visibleTabs.length;
|
|
340
|
+
} else {
|
|
333
341
|
currentFocusedIndex = this._visibleTabs.findIndex(
|
|
334
|
-
(tab) => tab.value === this._selectedTab
|
|
342
|
+
(tab) => tab.value === this._selectedTab?.value
|
|
335
343
|
);
|
|
336
344
|
}
|
|
337
345
|
handleKeyDownOnTabList(event, currentFocusedIndex, {
|
|
338
346
|
isVerticalOrientation: () => this.isVerticalVariant,
|
|
339
|
-
|
|
347
|
+
// add + 1 to account for the "more" tab
|
|
348
|
+
totalTabs: () =>
|
|
349
|
+
this._visibleTabs.length + (this._hasOverflow ? 1 : 0),
|
|
340
350
|
selectTabIndex: (index) => {
|
|
341
351
|
const tab = this._visibleTabs[index];
|
|
342
|
-
this.
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
.
|
|
352
|
+
if (index === this._visibleTabs.length) {
|
|
353
|
+
this.template
|
|
354
|
+
.querySelector('lightning-button-menu')
|
|
355
|
+
.focus();
|
|
356
|
+
} else {
|
|
357
|
+
this._selectTabAndFireSelectEvent(tab.value, {
|
|
358
|
+
hasFocus: true,
|
|
359
|
+
});
|
|
360
|
+
this.template
|
|
361
|
+
.querySelector(`a[data-tab-value="${tab.value}"]`)
|
|
362
|
+
.focus();
|
|
363
|
+
}
|
|
348
364
|
},
|
|
349
365
|
});
|
|
350
366
|
}
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { classSetToString } from 'lightning/utilsPrivate';
|
|
2
|
+
|
|
3
|
+
function classNamesHash(hash, classes) {
|
|
4
|
+
if (typeof classes === 'string') {
|
|
5
|
+
const array = classes.trim().split(/\s+/);
|
|
6
|
+
for (let i = 0, { length } = array; i < length; i += 1) {
|
|
7
|
+
hash[array[i]] = true;
|
|
8
|
+
}
|
|
9
|
+
return hash;
|
|
10
|
+
}
|
|
11
|
+
return Object.assign(hash, classes);
|
|
12
|
+
}
|
|
12
13
|
|
|
13
14
|
const proto = {
|
|
14
15
|
add(className) {
|
|
15
|
-
|
|
16
|
-
return this;
|
|
16
|
+
return classNamesHash(this, className);
|
|
17
17
|
},
|
|
18
18
|
invert() {
|
|
19
|
-
Object.keys(this)
|
|
19
|
+
const keys = Object.keys(this);
|
|
20
|
+
for (let i = 0, { length } = keys; i < length; i += 1) {
|
|
21
|
+
const key = keys[i];
|
|
20
22
|
this[key] = !this[key];
|
|
21
|
-
}
|
|
23
|
+
}
|
|
22
24
|
return this;
|
|
23
25
|
},
|
|
24
26
|
toString() {
|
|
25
|
-
return
|
|
26
|
-
.filter((key) => this[key])
|
|
27
|
-
.join(' ');
|
|
27
|
+
return classSetToString(this);
|
|
28
28
|
},
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
export function classSet(config) {
|
|
32
|
-
return
|
|
32
|
+
return classNamesHash({ __proto__: proto }, config);
|
|
33
33
|
}
|
|
@@ -65,28 +65,31 @@ const ARIA_PROP_LIST = [
|
|
|
65
65
|
* @returns {Object} A lookup object for ARIA properties in (modified) kebab-case or camel-case
|
|
66
66
|
*/
|
|
67
67
|
const getAriaLookup = (list, type = 'default') => {
|
|
68
|
-
|
|
68
|
+
const length = list ? list.length : 0;
|
|
69
|
+
if (length === 0) {
|
|
69
70
|
throw new Error('List of aria properties is required');
|
|
70
71
|
}
|
|
71
72
|
const lookupObj = {};
|
|
72
73
|
if (type === 'default') {
|
|
73
|
-
|
|
74
|
+
for (let i = 0; i < length; i += 1) {
|
|
75
|
+
const name = list[i];
|
|
74
76
|
const nameUpperCase = name.toUpperCase();
|
|
75
77
|
if (!lookupObj[nameUpperCase]) {
|
|
76
78
|
lookupObj[nameUpperCase] = `aria-${name.toLowerCase()}`;
|
|
77
79
|
}
|
|
78
|
-
}
|
|
80
|
+
}
|
|
79
81
|
return lookupObj;
|
|
80
82
|
}
|
|
81
|
-
|
|
83
|
+
for (let i = 0; i < length; i += 1) {
|
|
84
|
+
const name = list[i];
|
|
82
85
|
const ariaPropertyLowerCase = `aria-${name.toLowerCase()}`;
|
|
83
|
-
const ariaPropertyCamelCase = `aria${name
|
|
84
|
-
.charAt(0)
|
|
85
|
-
.toUpperCase()}${name.slice(1)}`;
|
|
86
86
|
if (!lookupObj[ariaPropertyLowerCase]) {
|
|
87
|
+
const ariaPropertyCamelCase = `aria${name[0].toUpperCase()}${name.slice(
|
|
88
|
+
1
|
|
89
|
+
)}`;
|
|
87
90
|
lookupObj[ariaPropertyLowerCase] = ariaPropertyCamelCase;
|
|
88
91
|
}
|
|
89
|
-
}
|
|
92
|
+
}
|
|
90
93
|
return lookupObj;
|
|
91
94
|
};
|
|
92
95
|
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
export function classListMutation(classList, config) {
|
|
2
|
-
Object.keys(config)
|
|
3
|
-
|
|
2
|
+
const keys = Object.keys(config);
|
|
3
|
+
for (let i = 0, { length } = keys[i]; i < length; i += 1) {
|
|
4
|
+
const key = keys[i];
|
|
5
|
+
if (typeof key === 'string' && key.length > 0) {
|
|
4
6
|
if (config[key]) {
|
|
5
7
|
classList.add(key);
|
|
6
8
|
} else {
|
|
7
9
|
classList.remove(key);
|
|
8
10
|
}
|
|
9
11
|
}
|
|
10
|
-
}
|
|
12
|
+
}
|
|
11
13
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function classSetToString(classes) {
|
|
2
|
+
let string = '';
|
|
3
|
+
const keys = Object.keys(classes);
|
|
4
|
+
for (let i = 0, { length } = keys; i < length; i += 1) {
|
|
5
|
+
const key = keys[i];
|
|
6
|
+
if (classes[key]) {
|
|
7
|
+
string += (string.length ? ' ' : '') + key;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
return string;
|
|
11
|
+
}
|
|
@@ -43,15 +43,15 @@ export class EventEmitter {
|
|
|
43
43
|
@return {Boolean} - Returns `true` if the event had listeners, `false` otherwise
|
|
44
44
|
**/
|
|
45
45
|
emit(name) {
|
|
46
|
-
const args = Array.prototype.slice.call(arguments, 1);
|
|
47
46
|
const listeners = this.registry[name];
|
|
48
47
|
let count = 0;
|
|
49
48
|
|
|
50
49
|
if (listeners) {
|
|
51
|
-
|
|
50
|
+
const args = Array.prototype.slice.call(arguments, 1);
|
|
51
|
+
for (let i = 0, { length } = listeners; i < length; i += 1) {
|
|
52
52
|
count += 1;
|
|
53
|
-
|
|
54
|
-
}
|
|
53
|
+
listeners[i].apply(null, args);
|
|
54
|
+
}
|
|
55
55
|
}
|
|
56
56
|
return count > 0;
|
|
57
57
|
}
|
|
@@ -48,9 +48,11 @@ export function makeEverythingExceptElementInert(blockingElement) {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
export function restoreInertness(savedInertElements) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
for (let i = 0, { length } = savedInertElements; i < length; i += 1) {
|
|
52
|
+
const element = savedInertElements[i];
|
|
53
|
+
const { node } = element;
|
|
54
|
+
if (node) {
|
|
55
|
+
node.ariaHidden = element.ariaHidden;
|
|
54
56
|
}
|
|
55
|
-
}
|
|
57
|
+
}
|
|
56
58
|
}
|
|
@@ -18,6 +18,7 @@ export {
|
|
|
18
18
|
export { deepCopy, arraysEqual, ArraySlice } from './utility';
|
|
19
19
|
export { guid } from './guid';
|
|
20
20
|
export { classListMutation } from './classListMutation';
|
|
21
|
+
export { classSetToString } from './classSet';
|
|
21
22
|
export { makeEverythingExceptElementInert, restoreInertness } from './inert';
|
|
22
23
|
export { hasAnimation } from './animation';
|
|
23
24
|
export {
|
|
@@ -64,9 +65,10 @@ export function synchronizeAttrs(element, values) {
|
|
|
64
65
|
return;
|
|
65
66
|
}
|
|
66
67
|
const attributes = Object.keys(values);
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
for (let i = 0, { length } = attributes; i < length; i += 1) {
|
|
69
|
+
const attr = attributes[i];
|
|
70
|
+
smartSetAttribute(element, attr, values[attr]);
|
|
71
|
+
}
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
/**
|
|
@@ -100,12 +102,10 @@ export function reflectAttribute(element, attrName, value) {
|
|
|
100
102
|
* @returns {String} The DOM id or null
|
|
101
103
|
*/
|
|
102
104
|
export function getRealDOMId(el) {
|
|
103
|
-
if (
|
|
104
|
-
return el;
|
|
105
|
-
} else if (el) {
|
|
106
|
-
return el.getAttribute('id');
|
|
105
|
+
if (typeof el === 'string') {
|
|
106
|
+
return el.length > 0 ? el : null;
|
|
107
107
|
}
|
|
108
|
-
return null;
|
|
108
|
+
return typeof el === 'object' && el !== null ? el.getAttribute('id') : null;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
/**
|
|
@@ -281,3 +281,35 @@ export function isNativeComponent(cmp) {
|
|
|
281
281
|
export function isDesktopBrowser() {
|
|
282
282
|
return formFactor === 'Large';
|
|
283
283
|
}
|
|
284
|
+
|
|
285
|
+
const { hasOwn: ObjectHasOwn } = Object;
|
|
286
|
+
const { hasOwnProperty: ObjectProtoHasOwnProperty } = Object.prototype;
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Determines if a given object has the specified key as a direct property.
|
|
290
|
+
*
|
|
291
|
+
* @param {Object} object The object to check
|
|
292
|
+
* @param {string} key The property key
|
|
293
|
+
* @returns {Boolean} Whether the given key is a direct property of the object.
|
|
294
|
+
*/
|
|
295
|
+
export const hasOwn =
|
|
296
|
+
typeof ObjectHasOwn === 'function'
|
|
297
|
+
? ObjectHasOwn
|
|
298
|
+
: function hasOwn(object, key) {
|
|
299
|
+
return ObjectProtoHasOwnProperty.call(object, key);
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Determines if a given object has any direct properties.
|
|
304
|
+
*
|
|
305
|
+
* @param {Object} object The object to check
|
|
306
|
+
* @returns {Boolean} Whether the object has direct properties.
|
|
307
|
+
*/
|
|
308
|
+
export function hasOwnProperties(object) {
|
|
309
|
+
for (let key in object) {
|
|
310
|
+
if (hasOwn(object, key)) {
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return false;
|
|
315
|
+
}
|