lightning-base-components 1.18.6-alpha → 1.18.7-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 +5 -0
- package/package.json +10 -59
- package/scopedImports/@salesforce-label-LightningPill.delete.js +1 -1
- package/scopedImports/@salesforce-label-LightningPill.deleteAndNavigate.js +1 -1
- package/scopedImports/@salesforce-label-LightningPill.remove.js +1 -1
- package/scopedImports/@salesforce-label-LightningRecordPicker.dataSourceErrorMessage.js +1 -0
- package/scopedImports/@salesforce-label-LightningRecordPicker.invalidConfigurationErrorMessage.js +1 -0
- package/src/lightning/accordion/accordion.css +2 -2
- package/src/lightning/accordion/accordion.js +2 -4
- package/src/lightning/accordionSection/accordionSection.css +2 -2
- package/src/lightning/accordionSection/accordionSection.js +2 -4
- package/src/lightning/avatar/avatar.css +2 -2
- package/src/lightning/avatar/avatar.js +2 -3
- package/src/lightning/baseCombobox/baseCombobox.css +2 -2
- package/src/lightning/baseCombobox/baseCombobox.js +37 -85
- package/src/lightning/baseComboboxItem/baseComboboxItem.js +2 -4
- package/src/lightning/baseComboboxItem/inline.css +2 -2
- package/src/lightning/breadcrumb/breadcrumb.css +2 -2
- package/src/lightning/breadcrumb/breadcrumb.js +2 -4
- package/src/lightning/breadcrumbs/breadcrumbs.css +2 -2
- package/src/lightning/breadcrumbs/breadcrumbs.js +2 -3
- package/src/lightning/button/button.css +2 -2
- package/src/lightning/buttonGroup/buttonGroup.css +2 -2
- package/src/lightning/buttonGroup/buttonGroup.js +2 -3
- package/src/lightning/buttonIcon/buttonIcon.css +2 -2
- package/src/lightning/buttonIcon/buttonIcon.js +0 -1
- package/src/lightning/buttonIconStateful/buttonIconStateful.css +2 -2
- package/src/lightning/buttonMenu/buttonMenu.css +2 -2
- package/src/lightning/buttonMenu/buttonMenu.js +2 -4
- package/src/lightning/buttonStateful/buttonStateful.css +2 -2
- package/src/lightning/buttonStateful/buttonStateful.js +2 -3
- package/src/lightning/calendar/calendar.css +2 -2
- package/src/lightning/calendar/calendar.js +2 -4
- package/src/lightning/card/card.css +2 -2
- package/src/lightning/card/card.js +2 -3
- package/src/lightning/colorPickerCustom/colorPickerCustom.css +2 -2
- package/src/lightning/colorPickerCustom/colorPickerCustom.js +2 -3
- package/src/lightning/colorPickerPanel/colorPickerPanel.css +2 -2
- package/src/lightning/colorPickerPanel/colorPickerPanel.js +2 -4
- package/src/lightning/combobox/combobox.css +2 -2
- package/src/lightning/combobox/combobox.js +2 -4
- package/src/lightning/datepicker/datepicker.css +2 -2
- package/src/lightning/datepicker/datepicker.js +2 -4
- package/src/lightning/datetimepicker/datetimepicker.css +2 -2
- package/src/lightning/datetimepicker/datetimepicker.js +2 -4
- package/src/lightning/dualListbox/dualListbox.css +2 -2
- package/src/lightning/dualListbox/dualListbox.js +2 -4
- package/src/lightning/dynamicIcon/dynamicIcon.js +2 -3
- package/src/lightning/dynamicIcon/ellie.css +1 -1
- package/src/lightning/dynamicIcon/eq.css +1 -1
- package/src/lightning/dynamicIcon/score.css +1 -1
- package/src/lightning/dynamicIcon/strength.css +1 -1
- package/src/lightning/dynamicIcon/trend.css +1 -1
- package/src/lightning/dynamicIcon/waffle.css +1 -1
- package/src/lightning/f6Controller/f6Controller.js +1 -1
- package/src/lightning/formattedRichText/formattedRichText.css +2 -2
- package/src/lightning/formattedRichText/formattedRichText.js +2 -4
- package/src/lightning/formattedText/formattedText.css +1 -1
- package/src/lightning/formattedText/formattedText.js +2 -3
- package/src/lightning/helptext/helptext.css +2 -2
- package/src/lightning/helptext/helptext.js +2 -3
- package/src/lightning/icon/icon.css +2 -2
- package/src/lightning/icon/icon.js +3 -10
- package/src/lightning/input/__examples__/checkboxbutton/checkboxbutton.html +1 -2
- package/src/lightning/input/__examples__/checkboxbutton/checkboxbutton.js +1 -1
- package/src/lightning/input/__examples__/number/number.html +5 -0
- package/src/lightning/input/input.css +4 -2
- package/src/lightning/input/input.html +239 -149
- package/src/lightning/input/input.js +532 -209
- package/src/lightning/{inputUtils/number.js → input/numberUtil.js} +1 -1
- package/src/lightning/inputUtils/inputUtils.js +20 -15
- package/src/lightning/inputUtils/normalize.js +0 -7
- package/src/lightning/layout/layout.css +2 -2
- package/src/lightning/layout/layout.js +2 -6
- package/src/lightning/layoutItem/layoutItem.css +2 -2
- package/src/lightning/layoutItem/layoutItem.js +2 -6
- package/src/lightning/menuDivider/menuDivider.css +2 -2
- package/src/lightning/menuDivider/menuDivider.js +2 -4
- package/src/lightning/menuItem/menuItem.css +2 -2
- package/src/lightning/menuItem/menuItem.js +2 -4
- package/src/lightning/menuSubheader/menuSubheader.css +2 -2
- package/src/lightning/menuSubheader/menuSubheader.js +2 -4
- package/src/lightning/pill/link.css +2 -2
- package/src/lightning/pill/link.html +8 -7
- package/src/lightning/pill/pill.js +9 -6
- package/src/lightning/pill/plain.css +2 -2
- package/src/lightning/pill/plain.html +2 -2
- package/src/lightning/pill/plainLink.css +2 -2
- package/src/lightning/pill/plainLink.html +6 -6
- package/src/lightning/pillContainer/barePillContainer.css +2 -2
- package/src/lightning/pillContainer/pillContainer.js +2 -4
- package/src/lightning/pillContainer/standardPillContainer.css +2 -2
- package/src/lightning/popup/popup.css +2 -2
- package/src/lightning/popup/popup.js +2 -3
- package/src/lightning/primitiveBubble/primitiveBubble.css +2 -2
- package/src/lightning/primitiveBubble/primitiveBubble.js +2 -4
- package/src/lightning/primitiveButton/primitiveButton.js +2 -3
- package/src/lightning/primitiveColorpickerButton/primitiveColorpickerButton.css +2 -2
- package/src/lightning/primitiveColorpickerButton/primitiveColorpickerButton.js +2 -3
- package/src/lightning/primitiveIcon/primitiveIcon.css +2 -2
- package/src/lightning/primitiveIcon/primitiveIcon.js +2 -3
- package/src/lightning/radioGroup/radioGroup.css +3 -2
- package/src/lightning/radioGroup/radioGroup.js +2 -4
- package/src/lightning/routingService/routingService.js +2 -1
- package/src/lightning/select/select.css +2 -2
- package/src/lightning/select/select.js +2 -4
- package/src/lightning/select/select.js-meta.xml +2 -0
- package/src/lightning/spinner/spinner.css +2 -2
- package/src/lightning/spinner/spinner.js +5 -11
- package/src/lightning/tabBar/tabBar.css +2 -2
- package/src/lightning/tabBar/tabBar.js +2 -4
- package/src/lightning/timepicker/timepicker.css +2 -2
- package/src/lightning/timepicker/timepicker.js +2 -4
- package/src/lightning/toast/__docs__/toast.md +2 -2
- package/src/lightning/toast/toast.css +2 -2
- package/src/lightning/toast/toast.js +2 -4
- package/src/lightning/toastContainer/toastContainer.css +2 -2
- package/src/lightning/verticalNavigation/verticalNavigation.css +3 -2
- package/src/lightning/verticalNavigation/verticalNavigation.js +2 -3
- package/src/lightning/verticalNavigationSection/verticalNavigationSection.css +3 -2
- package/src/lightning/verticalNavigationSection/verticalNavigationSection.js +2 -3
- package/src/lightning/input/__examples__/checkboxbutton/checkboxbutton.css +0 -6
- package/src/lightning/inputUtils/utils.js +0 -18
- package/src/lightning/primitiveInputCheckbox/form-element.slds.css +0 -281
- package/src/lightning/primitiveInputCheckbox/primitiveInputCheckbox.css +0 -3
- package/src/lightning/primitiveInputCheckbox/primitiveInputCheckbox.html +0 -48
- package/src/lightning/primitiveInputCheckbox/primitiveInputCheckbox.js +0 -139
- package/src/lightning/primitiveInputCheckboxButton/form-element.slds.css +0 -281
- package/src/lightning/primitiveInputCheckboxButton/input-checkbox-button.slds.css +0 -126
- package/src/lightning/primitiveInputCheckboxButton/primitiveInputCheckboxButton.css +0 -6
- package/src/lightning/primitiveInputCheckboxButton/primitiveInputCheckboxButton.html +0 -24
- package/src/lightning/primitiveInputCheckboxButton/primitiveInputCheckboxButton.js +0 -176
- package/src/lightning/primitiveInputColor/form-element.slds.css +0 -281
- package/src/lightning/primitiveInputColor/input-color.slds.css +0 -35
- package/src/lightning/primitiveInputColor/primitiveInputColor.css +0 -4
- package/src/lightning/primitiveInputColor/primitiveInputColor.html +0 -50
- package/src/lightning/primitiveInputColor/primitiveInputColor.js +0 -184
- package/src/lightning/primitiveInputFile/button.slds.css +0 -527
- package/src/lightning/primitiveInputFile/form-element.slds.css +0 -281
- package/src/lightning/primitiveInputFile/input-file.slds.css +0 -62
- package/src/lightning/primitiveInputFile/primitiveInputFile.css +0 -5
- package/src/lightning/primitiveInputFile/primitiveInputFile.html +0 -45
- package/src/lightning/primitiveInputFile/primitiveInputFile.js +0 -111
- package/src/lightning/primitiveInputRadio/primitiveInputRadio.html +0 -24
- package/src/lightning/primitiveInputRadio/primitiveInputRadio.js +0 -103
- package/src/lightning/primitiveInputSimple/form-element.slds.css +0 -281
- package/src/lightning/primitiveInputSimple/input-text.slds.css +0 -398
- package/src/lightning/primitiveInputSimple/primitiveInputSimple.css +0 -9
- package/src/lightning/primitiveInputSimple/primitiveInputSimple.html +0 -65
- package/src/lightning/primitiveInputSimple/primitiveInputSimple.js +0 -585
- package/src/lightning/primitiveInputToggle/form-element.slds.css +0 -281
- package/src/lightning/primitiveInputToggle/input-toggle.slds.css +0 -170
- package/src/lightning/primitiveInputToggle/primitiveInputToggle.css +0 -3
- package/src/lightning/primitiveInputToggle/primitiveInputToggle.html +0 -34
- package/src/lightning/primitiveInputToggle/primitiveInputToggle.js +0 -164
- /package/src/lightning/{inputUtils/email.js → input/emailUtil.js} +0 -0
- /package/src/lightning/{primitiveInputCheckbox → input}/input-checkbox.slds.css +0 -0
- /package/src/lightning/{primitiveInputColor → input}/input-text.slds.css +0 -0
- /package/src/lightning/{primitiveInputSimple → input}/normalize.js +0 -0
- /package/src/lightning/{primitiveInputSimple → input}/selection.js +0 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import labelA11yTriggerText from '@salesforce/label/LightningColorPicker.a11yTriggerText';
|
|
2
|
+
import labelInputFileBodyText from '@salesforce/label/LightningInputFile.bodyText';
|
|
3
|
+
import labelInputFileButtonLabel from '@salesforce/label/LightningInputFile.buttonLabel';
|
|
2
4
|
import labelMessageToggleActive from '@salesforce/label/LightningControl.activeCapitalized';
|
|
3
5
|
import labelMessageToggleInactive from '@salesforce/label/LightningControl.inactiveCapitalized';
|
|
4
6
|
import labelRequired from '@salesforce/label/LightningControl.required';
|
|
@@ -11,17 +13,20 @@ import labelHelpTextAlternativeText from '@salesforce/label/LightningInput.helpt
|
|
|
11
13
|
import userTimeZone from '@salesforce/i18n/timeZone';
|
|
12
14
|
import formFactor from '@salesforce/client/formFactor';
|
|
13
15
|
|
|
14
|
-
import { api, track } from 'lwc';
|
|
15
|
-
import LightningShadowBaseClass from 'lightning/shadowBaseClassPrivate';
|
|
16
|
+
import { LightningElement, api, track } from 'lwc';
|
|
16
17
|
import { classSet, formatLabel } from 'lightning/utils';
|
|
17
18
|
import {
|
|
18
19
|
assert,
|
|
19
20
|
classListMutation,
|
|
21
|
+
getRealDOMId,
|
|
20
22
|
reflectAttribute,
|
|
23
|
+
isSafari,
|
|
21
24
|
isNativeComponent,
|
|
25
|
+
isNotUndefinedOrNull,
|
|
22
26
|
isUndefinedOrNull,
|
|
23
27
|
normalizeAriaAttribute,
|
|
24
28
|
normalizeBoolean,
|
|
29
|
+
normalizeKeyValue,
|
|
25
30
|
normalizeString,
|
|
26
31
|
synchronizeAttrs,
|
|
27
32
|
decorateInputForDragon,
|
|
@@ -29,6 +34,7 @@ import {
|
|
|
29
34
|
computeAriaInvalid,
|
|
30
35
|
} from 'lightning/utilsPrivate';
|
|
31
36
|
import AriaObserver from 'lightning/ariaObserver';
|
|
37
|
+
import { normalizeInput } from './normalize';
|
|
32
38
|
import {
|
|
33
39
|
normalizeDate,
|
|
34
40
|
normalizeDateTimeToUTC,
|
|
@@ -41,14 +47,26 @@ import {
|
|
|
41
47
|
InteractingState,
|
|
42
48
|
normalizeVariant,
|
|
43
49
|
VARIANT,
|
|
44
|
-
normalizeInput,
|
|
45
|
-
isValidNumber,
|
|
46
|
-
isValidEmail,
|
|
47
|
-
isValidMultipleEmails,
|
|
48
50
|
} from 'lightning/inputUtils';
|
|
51
|
+
import {
|
|
52
|
+
calculateFractionDigitsFromStep,
|
|
53
|
+
formatNumber,
|
|
54
|
+
fromIsoDecimal,
|
|
55
|
+
hasValidNumberShortcut,
|
|
56
|
+
hasValidNumberSymbol,
|
|
57
|
+
increaseNumberByStep,
|
|
58
|
+
isValidNumber,
|
|
59
|
+
isValidNumberCharacter,
|
|
60
|
+
stringifyNumber,
|
|
61
|
+
toIsoDecimal,
|
|
62
|
+
} from './numberUtil';
|
|
63
|
+
import { isValidEmail, isValidMultipleEmails } from './emailUtil';
|
|
64
|
+
import { InputSelectionCache } from './selection';
|
|
49
65
|
|
|
50
66
|
const i18n = {
|
|
51
67
|
a11yTriggerText: labelA11yTriggerText,
|
|
68
|
+
inputFileBodyText: labelInputFileBodyText,
|
|
69
|
+
inputFileButtonLabel: labelInputFileButtonLabel,
|
|
52
70
|
messageToggleActive: labelMessageToggleActive,
|
|
53
71
|
messageToggleInactive: labelMessageToggleInactive,
|
|
54
72
|
numberIncrementCounter: labelNumberIncrementCounter,
|
|
@@ -88,12 +106,13 @@ const VALID_NUMBER_FORMATTERS = [
|
|
|
88
106
|
'percent-fixed',
|
|
89
107
|
'currency',
|
|
90
108
|
];
|
|
109
|
+
const DEFAULT_COLOR = '#000000';
|
|
91
110
|
const DEFAULT_FORMATTER = VALID_NUMBER_FORMATTERS[0];
|
|
92
111
|
|
|
93
112
|
/**
|
|
94
113
|
* Represents interactive controls that accept user input depending on the type attribute.
|
|
95
114
|
*/
|
|
96
|
-
export default class LightningInput extends
|
|
115
|
+
export default class LightningInput extends LightningElement {
|
|
97
116
|
static delegatesFocus = true;
|
|
98
117
|
|
|
99
118
|
/**
|
|
@@ -282,12 +301,12 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
282
301
|
@track _ariaInvalid;
|
|
283
302
|
@track _autocomplete;
|
|
284
303
|
|
|
285
|
-
_shouldShowHelpMessage = true;
|
|
286
|
-
_helpMessageChanged = false;
|
|
287
304
|
_formatter = DEFAULT_FORMATTER;
|
|
288
305
|
_showRawNumber = false;
|
|
289
306
|
_initialValueSet = false;
|
|
307
|
+
_files = null;
|
|
290
308
|
_rendered;
|
|
309
|
+
_selectionCache;
|
|
291
310
|
|
|
292
311
|
constructor() {
|
|
293
312
|
super();
|
|
@@ -295,11 +314,15 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
295
314
|
|
|
296
315
|
// Native Shadow Root will return [native code].
|
|
297
316
|
// Our synthetic method will return the function source.
|
|
298
|
-
this.
|
|
317
|
+
this.isNative = isNativeComponent(this);
|
|
318
|
+
|
|
319
|
+
// The selection cache allows us an input to remember what text was selected
|
|
320
|
+
// in cases where we change the text on blur or in browsers (Safari) that
|
|
321
|
+
// don't track it properly.
|
|
322
|
+
this._selectionCache = new InputSelectionCache();
|
|
299
323
|
}
|
|
300
324
|
|
|
301
325
|
connectedCallback() {
|
|
302
|
-
super.connectedCallback();
|
|
303
326
|
if (!this.ariaObserver) {
|
|
304
327
|
this.ariaObserver = new AriaObserver(this);
|
|
305
328
|
}
|
|
@@ -311,11 +334,15 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
311
334
|
|
|
312
335
|
this.classList.add('slds-form-element');
|
|
313
336
|
|
|
314
|
-
this.
|
|
315
|
-
this.
|
|
337
|
+
this._updateClassList();
|
|
338
|
+
this._validateRequiredAttributes();
|
|
316
339
|
|
|
317
340
|
this.interactingState = new InteractingState();
|
|
318
341
|
this.interactingState.onleave(() => this.reportValidity());
|
|
342
|
+
|
|
343
|
+
if (this.isTypeNumber) {
|
|
344
|
+
this._updateNumberValue(this._value);
|
|
345
|
+
}
|
|
319
346
|
}
|
|
320
347
|
|
|
321
348
|
disconnectedCallback() {
|
|
@@ -329,15 +356,18 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
329
356
|
}
|
|
330
357
|
|
|
331
358
|
renderedCallback() {
|
|
359
|
+
// For W-7962838: In Safari, focus doesn't scroll input into view.
|
|
360
|
+
// Attach the event listener used to cache the selected text when selection changes.
|
|
361
|
+
if (isSafari) {
|
|
362
|
+
this._inputElement.addEventListener(
|
|
363
|
+
'select',
|
|
364
|
+
this.handleSelect.bind(this)
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
|
|
332
368
|
if (this.isConnected) {
|
|
333
369
|
this.ariaObserver.sync(this.isNativeShadow);
|
|
334
370
|
|
|
335
|
-
// If the help message changed, the help message element needs to be (un)related
|
|
336
|
-
if (this._helpMessageChanged) {
|
|
337
|
-
this.connectAriaDescribedBy();
|
|
338
|
-
this._helpMessageChanged = false;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
371
|
if (!this._rendered) {
|
|
342
372
|
this.connectAriaDescribedBy();
|
|
343
373
|
this.connectAriaLabelledBy();
|
|
@@ -348,6 +378,10 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
348
378
|
if (!this._initialValueSet && this._inputElement) {
|
|
349
379
|
this._rendered = true;
|
|
350
380
|
|
|
381
|
+
if (this.isTypeNumber) {
|
|
382
|
+
this._numberRawValue = fromIsoDecimal(this._value);
|
|
383
|
+
}
|
|
384
|
+
|
|
351
385
|
this._setInputValue(this._displayedValue);
|
|
352
386
|
if (this.isTypeCheckable) {
|
|
353
387
|
this._inputElement.checked = this._checked;
|
|
@@ -363,7 +397,17 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
363
397
|
* @type {number}
|
|
364
398
|
*
|
|
365
399
|
*/
|
|
366
|
-
@api
|
|
400
|
+
@api
|
|
401
|
+
get formatFractionDigits() {
|
|
402
|
+
return this._formatFractionDigits;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
set formatFractionDigits(value) {
|
|
406
|
+
this._formatFractionDigits = value;
|
|
407
|
+
if (this._rendered && this.isTypeNumber) {
|
|
408
|
+
this._setInputValue(this._displayedValue);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
367
411
|
|
|
368
412
|
/**
|
|
369
413
|
* A space-separated list of element IDs whose presence or content is controlled by the
|
|
@@ -607,22 +651,15 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
607
651
|
*/
|
|
608
652
|
@api
|
|
609
653
|
get formatter() {
|
|
610
|
-
// Formatters are applicable to the number type
|
|
611
|
-
// If the primitive exists, retrieve value from primitive-input-simple
|
|
612
|
-
if (this.isTypeNumber && this._primitiveComponent) {
|
|
613
|
-
return this._primitiveComponent.formatter;
|
|
614
|
-
}
|
|
615
654
|
return this._formatter;
|
|
616
655
|
}
|
|
617
656
|
|
|
618
657
|
set formatter(value) {
|
|
619
|
-
this._formatter = value
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
this._primitiveComponent.formatter = this._formatter;
|
|
625
|
-
}
|
|
658
|
+
this._formatter = normalizeString(value, {
|
|
659
|
+
fallbackValue: DEFAULT_FORMATTER,
|
|
660
|
+
validValues: VALID_NUMBER_FORMATTERS,
|
|
661
|
+
});
|
|
662
|
+
this._updateInputDisplayValueIfTypeNumber();
|
|
626
663
|
}
|
|
627
664
|
|
|
628
665
|
/**
|
|
@@ -806,6 +843,7 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
806
843
|
}
|
|
807
844
|
|
|
808
845
|
this._updateProxyInputAttributes('step');
|
|
846
|
+
this._updateInputDisplayValueIfTypeNumber();
|
|
809
847
|
}
|
|
810
848
|
|
|
811
849
|
/**
|
|
@@ -827,11 +865,7 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
827
865
|
this._checked = normalizeBoolean(value);
|
|
828
866
|
|
|
829
867
|
if (this._rendered) {
|
|
830
|
-
|
|
831
|
-
this._primitiveComponent.checked = this._checked;
|
|
832
|
-
} else {
|
|
833
|
-
this._inputElement.checked = this._checked;
|
|
834
|
-
}
|
|
868
|
+
this._inputElement.checked = this._checked;
|
|
835
869
|
}
|
|
836
870
|
|
|
837
871
|
// Update proxy input should be set after _inputElement is updated.
|
|
@@ -862,29 +896,29 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
862
896
|
*/
|
|
863
897
|
@api
|
|
864
898
|
get value() {
|
|
865
|
-
if (this.isTypeSimple) {
|
|
866
|
-
const subcomponent = this._primitiveComponent;
|
|
867
|
-
if (subcomponent) {
|
|
868
|
-
return subcomponent.value;
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
899
|
return this._value;
|
|
872
900
|
}
|
|
873
901
|
|
|
874
902
|
set value(value) {
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
903
|
+
const previousValue = this._value;
|
|
904
|
+
|
|
905
|
+
this._value = normalizeInput(value);
|
|
906
|
+
|
|
907
|
+
if (this._rendered && this.isTypeNumber) {
|
|
908
|
+
this._value = stringifyNumber(value);
|
|
909
|
+
// the extra check for whether the value has changed is done for cases
|
|
910
|
+
// when the same value is set back in a change handler, this is to avoid
|
|
911
|
+
// the raw number from changing formatting under the user
|
|
912
|
+
// (eg. if the user typed 1,000 we want to preserve that formatting as the user
|
|
913
|
+
// types the value)
|
|
914
|
+
if (this.validity.badInput || this._value !== previousValue) {
|
|
915
|
+
this._updateNumberValue(value);
|
|
884
916
|
}
|
|
917
|
+
}
|
|
885
918
|
|
|
886
|
-
|
|
887
|
-
|
|
919
|
+
this._updateProxyInputAttributes('value');
|
|
920
|
+
// Setting value of a type='file' isn't allowed
|
|
921
|
+
if (!this.isTypeFile) {
|
|
888
922
|
// Again, due to the interop layer we need to check whether the value being set
|
|
889
923
|
// is different, otherwise we're duplicating the sets on the input, which result
|
|
890
924
|
// in different bugs like Japanese IME duplication of characters in Safari (likely a browser bug) or
|
|
@@ -915,7 +949,7 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
915
949
|
|
|
916
950
|
set variant(value) {
|
|
917
951
|
this._variant = normalizeVariant(value);
|
|
918
|
-
this.
|
|
952
|
+
this._updateClassList();
|
|
919
953
|
reflectAttribute(this, 'variant', this._variant);
|
|
920
954
|
}
|
|
921
955
|
|
|
@@ -1019,7 +1053,7 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1019
1053
|
@api
|
|
1020
1054
|
get files() {
|
|
1021
1055
|
if (this.isTypeFile) {
|
|
1022
|
-
return this.
|
|
1056
|
+
return this._files;
|
|
1023
1057
|
}
|
|
1024
1058
|
return null;
|
|
1025
1059
|
}
|
|
@@ -1034,14 +1068,6 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1034
1068
|
return this._constraint.validity;
|
|
1035
1069
|
}
|
|
1036
1070
|
|
|
1037
|
-
/**
|
|
1038
|
-
* Not moving selectionStart and selectionEnd to the inner component. Looks like
|
|
1039
|
-
* one of the expected error/fail cases is that the component throws an error in the console,
|
|
1040
|
-
* if the user attempts to set it on a non-supported type (like range, file, checkbox).
|
|
1041
|
-
* That can only happen from `lightning-input`. To avoid duplicating code, it's best to keep
|
|
1042
|
-
* this here.
|
|
1043
|
-
*/
|
|
1044
|
-
|
|
1045
1071
|
/**
|
|
1046
1072
|
* Specifies the index of the first character to select in the input element.
|
|
1047
1073
|
* This attribute is supported only for text type.
|
|
@@ -1116,13 +1142,9 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1116
1142
|
}
|
|
1117
1143
|
if (this._rendered && !this.isNativeInput) {
|
|
1118
1144
|
this._inputElement.showHelpMessage(message);
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
if (this._rendered && this.isTypePrimitiveInput) {
|
|
1122
|
-
this._shouldShowHelpMessage = false;
|
|
1123
|
-
this._helpMessageChanged = true;
|
|
1145
|
+
} else {
|
|
1146
|
+
this._helpMessage = message;
|
|
1124
1147
|
}
|
|
1125
|
-
this._helpMessage = message;
|
|
1126
1148
|
});
|
|
1127
1149
|
}
|
|
1128
1150
|
|
|
@@ -1155,47 +1177,195 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1155
1177
|
}
|
|
1156
1178
|
}
|
|
1157
1179
|
|
|
1158
|
-
get
|
|
1159
|
-
|
|
1160
|
-
|
|
1180
|
+
get isNativeInput() {
|
|
1181
|
+
return !(
|
|
1182
|
+
this.isTypeDesktopDate ||
|
|
1183
|
+
this.isTypeDesktopDateTime ||
|
|
1184
|
+
this.isTypeDesktopTime
|
|
1185
|
+
);
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
get computedAriaLabel() {
|
|
1189
|
+
const ariaValues = [];
|
|
1190
|
+
|
|
1191
|
+
// merge all date & time arias on mobile since it's displayed as a single field
|
|
1192
|
+
if (this.isTypeMobileDateTime) {
|
|
1193
|
+
ariaValues.push(this.dateAriaLabel);
|
|
1194
|
+
ariaValues.push(this.timeAriaLabel);
|
|
1161
1195
|
}
|
|
1162
|
-
if (this.
|
|
1163
|
-
|
|
1196
|
+
if (this.ariaLabel) {
|
|
1197
|
+
ariaValues.push(this.ariaLabel);
|
|
1164
1198
|
}
|
|
1199
|
+
|
|
1200
|
+
return normalizeAriaAttribute(ariaValues);
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
get computedAriaLabelledBy() {
|
|
1204
|
+
const ariaValues = [];
|
|
1205
|
+
|
|
1206
|
+
if (this.isTypeFile) {
|
|
1207
|
+
ariaValues.push(this.computedUniqueFileElementLabelledById);
|
|
1208
|
+
}
|
|
1209
|
+
// merge all date & time arias on mobile since it's displayed as a single field
|
|
1210
|
+
if (this.isTypeMobileDateTime) {
|
|
1211
|
+
ariaValues.push(this.dateAriaLabelledBy);
|
|
1212
|
+
ariaValues.push(this.timeAriaLabelledBy);
|
|
1213
|
+
}
|
|
1214
|
+
if (this.ariaLabelledBy) {
|
|
1215
|
+
ariaValues.push(this.ariaLabelledBy);
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
return normalizeAriaAttribute(ariaValues);
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
get computedAriaDescribedBy() {
|
|
1222
|
+
const ariaValues = [];
|
|
1223
|
+
|
|
1224
|
+
if (this._helpMessage) {
|
|
1225
|
+
ariaValues.push(this.computedUniqueHelpElementId);
|
|
1226
|
+
}
|
|
1227
|
+
// The toggle type is described by a secondary element
|
|
1165
1228
|
if (this.isTypeToggle) {
|
|
1166
|
-
|
|
1229
|
+
ariaValues.push(this.computedUniqueToggleElementDescribedById);
|
|
1167
1230
|
}
|
|
1168
|
-
|
|
1169
|
-
|
|
1231
|
+
// merge all date & time arias on mobile since it's displayed as a single field
|
|
1232
|
+
if (this.isTypeMobileDateTime) {
|
|
1233
|
+
ariaValues.push(this.dateAriaDescribedBy);
|
|
1234
|
+
ariaValues.push(this.timeAriaDescribedBy);
|
|
1170
1235
|
}
|
|
1171
|
-
if (this.
|
|
1172
|
-
|
|
1236
|
+
if (this.ariaDescribedBy) {
|
|
1237
|
+
ariaValues.push(this.ariaDescribedBy);
|
|
1173
1238
|
}
|
|
1174
|
-
|
|
1175
|
-
|
|
1239
|
+
|
|
1240
|
+
return normalizeAriaAttribute(ariaValues);
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
get computedAriaInvalid() {
|
|
1244
|
+
// W-8796658: aria-invalid should always follow the visual indication of errors
|
|
1245
|
+
return computeAriaInvalid(
|
|
1246
|
+
this._helpMessage,
|
|
1247
|
+
this.value,
|
|
1248
|
+
this.ariaInvalid
|
|
1249
|
+
);
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
get isLabelHidden() {
|
|
1253
|
+
return this.variant === VARIANT.LABEL_HIDDEN;
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
get isLabelStacked() {
|
|
1257
|
+
return this.variant === VARIANT.LABEL_STACKED;
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
get accesskey() {
|
|
1261
|
+
return this._accesskey;
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
get colorInputElementValue() {
|
|
1265
|
+
return this.validity.valid && this.value ? this.value : DEFAULT_COLOR;
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
get colorInputStyle() {
|
|
1269
|
+
return `background: ${this.value || '#5679C0'};`;
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
get computedUniqueHelpElementId() {
|
|
1273
|
+
return getRealDOMId(this.template.querySelector('[data-help-message]'));
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
get computedUniqueToggleElementDescribedById() {
|
|
1277
|
+
if (this.isTypeToggle) {
|
|
1278
|
+
const toggle = this.template.querySelector(
|
|
1279
|
+
'[data-toggle-description]'
|
|
1280
|
+
);
|
|
1281
|
+
return getRealDOMId(toggle);
|
|
1176
1282
|
}
|
|
1283
|
+
return null;
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
get computedUniqueFormLabelId() {
|
|
1177
1287
|
if (this.isTypeFile) {
|
|
1178
|
-
|
|
1288
|
+
const formLabel = this.template.querySelector('[data-form-label]');
|
|
1289
|
+
return getRealDOMId(formLabel);
|
|
1179
1290
|
}
|
|
1180
1291
|
return null;
|
|
1181
1292
|
}
|
|
1182
1293
|
|
|
1183
|
-
get
|
|
1184
|
-
|
|
1294
|
+
get computedUniqueFileSelectorLabelId() {
|
|
1295
|
+
if (this.isTypeFile) {
|
|
1296
|
+
const fileBodyLabel = this.template.querySelector(
|
|
1297
|
+
'[data-file-selector-label]'
|
|
1298
|
+
);
|
|
1299
|
+
return getRealDOMId(fileBodyLabel);
|
|
1300
|
+
}
|
|
1301
|
+
return null;
|
|
1185
1302
|
}
|
|
1186
1303
|
|
|
1187
|
-
|
|
1304
|
+
get computedUniqueFileElementLabelledById() {
|
|
1305
|
+
if (this.isTypeFile) {
|
|
1306
|
+
const labelIds = [
|
|
1307
|
+
this.computedUniqueFormLabelId,
|
|
1308
|
+
this.computedUniqueFileSelectorLabelId,
|
|
1309
|
+
];
|
|
1310
|
+
return labelIds.join(' ');
|
|
1311
|
+
}
|
|
1312
|
+
return null;
|
|
1313
|
+
}
|
|
1188
1314
|
|
|
1189
|
-
get
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1315
|
+
get computedFormElementClass() {
|
|
1316
|
+
const classes = classSet('slds-form-element__control slds-grow');
|
|
1317
|
+
|
|
1318
|
+
if (this.isTypeSearch) {
|
|
1319
|
+
classes.add('slds-input-has-icon slds-input-has-icon_left-right');
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
return classes.toString();
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
get i18n() {
|
|
1326
|
+
return i18n;
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
get computedLabelClass() {
|
|
1330
|
+
const classnames = classSet('slds-form-element__label');
|
|
1331
|
+
if (this.isTypeCheckable || this.isTypeFile) {
|
|
1332
|
+
// do nothing
|
|
1333
|
+
} else if (this.isTypeToggle) {
|
|
1334
|
+
classnames.add('slds-m-bottom_none');
|
|
1335
|
+
} else {
|
|
1336
|
+
classnames.add('slds-no-flex');
|
|
1337
|
+
}
|
|
1338
|
+
return classnames
|
|
1339
|
+
.add({ 'slds-assistive-text': this.isLabelHidden })
|
|
1340
|
+
.toString();
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
get computedNumberClass() {
|
|
1344
|
+
return classSet('slds-input')
|
|
1345
|
+
.add({ 'slds-is-disabled': this.disabled })
|
|
1346
|
+
.toString();
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
get computedColorLabelClass() {
|
|
1350
|
+
return classSet(
|
|
1351
|
+
'slds-form-element__label slds-color-picker__summary-label'
|
|
1352
|
+
)
|
|
1353
|
+
.add({ 'slds-assistive-text': this.isLabelHidden })
|
|
1354
|
+
.toString();
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
get computedCheckboxClass() {
|
|
1358
|
+
return classSet('slds-checkbox')
|
|
1359
|
+
.add({ 'slds-checkbox_standalone': !this.isStandardVariant })
|
|
1360
|
+
.toString();
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1363
|
+
get normalizedMax() {
|
|
1364
|
+
return this._normalizeDateTimeString(this.max);
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
get normalizedMin() {
|
|
1368
|
+
return this._normalizeDateTimeString(this.min);
|
|
1199
1369
|
}
|
|
1200
1370
|
|
|
1201
1371
|
get isTypeNumber() {
|
|
@@ -1224,6 +1394,10 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1224
1394
|
);
|
|
1225
1395
|
}
|
|
1226
1396
|
|
|
1397
|
+
get isTypeSearch() {
|
|
1398
|
+
return this.type === 'search';
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1227
1401
|
get isTypeToggle() {
|
|
1228
1402
|
return this.type === 'toggle';
|
|
1229
1403
|
}
|
|
@@ -1302,85 +1476,6 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1302
1476
|
);
|
|
1303
1477
|
}
|
|
1304
1478
|
|
|
1305
|
-
get isNativeInput() {
|
|
1306
|
-
return !(
|
|
1307
|
-
this.isTypeDesktopDate ||
|
|
1308
|
-
this.isTypeDesktopDateTime ||
|
|
1309
|
-
this.isTypeDesktopTime
|
|
1310
|
-
);
|
|
1311
|
-
}
|
|
1312
|
-
|
|
1313
|
-
get _primitiveComponent() {
|
|
1314
|
-
return this.template.querySelector(this.primitiveSelector);
|
|
1315
|
-
}
|
|
1316
|
-
/************************* GETTERS *************************/
|
|
1317
|
-
|
|
1318
|
-
/*** Accessibility ***/
|
|
1319
|
-
|
|
1320
|
-
get computedAriaLabel() {
|
|
1321
|
-
const ariaValues = [];
|
|
1322
|
-
|
|
1323
|
-
// merge all date & time arias on mobile since it's displayed as a single field
|
|
1324
|
-
if (this.isTypeMobileDateTime) {
|
|
1325
|
-
ariaValues.push(this.dateAriaLabel);
|
|
1326
|
-
ariaValues.push(this.timeAriaLabel);
|
|
1327
|
-
}
|
|
1328
|
-
if (this.ariaLabel) {
|
|
1329
|
-
ariaValues.push(this.ariaLabel);
|
|
1330
|
-
}
|
|
1331
|
-
|
|
1332
|
-
return normalizeAriaAttribute(ariaValues);
|
|
1333
|
-
}
|
|
1334
|
-
|
|
1335
|
-
get computedAriaInvalid() {
|
|
1336
|
-
// W-8796658: aria-invalid should always follow the visual indication of errors
|
|
1337
|
-
return computeAriaInvalid(
|
|
1338
|
-
this._helpMessage,
|
|
1339
|
-
this.value,
|
|
1340
|
-
this.ariaInvalid
|
|
1341
|
-
);
|
|
1342
|
-
}
|
|
1343
|
-
|
|
1344
|
-
/****** ******/
|
|
1345
|
-
|
|
1346
|
-
get isLabelHidden() {
|
|
1347
|
-
return this.variant === VARIANT.LABEL_HIDDEN;
|
|
1348
|
-
}
|
|
1349
|
-
|
|
1350
|
-
get isLabelStacked() {
|
|
1351
|
-
return this.variant === VARIANT.LABEL_STACKED;
|
|
1352
|
-
}
|
|
1353
|
-
|
|
1354
|
-
get accesskey() {
|
|
1355
|
-
return this._accesskey;
|
|
1356
|
-
}
|
|
1357
|
-
|
|
1358
|
-
get i18n() {
|
|
1359
|
-
return i18n;
|
|
1360
|
-
}
|
|
1361
|
-
|
|
1362
|
-
get computedLabelClass() {
|
|
1363
|
-
const classnames = classSet('slds-form-element__label');
|
|
1364
|
-
if (this.isTypeCheckable || this.isTypeFile) {
|
|
1365
|
-
// do nothing
|
|
1366
|
-
} else if (this.isTypeToggle) {
|
|
1367
|
-
classnames.add('slds-m-bottom_none');
|
|
1368
|
-
} else {
|
|
1369
|
-
classnames.add('slds-no-flex');
|
|
1370
|
-
}
|
|
1371
|
-
return classnames
|
|
1372
|
-
.add({ 'slds-assistive-text': this.isLabelHidden })
|
|
1373
|
-
.toString();
|
|
1374
|
-
}
|
|
1375
|
-
|
|
1376
|
-
get normalizedMax() {
|
|
1377
|
-
return this._normalizeDateTimeString(this.max);
|
|
1378
|
-
}
|
|
1379
|
-
|
|
1380
|
-
get normalizedMin() {
|
|
1381
|
-
return this._normalizeDateTimeString(this.min);
|
|
1382
|
-
}
|
|
1383
|
-
|
|
1384
1479
|
get _inputElement() {
|
|
1385
1480
|
if (!this._cachedInputElement || this._inputElementRefreshNeeded) {
|
|
1386
1481
|
this._inputDragonDecorated = false;
|
|
@@ -1397,8 +1492,6 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1397
1492
|
inputElement = this.template.querySelector(
|
|
1398
1493
|
'lightning-timepicker'
|
|
1399
1494
|
);
|
|
1400
|
-
} else if (this.isTypePrimitiveInput) {
|
|
1401
|
-
inputElement = this._primitiveComponent.inputElement;
|
|
1402
1495
|
} else {
|
|
1403
1496
|
inputElement = this.template.querySelector('input');
|
|
1404
1497
|
this._inputDragonDecorated = true;
|
|
@@ -1437,8 +1530,34 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1437
1530
|
|
|
1438
1531
|
get _displayedValue() {
|
|
1439
1532
|
if (this.isTypeNumber) {
|
|
1440
|
-
|
|
1441
|
-
|
|
1533
|
+
// When only a symbol is entered by the user, set the display value as the user's input.
|
|
1534
|
+
// This will not affect the value dispatched by input via the change event, as it only dispatches a valid decimal number.
|
|
1535
|
+
// Due to the above, in integrations like input-field, the user's initial input of a symbol
|
|
1536
|
+
// like a minus sign will not be overwritten by an empty string value.
|
|
1537
|
+
// See description in PR for more details: https://github.com/salesforce-experience-platform/lightning-components/pull/3843
|
|
1538
|
+
if (
|
|
1539
|
+
this._inputElement.value.length === 1 &&
|
|
1540
|
+
hasValidNumberSymbol(this._inputElement.value)
|
|
1541
|
+
) {
|
|
1542
|
+
return this._inputElement.value;
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
// If the number is not valid (bad input, step mismatch, etc.) show the raw number as
|
|
1546
|
+
// well, otherwise the formatted value ends up being 'NaN' which makes it hard to
|
|
1547
|
+
// see mistakes
|
|
1548
|
+
if (this._showRawNumber || !this.validity.valid) {
|
|
1549
|
+
if (
|
|
1550
|
+
hasValidNumberShortcut(this._numberRawValue) &&
|
|
1551
|
+
isValidNumber(this._numberRawValue)
|
|
1552
|
+
) {
|
|
1553
|
+
this._numberRawValue = fromIsoDecimal(this._value);
|
|
1554
|
+
}
|
|
1555
|
+
return this._numberRawValue;
|
|
1556
|
+
}
|
|
1557
|
+
return formatNumber(
|
|
1558
|
+
this._value,
|
|
1559
|
+
this._buildFormatNumberOptions(this.formatter)
|
|
1560
|
+
);
|
|
1442
1561
|
}
|
|
1443
1562
|
|
|
1444
1563
|
if (
|
|
@@ -1452,6 +1571,18 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1452
1571
|
return this._value;
|
|
1453
1572
|
}
|
|
1454
1573
|
|
|
1574
|
+
/**
|
|
1575
|
+
* Gets the value for the actual 'type' attribute on the input element.
|
|
1576
|
+
*/
|
|
1577
|
+
get _internalType() {
|
|
1578
|
+
// Maps number->text to support shorthand input strings like '1k'.
|
|
1579
|
+
if (this.isTypeNumber || this.isTypeEmail) {
|
|
1580
|
+
return 'text';
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
return this._type;
|
|
1584
|
+
}
|
|
1585
|
+
|
|
1455
1586
|
get isStandardVariant() {
|
|
1456
1587
|
return (
|
|
1457
1588
|
this.variant === VARIANT.STANDARD ||
|
|
@@ -1459,14 +1590,34 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1459
1590
|
);
|
|
1460
1591
|
}
|
|
1461
1592
|
|
|
1593
|
+
get _showClearButton() {
|
|
1594
|
+
return (
|
|
1595
|
+
this.isTypeSearch &&
|
|
1596
|
+
isNotUndefinedOrNull(this._value) &&
|
|
1597
|
+
this._value !== ''
|
|
1598
|
+
);
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1462
1601
|
get _ignoreRequired() {
|
|
1463
1602
|
// If uploading via the drop zone or via the input directly, we should
|
|
1464
1603
|
// ignore the required flag as a file has been uploaded
|
|
1465
1604
|
return (
|
|
1466
|
-
this.isTypeFile &&
|
|
1605
|
+
this.isTypeFile &&
|
|
1606
|
+
this._required &&
|
|
1607
|
+
(this.fileUploadedViaDroppableZone ||
|
|
1608
|
+
(this._files && this._files.length > 0))
|
|
1467
1609
|
);
|
|
1468
1610
|
}
|
|
1469
1611
|
|
|
1612
|
+
get _inputMode() {
|
|
1613
|
+
if (this.isTypeNumber) {
|
|
1614
|
+
return 'decimal';
|
|
1615
|
+
} else if (this.isTypeEmail) {
|
|
1616
|
+
return 'email';
|
|
1617
|
+
}
|
|
1618
|
+
return null;
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1470
1621
|
get _constraint() {
|
|
1471
1622
|
if (!this._constraintApi) {
|
|
1472
1623
|
const overrides = {
|
|
@@ -1610,6 +1761,37 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1610
1761
|
return this.template.host.getRootNode();
|
|
1611
1762
|
}
|
|
1612
1763
|
|
|
1764
|
+
handleFileClick() {
|
|
1765
|
+
this._setInputValue(null);
|
|
1766
|
+
this._updateValueAndValidityAttribute(null);
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
handleDropFiles(event) {
|
|
1770
|
+
// drop doesn't trigger focus nor blur, so set state to interacting
|
|
1771
|
+
// and auto leave when there's no more action
|
|
1772
|
+
this.interactingState.interacting();
|
|
1773
|
+
|
|
1774
|
+
this.fileUploadedViaDroppableZone = true;
|
|
1775
|
+
this._files = event.dataTransfer && event.dataTransfer.files;
|
|
1776
|
+
|
|
1777
|
+
this._updateProxyInputAttributes('required');
|
|
1778
|
+
|
|
1779
|
+
this._dispatchChangeEventWithDetail({
|
|
1780
|
+
files: this._files,
|
|
1781
|
+
});
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
/**
|
|
1785
|
+
* Handle text selection.
|
|
1786
|
+
* Dynamically bound to the select event by `renderedCallback`.
|
|
1787
|
+
* This allows us to cache text selection in Safari, which doesn't preserve selection.
|
|
1788
|
+
*/
|
|
1789
|
+
handleSelect() {
|
|
1790
|
+
if (isSafari) {
|
|
1791
|
+
this._selectionCache.preserve(this._inputElement);
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1613
1795
|
handleFocus() {
|
|
1614
1796
|
this.interactingState.enter();
|
|
1615
1797
|
|
|
@@ -1617,11 +1799,24 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1617
1799
|
this._isColorPickerPanelOpen = false;
|
|
1618
1800
|
}
|
|
1619
1801
|
|
|
1802
|
+
// Focusing a number input causes the value displayed to be modified.
|
|
1803
|
+
// Changing the value resets selection, so we save and restore selection.
|
|
1804
|
+
if (this._rendered && this.isTypeNumber) {
|
|
1805
|
+
this._showRawNumber = true;
|
|
1806
|
+
this._selectionCache.preserve(this._inputElement);
|
|
1807
|
+
this._inputElement.value = this._displayedValue;
|
|
1808
|
+
this._selectionCache.restore(this._inputElement);
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1620
1811
|
this.dispatchEvent(new CustomEvent('focus'));
|
|
1621
1812
|
}
|
|
1622
1813
|
|
|
1623
1814
|
handleBlur(event) {
|
|
1624
1815
|
this.interactingState.leave();
|
|
1816
|
+
if (this._rendered && this.isTypeNumber) {
|
|
1817
|
+
this._showRawNumber = false;
|
|
1818
|
+
this._setInputValue(this._displayedValue);
|
|
1819
|
+
}
|
|
1625
1820
|
|
|
1626
1821
|
if (
|
|
1627
1822
|
!event.relatedTarget ||
|
|
@@ -1639,34 +1834,87 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1639
1834
|
|
|
1640
1835
|
handleChange(event) {
|
|
1641
1836
|
event.stopPropagation();
|
|
1837
|
+
|
|
1642
1838
|
this._dispatchCommitEvent();
|
|
1839
|
+
|
|
1840
|
+
if (this.isTypeSimple && this.value === event.target.value) {
|
|
1841
|
+
return;
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1643
1844
|
this._dispatchChangeEvent();
|
|
1644
1845
|
}
|
|
1645
1846
|
|
|
1646
|
-
|
|
1647
|
-
|
|
1847
|
+
handleInput(event) {
|
|
1848
|
+
event.stopPropagation();
|
|
1849
|
+
|
|
1850
|
+
if (this.isTypeNumber) {
|
|
1851
|
+
// for invalid numbers the value might stay the same as the user
|
|
1852
|
+
// changed the invalid input, so we need to update the raw value
|
|
1853
|
+
this._numberRawValue = this._inputElement.value;
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1856
|
+
if (this.isTypeSimple && this.value === event.target.value) {
|
|
1857
|
+
return;
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1860
|
+
this._dispatchChangeEvent();
|
|
1648
1861
|
}
|
|
1649
1862
|
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1863
|
+
handleKeyDown(event) {
|
|
1864
|
+
if (this.isTypeNumber) {
|
|
1865
|
+
// we're letting "Shift" through to prevent capital letters, other special symbols for type="number"
|
|
1866
|
+
const hasMetaOrCtrlModifier = event.metaKey || event.ctrlKey;
|
|
1867
|
+
// need to check that event.key is valid for "autofill" cases
|
|
1868
|
+
if (!hasMetaOrCtrlModifier && !this.readOnly && event.key) {
|
|
1869
|
+
const key = normalizeKeyValue(event.key);
|
|
1870
|
+
|
|
1871
|
+
if (key.length === 1 && !isValidNumberCharacter(key)) {
|
|
1872
|
+
event.preventDefault();
|
|
1873
|
+
}
|
|
1657
1874
|
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1875
|
+
if (key === 'ArrowUp') {
|
|
1876
|
+
event.preventDefault();
|
|
1877
|
+
this._numberStepUpAndDispatchEvents(1);
|
|
1878
|
+
} else if (key === 'ArrowDown') {
|
|
1879
|
+
event.preventDefault();
|
|
1880
|
+
this._numberStepUpAndDispatchEvents(-1);
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1885
|
+
|
|
1886
|
+
handleColorChange(event) {
|
|
1887
|
+
const selectedColor = event.detail.color;
|
|
1888
|
+
if (selectedColor !== this._inputElement.value) {
|
|
1889
|
+
this._setInputValue(selectedColor);
|
|
1890
|
+
this._updateValueAndValidityAttribute(selectedColor);
|
|
1891
|
+
this.focus();
|
|
1892
|
+
this._dispatchChangeEventWithDetail({ value: selectedColor });
|
|
1893
|
+
this._dispatchCommitEvent();
|
|
1894
|
+
}
|
|
1895
|
+
this.template
|
|
1896
|
+
.querySelector('lightning-primitive-colorpicker-button')
|
|
1897
|
+
.focus();
|
|
1665
1898
|
}
|
|
1666
1899
|
|
|
1667
|
-
|
|
1900
|
+
_clearAndSetFocusOnInput(event) {
|
|
1901
|
+
// TODO: Discuss this, it seems the wrong thing to do.
|
|
1902
|
+
// button is removed from template, but
|
|
1903
|
+
// event still is propagated, For example, captured by panel,
|
|
1904
|
+
// then cause panel think is clicked outside.
|
|
1905
|
+
event.stopPropagation();
|
|
1906
|
+
|
|
1668
1907
|
this.interactingState.enter();
|
|
1669
|
-
this.
|
|
1908
|
+
this._setInputValue('');
|
|
1909
|
+
this._updateValueAndValidityAttribute('');
|
|
1910
|
+
|
|
1911
|
+
this._inputElement.focus();
|
|
1912
|
+
|
|
1913
|
+
this._dispatchChangeEventWithDetail({
|
|
1914
|
+
value: this._value,
|
|
1915
|
+
});
|
|
1916
|
+
|
|
1917
|
+
this._dispatchCommitEvent();
|
|
1670
1918
|
}
|
|
1671
1919
|
|
|
1672
1920
|
_dispatchCommitEvent() {
|
|
@@ -1703,11 +1951,7 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1703
1951
|
}
|
|
1704
1952
|
}
|
|
1705
1953
|
|
|
1706
|
-
|
|
1707
|
-
* Label is a required attribute.
|
|
1708
|
-
* Throw error if an invalid value is passed to the label attribute
|
|
1709
|
-
*/
|
|
1710
|
-
validateRequiredAttributes() {
|
|
1954
|
+
_validateRequiredAttributes() {
|
|
1711
1955
|
const { label } = this;
|
|
1712
1956
|
assert(
|
|
1713
1957
|
typeof label === 'string' && label.length,
|
|
@@ -1729,8 +1973,6 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1729
1973
|
}
|
|
1730
1974
|
|
|
1731
1975
|
_dispatchChangeEvent() {
|
|
1732
|
-
// TODO: investigate removing this in a future update
|
|
1733
|
-
// possibly phase out the interactingState entirely
|
|
1734
1976
|
this.interactingState.enter();
|
|
1735
1977
|
|
|
1736
1978
|
const detail = {};
|
|
@@ -1738,10 +1980,20 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1738
1980
|
if (this.isTypeCheckable) {
|
|
1739
1981
|
this._updateCheckedAndValidityAttribute(this._inputElement.checked);
|
|
1740
1982
|
detail.checked = this._checked;
|
|
1983
|
+
} else if (this.isTypeFile) {
|
|
1984
|
+
this._files = this._inputElement.files;
|
|
1985
|
+
|
|
1986
|
+
// LWC does not proxy dom elements any more. So there is no need to call lwc.unwrap here anymore
|
|
1987
|
+
detail.files = this._files;
|
|
1988
|
+
|
|
1989
|
+
this._updateProxyInputAttributes('required');
|
|
1741
1990
|
}
|
|
1742
1991
|
|
|
1743
1992
|
if (!this.isTypeCheckable) {
|
|
1744
|
-
if (
|
|
1993
|
+
if (this.isTypeNumber) {
|
|
1994
|
+
this._numberRawValue = this._inputElement.value;
|
|
1995
|
+
detail.value = toIsoDecimal(this._inputElement.value);
|
|
1996
|
+
} else {
|
|
1745
1997
|
detail.value = this._inputElement.value;
|
|
1746
1998
|
}
|
|
1747
1999
|
|
|
@@ -1795,9 +2047,36 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1795
2047
|
}
|
|
1796
2048
|
|
|
1797
2049
|
/**
|
|
1798
|
-
*
|
|
2050
|
+
* Increases (if increment is positive, decreases otherwise) the number value of the input by the increment
|
|
2051
|
+
* multiple of the given 'step'. Additionally dispatches the 'change' and 'commit' events.
|
|
2052
|
+
*
|
|
2053
|
+
* @param {Number} increment A multiple of the step to increase, when step is 'any',
|
|
2054
|
+
* the step is assumed to be 1.
|
|
2055
|
+
* @private
|
|
1799
2056
|
*/
|
|
1800
|
-
|
|
2057
|
+
_numberStepUpAndDispatchEvents(increment) {
|
|
2058
|
+
if (this._readOnly || this._disabled) {
|
|
2059
|
+
return;
|
|
2060
|
+
}
|
|
2061
|
+
this._value = increaseNumberByStep({
|
|
2062
|
+
value: this._value,
|
|
2063
|
+
step: this.step,
|
|
2064
|
+
increment,
|
|
2065
|
+
fractionDigits: this._buildFormatNumberOptions(this.formatter)
|
|
2066
|
+
.minimumFractionDigits,
|
|
2067
|
+
});
|
|
2068
|
+
|
|
2069
|
+
// Raw value is the value the user entered (we preserve a user's input),
|
|
2070
|
+
// since we're generating a new value we're overriding it
|
|
2071
|
+
this._numberRawValue = fromIsoDecimal(this._value);
|
|
2072
|
+
|
|
2073
|
+
this._setInputValue(this._displayedValue);
|
|
2074
|
+
|
|
2075
|
+
this._dispatchChangeEvent();
|
|
2076
|
+
this._dispatchCommitEvent();
|
|
2077
|
+
}
|
|
2078
|
+
|
|
2079
|
+
_updateClassList() {
|
|
1801
2080
|
classListMutation(this.classList, {
|
|
1802
2081
|
'slds-form-element_stacked': this.variant === VARIANT.LABEL_STACKED,
|
|
1803
2082
|
'slds-form-element_horizontal':
|
|
@@ -1805,6 +2084,39 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1805
2084
|
});
|
|
1806
2085
|
}
|
|
1807
2086
|
|
|
2087
|
+
_updateNumberValue(value) {
|
|
2088
|
+
const newValue = stringifyNumber(value);
|
|
2089
|
+
this._value = newValue;
|
|
2090
|
+
this._numberRawValue = fromIsoDecimal(newValue);
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2093
|
+
_buildFormatNumberOptions(formatter) {
|
|
2094
|
+
const options = {
|
|
2095
|
+
style: formatter,
|
|
2096
|
+
};
|
|
2097
|
+
// Use the min/max fraction digits from the formatFractionDigits provided by the user if available.
|
|
2098
|
+
// Otherwise, use the number of digits calculated from step
|
|
2099
|
+
if (this._formatFractionDigits !== undefined) {
|
|
2100
|
+
options.minimumFractionDigits = this._formatFractionDigits;
|
|
2101
|
+
options.maximumFractionDigits = this._formatFractionDigits;
|
|
2102
|
+
} else {
|
|
2103
|
+
let digitsFromStep = calculateFractionDigitsFromStep(this._step);
|
|
2104
|
+
// if formatting percentages, when calculating digits from step, take into
|
|
2105
|
+
// consideration that the formatted number is effectively multiplied by 10^2, ie. 0.1 is 10%
|
|
2106
|
+
// so we need to subtract 2 digits;
|
|
2107
|
+
if (formatter === 'percent' && typeof digitsFromStep === 'number') {
|
|
2108
|
+
digitsFromStep -= 2;
|
|
2109
|
+
if (digitsFromStep < 0) {
|
|
2110
|
+
digitsFromStep = 0;
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
|
|
2114
|
+
options.minimumFractionDigits = digitsFromStep;
|
|
2115
|
+
options.maximumFractionDigits = digitsFromStep;
|
|
2116
|
+
}
|
|
2117
|
+
return options;
|
|
2118
|
+
}
|
|
2119
|
+
|
|
1808
2120
|
_normalizeDateTimeString(value) {
|
|
1809
2121
|
let result = value;
|
|
1810
2122
|
if (this.isTypeDate) {
|
|
@@ -1817,6 +2129,14 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1817
2129
|
return result;
|
|
1818
2130
|
}
|
|
1819
2131
|
|
|
2132
|
+
_updateInputA11y(elem) {
|
|
2133
|
+
synchronizeAttrs(elem, {
|
|
2134
|
+
[ARIA_LABELLEDBY]: this.computedAriaLabelledBy,
|
|
2135
|
+
[ARIA_DESCRIBEDBY]: this.computedAriaDescribedBy,
|
|
2136
|
+
[ARIA_LABEL]: this.computedAriaLabel,
|
|
2137
|
+
});
|
|
2138
|
+
}
|
|
2139
|
+
|
|
1820
2140
|
_updateDateOrTimePickerA11y(elem) {
|
|
1821
2141
|
synchronizeAttrs(elem, {
|
|
1822
2142
|
ariaLabelledByElement: this._ariaLabelledBy,
|
|
@@ -1844,6 +2164,7 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1844
2164
|
_synchronizeA11y() {
|
|
1845
2165
|
// each of these templates are mutually exclusive and are selected
|
|
1846
2166
|
// depending on the [type] of input.
|
|
2167
|
+
const input = this.template.querySelector('input');
|
|
1847
2168
|
const datepicker = this.template.querySelector('lightning-datepicker');
|
|
1848
2169
|
const timepicker = this.template.querySelector('lightning-timepicker');
|
|
1849
2170
|
const datetimepicker = this.template.querySelector(
|
|
@@ -1851,7 +2172,9 @@ export default class LightningInput extends LightningShadowBaseClass {
|
|
|
1851
2172
|
);
|
|
1852
2173
|
// determine which template type is present,
|
|
1853
2174
|
// and update a11y props accordingly
|
|
1854
|
-
if (
|
|
2175
|
+
if (input) {
|
|
2176
|
+
this._updateInputA11y(input);
|
|
2177
|
+
} else if (datepicker) {
|
|
1855
2178
|
this._updateDateOrTimePickerA11y(datepicker);
|
|
1856
2179
|
} else if (timepicker) {
|
|
1857
2180
|
this._updateDateOrTimePickerA11y(timepicker);
|