lightning-base-components 1.18.1-alpha → 1.18.3-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (298) hide show
  1. package/metadata/raptor.json +9 -0
  2. package/package.json +57 -1
  3. package/src/lightning/accordion/__docs__/accordion.md +2 -2
  4. package/src/lightning/accordion/accordion.css +12 -0
  5. package/src/lightning/accordion/accordion.html +3 -1
  6. package/src/lightning/accordion/accordion.js +4 -2
  7. package/src/lightning/accordion/accordion.slds.css +671 -0
  8. package/src/lightning/accordionSection/accordion-section.slds.css +647 -0
  9. package/src/lightning/accordionSection/accordionSection.css +14 -0
  10. package/src/lightning/accordionSection/accordionSection.html +23 -19
  11. package/src/lightning/accordionSection/accordionSection.js +29 -2
  12. package/src/lightning/ariaObserver/__docs__/ariaObserver.md +21 -9
  13. package/src/lightning/ariaObserver/ariaObserver.js +185 -154
  14. package/src/lightning/ariaObserver/polyfill.js +639 -0
  15. package/src/lightning/avatar/__docs__/avatar.md +7 -7
  16. package/src/lightning/avatar/avatar.css +2 -0
  17. package/src/lightning/avatar/avatar.html +2 -0
  18. package/src/lightning/avatar/avatar.js +18 -15
  19. package/src/lightning/avatar/avatar.slds.css +272 -0
  20. package/src/lightning/badge/__docs__/badge.md +2 -2
  21. package/src/lightning/baseCombobox/base-combobox.slds.css +1585 -0
  22. package/src/lightning/baseCombobox/baseCombobox.css +11 -1
  23. package/src/lightning/baseCombobox/baseCombobox.html +154 -146
  24. package/src/lightning/baseCombobox/baseCombobox.js +122 -46
  25. package/src/lightning/baseCombobox/spinner.slds.css +438 -0
  26. package/src/lightning/baseComboboxItem/baseComboboxItem.js +4 -2
  27. package/src/lightning/baseComboboxItem/inline.css +2 -0
  28. package/src/lightning/breadcrumb/breadcrumb.css +2 -2
  29. package/src/lightning/breadcrumb/breadcrumb.js +4 -2
  30. package/src/lightning/breadcrumb/breadcrumb.slds.css +2 -7
  31. package/src/lightning/breadcrumbs/__docs__/breadcrumbs.md +3 -3
  32. package/src/lightning/breadcrumbs/breadcrumbs.css +2 -2
  33. package/src/lightning/breadcrumbs/breadcrumbs.js +3 -2
  34. package/src/lightning/breadcrumbs/breadcrumbs.slds.css +7 -1
  35. package/src/lightning/button/__docs__/button.md +15 -15
  36. package/src/lightning/button/__examples__/inverse/inverse.css +8 -0
  37. package/src/lightning/button/__examples__/inverse/inverse.html +3 -2
  38. package/src/lightning/button/button.css +2 -0
  39. package/src/lightning/button/button.html +4 -2
  40. package/src/lightning/button/button.js +21 -0
  41. package/src/lightning/button/button.slds.css +527 -0
  42. package/src/lightning/buttonGroup/buttonGroup.css +2 -2
  43. package/src/lightning/buttonGroup/buttonGroup.js +3 -2
  44. package/src/lightning/buttonIcon/__docs__/buttonIcon.md +9 -9
  45. package/src/lightning/buttonIcon/button-icon.slds.css +215 -453
  46. package/src/lightning/buttonIcon/buttonIcon.css +2 -2
  47. package/src/lightning/buttonIcon/buttonIcon.js +4 -0
  48. package/src/lightning/buttonIconStateful/__docs__/buttonIconStateful.md +9 -9
  49. package/src/lightning/buttonIconStateful/button-icon-stateful.slds.css +215 -453
  50. package/src/lightning/buttonIconStateful/buttonIconStateful.css +2 -2
  51. package/src/lightning/buttonMenu/__docs__/buttonMenu.md +8 -8
  52. package/src/lightning/buttonMenu/{dropdown.slds.css → button-menu.slds.css} +853 -217
  53. package/src/lightning/buttonMenu/buttonMenu.css +2 -2
  54. package/src/lightning/buttonMenu/buttonMenu.html +2 -2
  55. package/src/lightning/buttonMenu/buttonMenu.js +10 -14
  56. package/src/lightning/buttonStateful/__docs__/buttonStateful.md +12 -12
  57. package/src/lightning/buttonStateful/button-stateful.slds.css +225 -457
  58. package/src/lightning/buttonStateful/buttonStateful.css +2 -2
  59. package/src/lightning/buttonStateful/buttonStateful.js +3 -2
  60. package/src/lightning/calendar/__examples__/basic/basic.html +7 -0
  61. package/src/lightning/calendar/__examples__/basic/basic.js +3 -0
  62. package/src/lightning/calendar/calendar.css +3 -0
  63. package/src/lightning/calendar/calendar.html +12 -9
  64. package/src/lightning/calendar/calendar.js +18 -2
  65. package/src/lightning/calendar/calendar.slds.css +2048 -0
  66. package/src/lightning/card/__docs__/card.md +3 -3
  67. package/src/lightning/card/card.css +2 -2
  68. package/src/lightning/card/card.js +3 -2
  69. package/src/lightning/card/card.slds.css +141 -88
  70. package/src/lightning/checkboxGroup/__docs__/checkboxGroup.md +2 -2
  71. package/src/lightning/colorPickerCustom/colorPickerCustom.css +2 -2
  72. package/src/lightning/colorPickerCustom/colorPickerCustom.js +3 -2
  73. package/src/lightning/colorPickerPanel/color-picker-panel.slds.css +11 -38
  74. package/src/lightning/colorPickerPanel/colorPickerPanel.css +3 -2
  75. package/src/lightning/colorPickerPanel/colorPickerPanel.js +4 -2
  76. package/src/lightning/colorPickerPanel/popover.slds.css +121 -0
  77. package/src/lightning/combobox/combobox.css +4 -0
  78. package/src/lightning/combobox/combobox.html +31 -29
  79. package/src/lightning/combobox/combobox.js +21 -4
  80. package/src/lightning/combobox/combobox.slds.css +13 -0
  81. package/src/lightning/combobox/form-element.slds.css +281 -0
  82. package/src/lightning/configProvider/defaultConfig.js +2 -1
  83. package/src/lightning/datatable/__docs__/datatable.md +45 -35
  84. package/src/lightning/datatable/autoWidthStrategy.js +3 -0
  85. package/src/lightning/datatable/columnWidthManager.js +1 -1
  86. package/src/lightning/datatable/datatable.js +8 -7
  87. package/src/lightning/datatable/rowSelection.js +7 -4
  88. package/src/lightning/datatable/templates/table/table.html +1 -0
  89. package/src/lightning/datepicker/datepicker.css +3 -0
  90. package/src/lightning/datepicker/datepicker.html +7 -4
  91. package/src/lightning/datepicker/datepicker.js +76 -20
  92. package/src/lightning/datepicker/form-element.slds.css +281 -0
  93. package/src/lightning/datepicker/input-text.slds.css +398 -0
  94. package/src/lightning/datetimepicker/datetimepicker.css +3 -0
  95. package/src/lightning/datetimepicker/datetimepicker.html +9 -3
  96. package/src/lightning/datetimepicker/datetimepicker.js +42 -36
  97. package/src/lightning/datetimepicker/form-element.slds.css +281 -0
  98. package/src/lightning/datetimepicker/input-text.slds.css +398 -0
  99. package/src/lightning/dualListbox/dualListbox.css +2 -2
  100. package/src/lightning/dualListbox/dualListbox.html +3 -3
  101. package/src/lightning/dualListbox/dualListbox.js +47 -13
  102. package/src/lightning/dualListbox/form-element.slds.css +83 -34
  103. package/src/lightning/dualListbox/keyboard.js +20 -1
  104. package/src/lightning/dynamicIcon/dynamicIcon.js +3 -2
  105. package/src/lightning/dynamicIcon/ellie.css +1 -1
  106. package/src/lightning/dynamicIcon/eq.css +1 -1
  107. package/src/lightning/dynamicIcon/score.css +1 -1
  108. package/src/lightning/dynamicIcon/strength.css +1 -1
  109. package/src/lightning/dynamicIcon/trend.css +1 -1
  110. package/src/lightning/dynamicIcon/waffle.css +1 -1
  111. package/src/lightning/formattedRichText/formatted-rich-text.slds.css +230 -0
  112. package/src/lightning/formattedRichText/formattedRichText.css +2 -0
  113. package/src/lightning/formattedRichText/formattedRichText.js +4 -2
  114. package/src/lightning/formattedRichText/linkify.js +2 -2
  115. package/src/lightning/formattedText/formattedText.css +1 -0
  116. package/src/lightning/formattedText/formattedText.js +3 -2
  117. package/src/lightning/helptext/__docs__/helptext.md +2 -2
  118. package/src/lightning/helptext/form-element.slds.css +83 -34
  119. package/src/lightning/helptext/help-text.slds.css +215 -453
  120. package/src/lightning/helptext/helptext.css +2 -2
  121. package/src/lightning/helptext/helptext.js +3 -2
  122. package/src/lightning/i18nCldrOptions/README.md +5 -0
  123. package/src/lightning/i18nService/README.md +5 -0
  124. package/src/lightning/icon/__docs__/icon.md +5 -5
  125. package/src/lightning/icon/icon.css +2 -2
  126. package/src/lightning/icon/icon.js +21 -2
  127. package/src/lightning/icon/icon.slds.css +29 -17
  128. package/src/lightning/icon/iconColors.js +1 -0
  129. package/src/lightning/iconUtils/iconUtils.js +0 -12
  130. package/src/lightning/iconUtils/polyfill.js +5 -90
  131. package/src/lightning/input/__docs__/input.md +7 -7
  132. package/src/lightning/input/__examples__/checkboxbutton/checkboxbutton.css +6 -0
  133. package/src/lightning/input/__examples__/checkboxbutton/checkboxbutton.html +2 -1
  134. package/src/lightning/input/__examples__/checkboxbutton/checkboxbutton.js +1 -1
  135. package/src/lightning/input/__examples__/number/number.html +0 -5
  136. package/src/lightning/input/__examples__/text/text.html +0 -1
  137. package/src/lightning/input/form-element.slds.css +281 -0
  138. package/src/lightning/input/input.css +2 -3
  139. package/src/lightning/input/input.html +154 -244
  140. package/src/lightning/input/input.js +306 -595
  141. package/src/lightning/inputAddress/__docs__/inputAddress.md +3 -3
  142. package/src/lightning/inputUtils/inputUtils.js +15 -20
  143. package/src/lightning/inputUtils/normalize.js +7 -0
  144. package/src/lightning/{input/numberUtil.js → inputUtils/number.js} +1 -1
  145. package/src/lightning/inputUtils/utils.js +18 -0
  146. package/src/lightning/internationalizationLibrary/README.md +24 -0
  147. package/src/lightning/internationalizationLibrary/utils.js +4 -1
  148. package/src/lightning/layout/__docs__/layout.md +1 -1
  149. package/src/lightning/layout/__examples__/simple/simple.css +1 -1
  150. package/src/lightning/layout/layout.css +5 -1
  151. package/src/lightning/layout/layout.js +4 -2
  152. package/src/lightning/layoutItem/__examples__/alignmentBump/alignmentBump.css +1 -1
  153. package/src/lightning/layoutItem/__examples__/sizePerDevice/sizePerDevice.css +0 -1
  154. package/src/lightning/layoutItem/layoutItem.css +5 -0
  155. package/src/lightning/layoutItem/layoutItem.js +4 -2
  156. package/src/lightning/menuDivider/menu-divider.slds.css +15 -0
  157. package/src/lightning/menuDivider/menuDivider.css +3 -0
  158. package/src/lightning/menuDivider/menuDivider.html +1 -1
  159. package/src/lightning/menuDivider/menuDivider.js +4 -2
  160. package/src/lightning/menuItem/menu-item.slds.css +140 -0
  161. package/src/lightning/menuItem/menuItem.css +3 -0
  162. package/src/lightning/menuItem/menuItem.html +43 -41
  163. package/src/lightning/menuItem/menuItem.js +4 -4
  164. package/src/lightning/menuSubheader/menu-subheader.slds.css +22 -0
  165. package/src/lightning/menuSubheader/menuSubheader.css +3 -0
  166. package/src/lightning/menuSubheader/menuSubheader.html +3 -1
  167. package/src/lightning/menuSubheader/menuSubheader.js +4 -6
  168. package/src/lightning/modal/__docs__/modal.md +3 -1
  169. package/src/lightning/modal/__modalUtils__/modalContainerTestConstants.js +267 -0
  170. package/src/lightning/modal/__modalUtils__/modalContainerTestMethods.js +1165 -0
  171. package/src/lightning/modal/__modalUtils__/modalContainerTestMockData.js +131 -0
  172. package/src/lightning/modal/modal.js +1 -1
  173. package/src/lightning/modalBody/__docs__/modalBody.md +9 -9
  174. package/src/lightning/modalFooter/__docs__/modalFooter.md +9 -9
  175. package/src/lightning/modalHeader/__docs__/modalHeader.md +9 -9
  176. package/src/lightning/overlayContainer/overlayContainer.js +4 -2
  177. package/src/lightning/pill/__docs__/pill.md +3 -3
  178. package/src/lightning/pill/avatar.slds.css +272 -0
  179. package/src/lightning/pill/link.css +3 -0
  180. package/src/lightning/pill/link.html +1 -1
  181. package/src/lightning/pill/pill.js +29 -9
  182. package/src/lightning/pill/pill.slds.css +168 -0
  183. package/src/lightning/pill/plain.css +3 -0
  184. package/src/lightning/pill/plain.html +1 -1
  185. package/src/lightning/pill/plainLink.css +3 -0
  186. package/src/lightning/pill/plainLink.html +1 -1
  187. package/src/lightning/pillContainer/__docs__/pillContainer.md +14 -14
  188. package/src/lightning/pillContainer/barePillContainer.css +3 -0
  189. package/src/lightning/pillContainer/barePillContainer.html +1 -2
  190. package/src/lightning/pillContainer/listbox.slds.css +267 -0
  191. package/src/lightning/pillContainer/pill-container.slds.css +22 -0
  192. package/src/lightning/pillContainer/pill.slds.css +168 -0
  193. package/src/lightning/pillContainer/pillContainer.js +7 -3
  194. package/src/lightning/pillContainer/standardPillContainer.css +4 -0
  195. package/src/lightning/pillContainer/standardPillContainer.html +2 -2
  196. package/src/lightning/popup/popover.slds.css +119 -119
  197. package/src/lightning/popup/popup.css +1 -2
  198. package/src/lightning/popup/popup.js +3 -2
  199. package/src/lightning/positionLibrary/elementProxy.js +7 -2
  200. package/src/lightning/positionLibrary/util.js +8 -0
  201. package/src/lightning/primitiveBubble/primitiveBubble.css +2 -2
  202. package/src/lightning/primitiveBubble/primitiveBubble.js +4 -2
  203. package/src/lightning/primitiveButton/primitiveButton.js +5 -4
  204. package/src/lightning/primitiveCellFactory/cellWithStandardLayout.html +29 -21
  205. package/src/lightning/primitiveCellFactory/primitiveCellFactory.js +4 -0
  206. package/src/lightning/primitiveColorpickerButton/color-picker-button.slds.css +31 -19
  207. package/src/lightning/primitiveColorpickerButton/primitiveColorpickerButton.css +2 -2
  208. package/src/lightning/primitiveColorpickerButton/primitiveColorpickerButton.js +5 -3
  209. package/src/lightning/primitiveIcon/icon.slds.css +209 -0
  210. package/src/lightning/primitiveIcon/primitiveIcon.css +2 -1
  211. package/src/lightning/primitiveIcon/primitiveIcon.html +1 -1
  212. package/src/lightning/primitiveIcon/primitiveIcon.js +26 -16
  213. package/src/lightning/progressStep/progressStep.js +10 -13
  214. package/src/lightning/radioGroup/__docs__/radioGroup.md +4 -4
  215. package/src/lightning/radioGroup/radioGroup.css +2 -1
  216. package/src/lightning/radioGroup/radioGroup.js +4 -2
  217. package/src/lightning/select/__docs__/select.md +2 -2
  218. package/src/lightning/select/form-element.slds.css +83 -34
  219. package/src/lightning/select/select.css +2 -2
  220. package/src/lightning/select/select.js +4 -2
  221. package/src/lightning/select/select.slds.css +86 -34
  222. package/src/lightning/shadowBaseClassPrivate/shadowBaseClassPrivate.js +1 -1
  223. package/src/lightning/sldsCommon/sldsCommon.css +251 -89
  224. package/src/lightning/sldsUtilsAlignment/sldsUtilsAlignment.css +10 -0
  225. package/src/lightning/sldsUtilsAlignment/sldsUtilsAlignment.js-meta.xml +4 -0
  226. package/src/lightning/sldsUtilsBorders/sldsUtilsBorders.css +18 -0
  227. package/src/lightning/sldsUtilsBorders/sldsUtilsBorders.js-meta.xml +4 -0
  228. package/src/lightning/sldsUtilsBox/sldsUtilsBox.css +24 -0
  229. package/src/lightning/sldsUtilsBox/sldsUtilsBox.js-meta.xml +4 -0
  230. package/src/lightning/sldsUtilsFloats/sldsUtilsFloats.css +20 -0
  231. package/src/lightning/sldsUtilsFloats/sldsUtilsFloats.js-meta.xml +4 -0
  232. package/src/lightning/sldsUtilsGrid/sldsUtilsGrid.css +259 -0
  233. package/src/lightning/sldsUtilsGrid/sldsUtilsGrid.js-meta.xml +4 -0
  234. package/src/lightning/sldsUtilsHyphenation/sldsUtilsHyphenation.css +8 -0
  235. package/src/lightning/sldsUtilsHyphenation/sldsUtilsHyphenation.js-meta.xml +4 -0
  236. package/src/lightning/sldsUtilsLineClamp/sldsUtilsLineClamp.css +57 -0
  237. package/src/lightning/sldsUtilsLineClamp/sldsUtilsLineClamp.js-meta.xml +4 -0
  238. package/src/lightning/sldsUtilsMargin/sldsUtilsMargin.css +313 -0
  239. package/src/lightning/sldsUtilsMargin/sldsUtilsMargin.js-meta.xml +4 -0
  240. package/src/lightning/sldsUtilsPadding/sldsUtilsPadding.css +308 -0
  241. package/src/lightning/sldsUtilsPadding/sldsUtilsPadding.js-meta.xml +4 -0
  242. package/src/lightning/sldsUtilsPosition/sldsUtilsPosition.css +18 -0
  243. package/src/lightning/sldsUtilsPosition/sldsUtilsPosition.js-meta.xml +4 -0
  244. package/src/lightning/sldsUtilsSizing/sldsUtilsSizing.css +1408 -0
  245. package/src/lightning/sldsUtilsSizing/sldsUtilsSizing.js-meta.xml +4 -0
  246. package/src/lightning/sldsUtilsThemes/sldsUtilsThemes.css +295 -0
  247. package/src/lightning/sldsUtilsThemes/sldsUtilsThemes.js-meta.xml +4 -0
  248. package/src/lightning/sldsUtilsTruncation/sldsUtilsTruncation.css +14 -0
  249. package/src/lightning/sldsUtilsTruncation/sldsUtilsTruncation.js-meta.xml +4 -0
  250. package/src/lightning/slider/__docs__/slider.md +2 -2
  251. package/src/lightning/spinner/spinner.css +2 -2
  252. package/src/lightning/spinner/spinner.js +4 -2
  253. package/src/lightning/tabBar/tab-bar.slds.css +334 -0
  254. package/src/lightning/tabBar/tabBar.css +2 -0
  255. package/src/lightning/tabBar/tabBar.html +4 -3
  256. package/src/lightning/tabBar/tabBar.js +30 -3
  257. package/src/lightning/tabset/__docs__/tabset.md +2 -2
  258. package/src/lightning/tabset/tabset.html +5 -4
  259. package/src/lightning/tabset/tabset.js +29 -11
  260. package/src/lightning/textarea/__docs__/textarea.md +2 -2
  261. package/src/lightning/timepicker/form-element.slds.css +281 -0
  262. package/src/lightning/timepicker/timepicker.css +3 -0
  263. package/src/lightning/timepicker/timepicker.html +5 -1
  264. package/src/lightning/timepicker/timepicker.js +22 -17
  265. package/src/lightning/timepicker/timepicker.slds.css +18 -0
  266. package/src/lightning/toast/toast.js-meta.xml +2 -0
  267. package/src/lightning/toastContainer/__docs__/toastContainer.md +14 -34
  268. package/src/lightning/toastContainer/toastContainer.js +10 -15
  269. package/src/lightning/tooltipLibrary/tooltipLibrary.js +32 -23
  270. package/src/lightning/utilsPrivate/browser.js +5 -3
  271. package/src/lightning/utilsPrivate/os.js +6 -4
  272. package/src/lightning/utilsPrivate/ssr.js +4 -0
  273. package/src/lightning/utilsPrivate/utilsPrivate.js +2 -0
  274. package/src/lightning/verticalNavigation/verticalNavigation.css +2 -1
  275. package/src/lightning/verticalNavigation/verticalNavigation.js +3 -2
  276. package/src/lightning/verticalNavigationSection/verticalNavigationSection.css +2 -1
  277. package/src/lightning/verticalNavigationSection/verticalNavigationSection.js +3 -2
  278. package/src/lightning/accordion/__perf__DISABLED/accordion-perf-utils.js +0 -76
  279. package/src/lightning/accordion/__perf__DISABLED/accordion10Multiple25SectionEach.perf.js +0 -57
  280. package/src/lightning/accordion/__perf__DISABLED/accordion10Simple25SectionEach.perf.js +0 -37
  281. package/src/lightning/accordion/__perf__DISABLED/accordionMultiple50Section.perf.js +0 -45
  282. package/src/lightning/accordion/__perf__DISABLED/accordionSimple50Section.perf.js +0 -35
  283. package/src/lightning/accordion/__perf__DISABLED/container/container.html +0 -15
  284. package/src/lightning/accordion/__perf__DISABLED/container/container.js +0 -7
  285. package/src/lightning/iconUtils/isIframeInEdge.js +0 -7
  286. package/src/lightning/iconUtils/supportsSvg.js +0 -16
  287. package/src/lightning/input/input-checkbox.slds.css +0 -404
  288. package/src/lightning/input/input-text.slds.css +0 -287
  289. package/src/lightning/input/normalize.js +0 -6
  290. package/src/lightning/input/selection.js +0 -131
  291. package/src/lightning/positionLibrary/__component__/positionLibraryBounding.spec.js +0 -319
  292. package/src/lightning/positionLibrary/__component__/x/bounding/bounding.css +0 -16
  293. package/src/lightning/positionLibrary/__component__/x/bounding/bounding.html +0 -36
  294. package/src/lightning/positionLibrary/__component__/x/bounding/bounding.js +0 -122
  295. /package/src/lightning/{baseCombobox → baseComboboxItem}/listbox.slds.css +0 -0
  296. /package/src/lightning/formattedRichText/{__examples__disabled → __examples__}/basic/basic.html +0 -0
  297. /package/src/lightning/formattedRichText/{__examples__disabled → __examples__}/basic/basic.js +0 -0
  298. /package/src/lightning/{input/emailUtil.js → inputUtils/email.js} +0 -0
@@ -1,6 +1,4 @@
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';
4
2
  import labelMessageToggleActive from '@salesforce/label/LightningControl.activeCapitalized';
5
3
  import labelMessageToggleInactive from '@salesforce/label/LightningControl.inactiveCapitalized';
6
4
  import labelRequired from '@salesforce/label/LightningControl.required';
@@ -13,20 +11,17 @@ import labelHelpTextAlternativeText from '@salesforce/label/LightningInput.helpt
13
11
  import userTimeZone from '@salesforce/i18n/timeZone';
14
12
  import formFactor from '@salesforce/client/formFactor';
15
13
 
16
- import { api, LightningElement, track } from 'lwc';
14
+ import { api, track } from 'lwc';
15
+ import LightningShadowBaseClass from 'lightning/shadowBaseClassPrivate';
17
16
  import { classSet, formatLabel } from 'lightning/utils';
18
17
  import {
19
18
  assert,
20
19
  classListMutation,
21
- getRealDOMId,
22
20
  reflectAttribute,
23
- isSafari,
24
21
  isNativeComponent,
25
- isNotUndefinedOrNull,
26
22
  isUndefinedOrNull,
27
23
  normalizeAriaAttribute,
28
24
  normalizeBoolean,
29
- normalizeKeyValue,
30
25
  normalizeString,
31
26
  synchronizeAttrs,
32
27
  decorateInputForDragon,
@@ -34,7 +29,6 @@ import {
34
29
  computeAriaInvalid,
35
30
  } from 'lightning/utilsPrivate';
36
31
  import AriaObserver from 'lightning/ariaObserver';
37
- import { normalizeInput } from './normalize';
38
32
  import {
39
33
  normalizeDate,
40
34
  normalizeDateTimeToUTC,
@@ -47,26 +41,14 @@ import {
47
41
  InteractingState,
48
42
  normalizeVariant,
49
43
  VARIANT,
50
- } from 'lightning/inputUtils';
51
- import {
52
- calculateFractionDigitsFromStep,
53
- formatNumber,
54
- fromIsoDecimal,
55
- hasValidNumberShortcut,
56
- hasValidNumberSymbol,
57
- increaseNumberByStep,
44
+ normalizeInput,
58
45
  isValidNumber,
59
- isValidNumberCharacter,
60
- stringifyNumber,
61
- toIsoDecimal,
62
- } from './numberUtil';
63
- import { isValidEmail, isValidMultipleEmails } from './emailUtil';
64
- import { InputSelectionCache } from './selection';
46
+ isValidEmail,
47
+ isValidMultipleEmails,
48
+ } from 'lightning/inputUtils';
65
49
 
66
50
  const i18n = {
67
51
  a11yTriggerText: labelA11yTriggerText,
68
- inputFileBodyText: labelInputFileBodyText,
69
- inputFileButtonLabel: labelInputFileButtonLabel,
70
52
  messageToggleActive: labelMessageToggleActive,
71
53
  messageToggleInactive: labelMessageToggleInactive,
72
54
  numberIncrementCounter: labelNumberIncrementCounter,
@@ -106,30 +88,12 @@ const VALID_NUMBER_FORMATTERS = [
106
88
  'percent-fixed',
107
89
  'currency',
108
90
  ];
109
- const DEFAULT_COLOR = '#000000';
110
91
  const DEFAULT_FORMATTER = VALID_NUMBER_FORMATTERS[0];
111
92
 
112
- /**
113
- * Returns an aria string with all the non-autolinked values removed
114
- * @param {String} values space sperated list of ids
115
- * @returns {String} The aria values with the non-auto linked ones removed
116
- */
117
- function filterNonAutoLink(values) {
118
- const ariaValues = values && values.split(/\s+/);
119
- return (
120
- ariaValues &&
121
- ariaValues
122
- .filter((value) => {
123
- return !!value.match(/^auto-link/);
124
- })
125
- .join(' ')
126
- );
127
- }
128
-
129
93
  /**
130
94
  * Represents interactive controls that accept user input depending on the type attribute.
131
95
  */
132
- export default class LightningInput extends LightningElement {
96
+ export default class LightningInput extends LightningShadowBaseClass {
133
97
  static delegatesFocus = true;
134
98
 
135
99
  /**
@@ -318,12 +282,12 @@ export default class LightningInput extends LightningElement {
318
282
  @track _ariaInvalid;
319
283
  @track _autocomplete;
320
284
 
285
+ _shouldShowHelpMessage = true;
286
+ _helpMessageChanged = false;
321
287
  _formatter = DEFAULT_FORMATTER;
322
288
  _showRawNumber = false;
323
289
  _initialValueSet = false;
324
- _files = null;
325
290
  _rendered;
326
- _selectionCache;
327
291
 
328
292
  constructor() {
329
293
  super();
@@ -331,15 +295,11 @@ export default class LightningInput extends LightningElement {
331
295
 
332
296
  // Native Shadow Root will return [native code].
333
297
  // Our synthetic method will return the function source.
334
- this.isNative = isNativeComponent(this);
335
-
336
- // The selection cache allows us an input to remember what text was selected
337
- // in cases where we change the text on blur or in browsers (Safari) that
338
- // don't track it properly.
339
- this._selectionCache = new InputSelectionCache();
298
+ this._isNativeShadow = isNativeComponent(this);
340
299
  }
341
300
 
342
301
  connectedCallback() {
302
+ super.connectedCallback();
343
303
  if (!this.ariaObserver) {
344
304
  this.ariaObserver = new AriaObserver(this);
345
305
  }
@@ -351,15 +311,11 @@ export default class LightningInput extends LightningElement {
351
311
 
352
312
  this.classList.add('slds-form-element');
353
313
 
354
- this._updateClassList();
355
- this._validateRequiredAttributes();
314
+ this.updateClassListForVariant();
315
+ this.validateRequiredAttributes();
356
316
 
357
317
  this.interactingState = new InteractingState();
358
318
  this.interactingState.onleave(() => this.reportValidity());
359
-
360
- if (this.isTypeNumber) {
361
- this._updateNumberValue(this._value);
362
- }
363
319
  }
364
320
 
365
321
  disconnectedCallback() {
@@ -373,22 +329,25 @@ export default class LightningInput extends LightningElement {
373
329
  }
374
330
 
375
331
  renderedCallback() {
376
- // For W-7962838: In Safari, focus doesn't scroll input into view.
377
- // Attach the event listener used to cache the selected text when selection changes.
378
- if (isSafari) {
379
- this._inputElement.addEventListener(
380
- 'select',
381
- this.handleSelect.bind(this)
382
- );
332
+ if (this.isConnected) {
333
+ this.ariaObserver.sync(this.isNativeShadow);
334
+
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
+ if (!this._rendered) {
342
+ this.connectAriaDescribedBy();
343
+ this.connectAriaLabelledBy();
344
+ this.connectAriaControls();
345
+ }
383
346
  }
384
347
 
385
348
  if (!this._initialValueSet && this._inputElement) {
386
349
  this._rendered = true;
387
350
 
388
- if (this.isTypeNumber) {
389
- this._numberRawValue = fromIsoDecimal(this._value);
390
- }
391
-
392
351
  this._setInputValue(this._displayedValue);
393
352
  if (this.isTypeCheckable) {
394
353
  this._inputElement.checked = this._checked;
@@ -396,9 +355,6 @@ export default class LightningInput extends LightningElement {
396
355
  this._initialValueSet = true;
397
356
  }
398
357
 
399
- if (this.isConnected) {
400
- this.ariaObserver.sync();
401
- }
402
358
  this._synchronizeA11y();
403
359
  }
404
360
 
@@ -407,17 +363,7 @@ export default class LightningInput extends LightningElement {
407
363
  * @type {number}
408
364
  *
409
365
  */
410
- @api
411
- get formatFractionDigits() {
412
- return this._formatFractionDigits;
413
- }
414
-
415
- set formatFractionDigits(value) {
416
- this._formatFractionDigits = value;
417
- if (this._rendered && this.isTypeNumber) {
418
- this._setInputValue(this._displayedValue);
419
- }
420
- }
366
+ @api formatFractionDigits;
421
367
 
422
368
  /**
423
369
  * A space-separated list of element IDs whose presence or content is controlled by the
@@ -541,6 +487,9 @@ export default class LightningInput extends LightningElement {
541
487
 
542
488
  set ariaControls(references) {
543
489
  this._ariaControls = references;
490
+ if (this._rendered) {
491
+ this.connectAriaControls();
492
+ }
544
493
  reflectAttribute(this, ARIA_CONTROLS, references);
545
494
  }
546
495
 
@@ -550,21 +499,17 @@ export default class LightningInput extends LightningElement {
550
499
  */
551
500
  @api
552
501
  get ariaLabelledBy() {
553
- // native version returns the auto linked value
554
- if (this.isNative && this._rendered) {
555
- const ariaValues = this._inputElement.getAttribute(ARIA_LABELLEDBY);
556
- return filterNonAutoLink(ariaValues);
557
- }
558
- return this._ariaLabelledBy;
502
+ // native shadow version returns the mirrored values
503
+ return this._rendered && this.isNativeShadow
504
+ ? this._inputElement.getAttribute(ARIA_LABELLEDBY)
505
+ : this._ariaLabelledBy;
559
506
  }
560
507
 
561
508
  set ariaLabelledBy(references) {
562
509
  this._ariaLabelledBy = references;
563
- this.ariaObserver.connect({
564
- targetSelector: 'input',
565
- attribute: ARIA_LABELLEDBY,
566
- ids: references,
567
- });
510
+ if (this._rendered) {
511
+ this.connectAriaLabelledBy();
512
+ }
568
513
  }
569
514
 
570
515
  /**
@@ -573,26 +518,66 @@ export default class LightningInput extends LightningElement {
573
518
  */
574
519
  @api
575
520
  get ariaDescribedBy() {
576
- if (this.isNative) {
577
- // in native case return the linked value
578
- const ariaValues =
579
- this._inputElement.getAttribute(ARIA_DESCRIBEDBY);
580
- return filterNonAutoLink(ariaValues);
581
- }
582
- return this._ariaDescribedBy;
521
+ // native shadow version returns the mirrored values
522
+ return this._rendered && this.isNativeShadow
523
+ ? this._inputElement.getAttribute(ARIA_DESCRIBEDBY)
524
+ : this._ariaDescribedBy;
583
525
  }
584
526
 
585
527
  set ariaDescribedBy(references) {
586
528
  this._ariaDescribedBy = references;
587
- this.ariaObserver.connect({
588
- targetSelector: 'input',
589
- attribute: ARIA_DESCRIBEDBY,
590
- ids: references,
591
- });
529
+ if (this._rendered) {
530
+ this.connectAriaDescribedBy();
531
+ }
532
+ }
533
+
534
+ get isNativeShadow() {
535
+ return this._primitiveComponent?.isNativeShadow || this._isNativeShadow;
592
536
  }
593
537
 
594
538
  /**
595
- * A boolean value that controls whether accessibility tools read empty required textboxes as invalid. Default value is false.
539
+ * Connect aria-labelledby to the ariaObserver.
540
+ */
541
+ connectAriaLabelledBy() {
542
+ if (this._primitiveComponent) {
543
+ this.ariaObserver.connect({
544
+ attribute: ARIA_LABELLEDBY,
545
+ targetNode: this._inputElement,
546
+ relatedNodes: this._primitiveComponent.ariaLabelledByElements,
547
+ relatedNodeIds: this._ariaLabelledBy,
548
+ });
549
+ }
550
+ }
551
+
552
+ /**
553
+ * Connect aria-describedby to the ariaObserver.
554
+ */
555
+ connectAriaDescribedBy() {
556
+ if (this._primitiveComponent) {
557
+ this.ariaObserver.connect({
558
+ attribute: ARIA_DESCRIBEDBY,
559
+ targetNode: this._inputElement,
560
+ relatedNodes: this._primitiveComponent.ariaDescribedByElements,
561
+ relatedNodeIds: this._ariaDescribedBy,
562
+ });
563
+ }
564
+ }
565
+
566
+ /**
567
+ * Connect aria-controls to the ariaObserver.
568
+ */
569
+ connectAriaControls() {
570
+ if (this._primitiveComponent) {
571
+ this.ariaObserver.connect({
572
+ attribute: ARIA_CONTROLS,
573
+ targetNode: this._inputElement,
574
+ relatedNodeIds: this._ariaControls,
575
+ });
576
+ }
577
+ }
578
+
579
+ /**
580
+ * A Boolean value for aria-invalid.
596
581
  * @type {boolean}
597
582
  */
598
583
  @api
@@ -622,15 +607,22 @@ export default class LightningInput extends LightningElement {
622
607
  */
623
608
  @api
624
609
  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
+ }
625
615
  return this._formatter;
626
616
  }
627
617
 
628
618
  set formatter(value) {
629
- this._formatter = normalizeString(value, {
630
- fallbackValue: DEFAULT_FORMATTER,
631
- validValues: VALID_NUMBER_FORMATTERS,
632
- });
633
- this._updateInputDisplayValueIfTypeNumber();
619
+ this._formatter = value;
620
+
621
+ // If the primitive exists, retrieve value from primitive-input-simple
622
+ // The primitive will normalize the value
623
+ if (this.isTypeNumber && this._primitiveComponent) {
624
+ this._primitiveComponent.formatter = this._formatter;
625
+ }
634
626
  }
635
627
 
636
628
  /**
@@ -659,10 +651,10 @@ export default class LightningInput extends LightningElement {
659
651
  // from text to 'checkbox', so we need to set the initial value again
660
652
  this._initialValueSet = false;
661
653
 
662
- if (this.isTypeNumber) {
663
- // If the type has changed, we need to re-parse the value as a number
664
- this._updateNumberValue(this._value);
665
- }
654
+ // Reconnect aria attributes as the parentSelector is based on the input type
655
+ this.connectAriaLabelledBy();
656
+ this.connectAriaDescribedBy();
657
+ this.connectAriaControls();
666
658
  }
667
659
 
668
660
  this._updateProxyInputAttributes([
@@ -814,7 +806,6 @@ export default class LightningInput extends LightningElement {
814
806
  }
815
807
 
816
808
  this._updateProxyInputAttributes('step');
817
- this._updateInputDisplayValueIfTypeNumber();
818
809
  }
819
810
 
820
811
  /**
@@ -836,7 +827,11 @@ export default class LightningInput extends LightningElement {
836
827
  this._checked = normalizeBoolean(value);
837
828
 
838
829
  if (this._rendered) {
839
- this._inputElement.checked = this._checked;
830
+ if (this.isTypeCheckbox) {
831
+ this._primitiveComponent.checked = this._checked;
832
+ } else {
833
+ this._inputElement.checked = this._checked;
834
+ }
840
835
  }
841
836
 
842
837
  // Update proxy input should be set after _inputElement is updated.
@@ -867,29 +862,29 @@ export default class LightningInput extends LightningElement {
867
862
  */
868
863
  @api
869
864
  get value() {
865
+ if (this.isTypeSimple) {
866
+ const subcomponent = this._primitiveComponent;
867
+ if (subcomponent) {
868
+ return subcomponent.value;
869
+ }
870
+ }
870
871
  return this._value;
871
872
  }
872
873
 
873
874
  set value(value) {
874
- const previousValue = this._value;
875
-
876
- this._value = normalizeInput(value);
877
-
878
- if (this._rendered && this.isTypeNumber) {
879
- this._value = stringifyNumber(value);
880
- // the extra check for whether the value has changed is done for cases
881
- // when the same value is set back in a change handler, this is to avoid
882
- // the raw number from changing formatting under the user
883
- // (eg. if the user typed 1,000 we want to preserve that formatting as the user
884
- // types the value)
885
- if (this.validity.badInput || this._value !== previousValue) {
886
- this._updateNumberValue(value);
887
- }
888
- }
889
-
890
- this._updateProxyInputAttributes('value');
891
875
  // Setting value of a type='file' isn't allowed
892
876
  if (!this.isTypeFile) {
877
+ this._value = normalizeInput(value);
878
+
879
+ if (this.isTypeSimple) {
880
+ const subcomponent = this._primitiveComponent;
881
+ if (subcomponent) {
882
+ subcomponent.value = this._value;
883
+ }
884
+ }
885
+
886
+ this._updateProxyInputAttributes('value');
887
+
893
888
  // Again, due to the interop layer we need to check whether the value being set
894
889
  // is different, otherwise we're duplicating the sets on the input, which result
895
890
  // in different bugs like Japanese IME duplication of characters in Safari (likely a browser bug) or
@@ -920,7 +915,7 @@ export default class LightningInput extends LightningElement {
920
915
 
921
916
  set variant(value) {
922
917
  this._variant = normalizeVariant(value);
923
- this._updateClassList();
918
+ this.updateClassListForVariant();
924
919
  reflectAttribute(this, 'variant', this._variant);
925
920
  }
926
921
 
@@ -1024,7 +1019,7 @@ export default class LightningInput extends LightningElement {
1024
1019
  @api
1025
1020
  get files() {
1026
1021
  if (this.isTypeFile) {
1027
- return this._files;
1022
+ return this._primitiveComponent.files;
1028
1023
  }
1029
1024
  return null;
1030
1025
  }
@@ -1039,6 +1034,14 @@ export default class LightningInput extends LightningElement {
1039
1034
  return this._constraint.validity;
1040
1035
  }
1041
1036
 
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
+
1042
1045
  /**
1043
1046
  * Specifies the index of the first character to select in the input element.
1044
1047
  * This attribute is supported only for text type.
@@ -1104,11 +1107,22 @@ export default class LightningInput extends LightningElement {
1104
1107
  @api
1105
1108
  reportValidity() {
1106
1109
  return this._constraint.reportValidity((message) => {
1110
+ if (this.isTypeDesktopTime) {
1111
+ reflectAttribute(
1112
+ this._inputElement.comboboxComponent,
1113
+ 'invalid',
1114
+ !this.checkValidity()
1115
+ );
1116
+ }
1107
1117
  if (this._rendered && !this.isNativeInput) {
1108
1118
  this._inputElement.showHelpMessage(message);
1109
- } else {
1110
- this._helpMessage = message;
1119
+ return;
1111
1120
  }
1121
+ if (this._rendered && this.isTypePrimitiveInput) {
1122
+ this._shouldShowHelpMessage = false;
1123
+ this._helpMessageChanged = true;
1124
+ }
1125
+ this._helpMessage = message;
1112
1126
  });
1113
1127
  }
1114
1128
 
@@ -1141,211 +1155,51 @@ export default class LightningInput extends LightningElement {
1141
1155
  }
1142
1156
  }
1143
1157
 
1144
- get isAutoCompleteSupported() {
1145
- return (
1146
- this.isTypeTelephone ||
1147
- this.isTypeUrl ||
1148
- this.isTypeSearch ||
1149
- this.isTypeEmail ||
1150
- this.isTypeText
1151
- );
1152
- }
1153
-
1154
- get isNativeInput() {
1155
- return !(
1156
- this.isTypeDesktopDate ||
1157
- this.isTypeDesktopDateTime ||
1158
- this.isTypeDesktopTime
1159
- );
1160
- }
1161
-
1162
- get computedAriaLabel() {
1163
- const ariaValues = [];
1164
-
1165
- // merge all date & time arias on mobile since it's displayed as a single field
1166
- if (this.isTypeMobileDateTime) {
1167
- ariaValues.push(this.dateAriaLabel);
1168
- ariaValues.push(this.timeAriaLabel);
1169
- }
1170
- if (this.ariaLabel) {
1171
- ariaValues.push(this.ariaLabel);
1172
- }
1173
-
1174
- return normalizeAriaAttribute(ariaValues);
1175
- }
1176
-
1177
- get computedAriaLabelledBy() {
1178
- const ariaValues = [];
1179
-
1180
- if (this.isTypeFile) {
1181
- ariaValues.push(this.computedUniqueFileElementLabelledById);
1182
- }
1183
- // merge all date & time arias on mobile since it's displayed as a single field
1184
- if (this.isTypeMobileDateTime) {
1185
- ariaValues.push(this.dateAriaLabelledBy);
1186
- ariaValues.push(this.timeAriaLabelledBy);
1158
+ get primitiveSelector() {
1159
+ if (this.isTypeSimple) {
1160
+ return 'lightning-primitive-input-simple';
1187
1161
  }
1188
- if (this.ariaLabelledBy) {
1189
- ariaValues.push(this.ariaLabelledBy);
1162
+ if (this.isTypeCheckboxButton) {
1163
+ return 'lightning-primitive-input-checkbox-button';
1190
1164
  }
1191
-
1192
- return normalizeAriaAttribute(ariaValues);
1193
- }
1194
-
1195
- get computedAriaDescribedBy() {
1196
- const ariaValues = [];
1197
-
1198
- if (this._helpMessage) {
1199
- ariaValues.push(this.computedUniqueHelpElementId);
1200
- }
1201
- // The toggle type is described by a secondary element
1202
1165
  if (this.isTypeToggle) {
1203
- ariaValues.push(this.computedUniqueToggleElementDescribedById);
1204
- }
1205
- // merge all date & time arias on mobile since it's displayed as a single field
1206
- if (this.isTypeMobileDateTime) {
1207
- ariaValues.push(this.dateAriaDescribedBy);
1208
- ariaValues.push(this.timeAriaDescribedBy);
1209
- }
1210
- if (this.ariaDescribedBy) {
1211
- ariaValues.push(this.ariaDescribedBy);
1166
+ return 'lightning-primitive-input-toggle';
1212
1167
  }
1213
-
1214
- return normalizeAriaAttribute(ariaValues);
1215
- }
1216
-
1217
- get computedAriaInvalid() {
1218
- // W-8796658: aria-invalid should always follow the visual indication of errors
1219
- return computeAriaInvalid(
1220
- this._helpMessage,
1221
- this.value,
1222
- this.ariaInvalid
1223
- );
1224
- }
1225
-
1226
- get isLabelHidden() {
1227
- return this.variant === VARIANT.LABEL_HIDDEN;
1228
- }
1229
-
1230
- get isLabelStacked() {
1231
- return this.variant === VARIANT.LABEL_STACKED;
1232
- }
1233
-
1234
- get accesskey() {
1235
- return this._accesskey;
1236
- }
1237
-
1238
- get colorInputElementValue() {
1239
- return this.validity.valid && this.value ? this.value : DEFAULT_COLOR;
1240
- }
1241
-
1242
- get colorInputStyle() {
1243
- return `background: ${this.value || '#5679C0'};`;
1244
- }
1245
-
1246
- get computedUniqueHelpElementId() {
1247
- return getRealDOMId(this.template.querySelector('[data-help-message]'));
1248
- }
1249
-
1250
- get computedUniqueToggleElementDescribedById() {
1251
- if (this.isTypeToggle) {
1252
- const toggle = this.template.querySelector(
1253
- '[data-toggle-description]'
1254
- );
1255
- return getRealDOMId(toggle);
1168
+ if (this.isTypeColor) {
1169
+ return 'lightning-primitive-input-color';
1256
1170
  }
1257
- return null;
1258
- }
1259
-
1260
- get computedUniqueFormLabelId() {
1261
- if (this.isTypeFile) {
1262
- const formLabel = this.template.querySelector('[data-form-label]');
1263
- return getRealDOMId(formLabel);
1171
+ if (this.isTypeCheckbox) {
1172
+ return 'lightning-primitive-input-checkbox';
1264
1173
  }
1265
- return null;
1266
- }
1267
-
1268
- get computedUniqueFileSelectorLabelId() {
1269
- if (this.isTypeFile) {
1270
- const fileBodyLabel = this.template.querySelector(
1271
- '[data-file-selector-label]'
1272
- );
1273
- return getRealDOMId(fileBodyLabel);
1174
+ if (this.isTypeRadio) {
1175
+ return 'lightning-primitive-input-radio';
1274
1176
  }
1275
- return null;
1276
- }
1277
-
1278
- get computedUniqueFileElementLabelledById() {
1279
1177
  if (this.isTypeFile) {
1280
- const labelIds = [
1281
- this.computedUniqueFormLabelId,
1282
- this.computedUniqueFileSelectorLabelId,
1283
- ];
1284
- return labelIds.join(' ');
1178
+ return 'lightning-primitive-input-file';
1285
1179
  }
1286
1180
  return null;
1287
1181
  }
1288
1182
 
1289
- get computedFormElementClass() {
1290
- const classes = classSet('slds-form-element__control slds-grow');
1291
-
1292
- if (this.isTypeSearch) {
1293
- classes.add('slds-input-has-icon slds-input-has-icon_left-right');
1294
- }
1295
-
1296
- return classes.toString();
1297
- }
1298
-
1299
- get i18n() {
1300
- return i18n;
1301
- }
1302
-
1303
- get computedLabelClass() {
1304
- const classnames = classSet('slds-form-element__label');
1305
- if (this.isTypeCheckable || this.isTypeFile) {
1306
- // do nothing
1307
- } else if (this.isTypeToggle) {
1308
- classnames.add('slds-m-bottom_none');
1309
- } else {
1310
- classnames.add('slds-no-flex');
1311
- }
1312
- return classnames
1313
- .add({ 'slds-assistive-text': this.isLabelHidden })
1314
- .toString();
1315
- }
1316
-
1317
- get computedNumberClass() {
1318
- return classSet('slds-input')
1319
- .add({ 'slds-is-disabled': this.disabled })
1320
- .toString();
1321
- }
1322
-
1323
- get computedColorLabelClass() {
1324
- return classSet(
1325
- 'slds-form-element__label slds-color-picker__summary-label'
1326
- )
1327
- .add({ 'slds-assistive-text': this.isLabelHidden })
1328
- .toString();
1329
- }
1330
-
1331
- get computedCheckboxClass() {
1332
- return classSet('slds-checkbox')
1333
- .add({ 'slds-checkbox_standalone': !this.isStandardVariant })
1334
- .toString();
1183
+ get shouldShowHelpMessage() {
1184
+ return this._shouldShowHelpMessage && this._helpMessage;
1335
1185
  }
1336
1186
 
1337
- get computedHelpMessageClass() {
1338
- return classSet('slds-form-element__help')
1339
- .add({ 'slds-m-left_none': this.variant !== VARIANT.LABEL_INLINE })
1340
- .toString();
1341
- }
1187
+ /************************* INPUT TYPE GETTERS *************************/
1342
1188
 
1343
- get normalizedMax() {
1344
- return this._normalizeDateTimeString(this.max);
1189
+ get isTypePrimitiveInput() {
1190
+ return (
1191
+ this.isTypeSimple ||
1192
+ this.isTypeCheckboxButton ||
1193
+ this.isTypeCheckbox ||
1194
+ this.isTypeToggle ||
1195
+ this.isTypeColor ||
1196
+ this.isTypeRadio ||
1197
+ this.isTypeFile
1198
+ );
1345
1199
  }
1346
1200
 
1347
- get normalizedMin() {
1348
- return this._normalizeDateTimeString(this.min);
1201
+ get isTypeNumber() {
1202
+ return this.type === 'number';
1349
1203
  }
1350
1204
 
1351
1205
  get isTypeTelephone() {
@@ -1356,10 +1210,6 @@ export default class LightningInput extends LightningElement {
1356
1210
  return this.type === 'url';
1357
1211
  }
1358
1212
 
1359
- get isTypeNumber() {
1360
- return this.type === 'number';
1361
- }
1362
-
1363
1213
  get isTypeEmail() {
1364
1214
  // To test against native change this to type="emails"
1365
1215
  return this.type === 'email';
@@ -1374,10 +1224,6 @@ export default class LightningInput extends LightningElement {
1374
1224
  );
1375
1225
  }
1376
1226
 
1377
- get isTypeSearch() {
1378
- return this.type === 'search';
1379
- }
1380
-
1381
1227
  get isTypeToggle() {
1382
1228
  return this.type === 'toggle';
1383
1229
  }
@@ -1456,6 +1302,85 @@ export default class LightningInput extends LightningElement {
1456
1302
  );
1457
1303
  }
1458
1304
 
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
+
1459
1384
  get _inputElement() {
1460
1385
  if (!this._cachedInputElement || this._inputElementRefreshNeeded) {
1461
1386
  this._inputDragonDecorated = false;
@@ -1472,6 +1397,8 @@ export default class LightningInput extends LightningElement {
1472
1397
  inputElement = this.template.querySelector(
1473
1398
  'lightning-timepicker'
1474
1399
  );
1400
+ } else if (this.isTypePrimitiveInput) {
1401
+ inputElement = this._primitiveComponent.inputElement;
1475
1402
  } else {
1476
1403
  inputElement = this.template.querySelector('input');
1477
1404
  this._inputDragonDecorated = true;
@@ -1510,34 +1437,8 @@ export default class LightningInput extends LightningElement {
1510
1437
 
1511
1438
  get _displayedValue() {
1512
1439
  if (this.isTypeNumber) {
1513
- // When only a symbol is entered by the user, set the display value as the user's input.
1514
- // This will not affect the value dispatched by input via the change event, as it only dispatches a valid decimal number.
1515
- // Due to the above, in integrations like input-field, the user's initial input of a symbol
1516
- // like a minus sign will not be overwritten by an empty string value.
1517
- // See description in PR for more details: https://github.com/salesforce-experience-platform-emu/lightning-components/pull/3843
1518
- if (
1519
- this._inputElement.value.length === 1 &&
1520
- hasValidNumberSymbol(this._inputElement.value)
1521
- ) {
1522
- return this._inputElement.value;
1523
- }
1524
-
1525
- // If the number is not valid (bad input, step mismatch, etc.) show the raw number as
1526
- // well, otherwise the formatted value ends up being 'NaN' which makes it hard to
1527
- // see mistakes
1528
- if (this._showRawNumber || !this.validity.valid) {
1529
- if (
1530
- hasValidNumberShortcut(this._numberRawValue) &&
1531
- isValidNumber(this._numberRawValue)
1532
- ) {
1533
- this._numberRawValue = fromIsoDecimal(this._value);
1534
- }
1535
- return this._numberRawValue;
1536
- }
1537
- return formatNumber(
1538
- this._value,
1539
- this._buildFormatNumberOptions(this.formatter)
1540
- );
1440
+ const subcomponent = this._primitiveComponent;
1441
+ return subcomponent.getDisplayedValue();
1541
1442
  }
1542
1443
 
1543
1444
  if (
@@ -1551,18 +1452,6 @@ export default class LightningInput extends LightningElement {
1551
1452
  return this._value;
1552
1453
  }
1553
1454
 
1554
- /**
1555
- * Gets the value for the actual 'type' attribute on the input element.
1556
- */
1557
- get _internalType() {
1558
- // Maps number->text to support shorthand input strings like '1k'.
1559
- if (this.isTypeNumber || this.isTypeEmail) {
1560
- return 'text';
1561
- }
1562
-
1563
- return this._type;
1564
- }
1565
-
1566
1455
  get isStandardVariant() {
1567
1456
  return (
1568
1457
  this.variant === VARIANT.STANDARD ||
@@ -1570,34 +1459,14 @@ export default class LightningInput extends LightningElement {
1570
1459
  );
1571
1460
  }
1572
1461
 
1573
- get _showClearButton() {
1574
- return (
1575
- this.isTypeSearch &&
1576
- isNotUndefinedOrNull(this._value) &&
1577
- this._value !== ''
1578
- );
1579
- }
1580
-
1581
1462
  get _ignoreRequired() {
1582
1463
  // If uploading via the drop zone or via the input directly, we should
1583
1464
  // ignore the required flag as a file has been uploaded
1584
1465
  return (
1585
- this.isTypeFile &&
1586
- this._required &&
1587
- (this.fileUploadedViaDroppableZone ||
1588
- (this._files && this._files.length > 0))
1466
+ this.isTypeFile && this._required && this.files && this.files.length
1589
1467
  );
1590
1468
  }
1591
1469
 
1592
- get _inputMode() {
1593
- if (this.isTypeNumber) {
1594
- return 'decimal';
1595
- } else if (this.isTypeEmail) {
1596
- return 'email';
1597
- }
1598
- return null;
1599
- }
1600
-
1601
1470
  get _constraint() {
1602
1471
  if (!this._constraintApi) {
1603
1472
  const overrides = {
@@ -1727,35 +1596,18 @@ export default class LightningInput extends LightningElement {
1727
1596
  return formatLabel(i18n.helpTextAlternativeText, this.label);
1728
1597
  }
1729
1598
 
1730
- handleFileClick() {
1731
- this._setInputValue(null);
1732
- this._updateValueAndValidityAttribute(null);
1733
- }
1734
-
1735
- handleDropFiles(event) {
1736
- // drop doesn't trigger focus nor blur, so set state to interacting
1737
- // and auto leave when there's no more action
1738
- this.interactingState.interacting();
1739
-
1740
- this.fileUploadedViaDroppableZone = true;
1741
- this._files = event.dataTransfer && event.dataTransfer.files;
1742
-
1743
- this._updateProxyInputAttributes('required');
1744
-
1745
- this._dispatchChangeEventWithDetail({
1746
- files: this._files,
1747
- });
1599
+ get isAutoCompleteSupported() {
1600
+ return (
1601
+ this.isTypeTelephone ||
1602
+ this.isTypeUrl ||
1603
+ this.isTypeSearch ||
1604
+ this.isTypeEmail ||
1605
+ this.isTypeText
1606
+ );
1748
1607
  }
1749
1608
 
1750
- /**
1751
- * Handle text selection.
1752
- * Dynamically bound to the select event by `renderedCallback`.
1753
- * This allows us to cache text selection in Safari, which doesn't preserve selection.
1754
- */
1755
- handleSelect() {
1756
- if (isSafari) {
1757
- this._selectionCache.preserve(this._inputElement);
1758
- }
1609
+ get templateRootNode() {
1610
+ return this.template.host.getRootNode();
1759
1611
  }
1760
1612
 
1761
1613
  handleFocus() {
@@ -1765,24 +1617,11 @@ export default class LightningInput extends LightningElement {
1765
1617
  this._isColorPickerPanelOpen = false;
1766
1618
  }
1767
1619
 
1768
- // Focusing a number input causes the value displayed to be modified.
1769
- // Changing the value resets selection, so we save and restore selection.
1770
- if (this._rendered && this.isTypeNumber) {
1771
- this._showRawNumber = true;
1772
- this._selectionCache.preserve(this._inputElement);
1773
- this._inputElement.value = this._displayedValue;
1774
- this._selectionCache.restore(this._inputElement);
1775
- }
1776
-
1777
1620
  this.dispatchEvent(new CustomEvent('focus'));
1778
1621
  }
1779
1622
 
1780
1623
  handleBlur(event) {
1781
1624
  this.interactingState.leave();
1782
- if (this._rendered && this.isTypeNumber) {
1783
- this._showRawNumber = false;
1784
- this._setInputValue(this._displayedValue);
1785
- }
1786
1625
 
1787
1626
  if (
1788
1627
  !event.relatedTarget ||
@@ -1800,87 +1639,34 @@ export default class LightningInput extends LightningElement {
1800
1639
 
1801
1640
  handleChange(event) {
1802
1641
  event.stopPropagation();
1803
-
1804
1642
  this._dispatchCommitEvent();
1805
-
1806
- if (this.isTypeSimple && this.value === event.target.value) {
1807
- return;
1808
- }
1809
-
1810
1643
  this._dispatchChangeEvent();
1811
1644
  }
1812
1645
 
1813
- handleInput(event) {
1814
- event.stopPropagation();
1815
-
1816
- if (this.isTypeNumber) {
1817
- // for invalid numbers the value might stay the same as the user
1818
- // changed the invalid input, so we need to update the raw value
1819
- this._numberRawValue = this._inputElement.value;
1820
- }
1821
-
1822
- if (this.isTypeSimple && this.value === event.target.value) {
1823
- return;
1824
- }
1825
-
1826
- this._dispatchChangeEvent();
1646
+ handleCommit() {
1647
+ this._dispatchCommitEvent();
1827
1648
  }
1828
1649
 
1829
- handleKeyDown(event) {
1830
- if (this.isTypeNumber) {
1831
- // we're letting "Shift" through to prevent capital letters, other special symbols for type="number"
1832
- const hasMetaOrCtrlModifier = event.metaKey || event.ctrlKey;
1833
- // need to check that event.key is valid for "autofill" cases
1834
- if (!hasMetaOrCtrlModifier && !this.readOnly && event.key) {
1835
- const key = normalizeKeyValue(event.key);
1836
-
1837
- if (key.length === 1 && !isValidNumberCharacter(key)) {
1838
- event.preventDefault();
1839
- }
1840
-
1841
- if (key === 'ArrowUp') {
1842
- event.preventDefault();
1843
- this._numberStepUpAndDispatchEvents(1);
1844
- } else if (key === 'ArrowDown') {
1845
- event.preventDefault();
1846
- this._numberStepUpAndDispatchEvents(-1);
1847
- }
1848
- }
1849
- }
1850
- }
1650
+ handlePrimitiveInputFileChange() {
1651
+ const detail = {
1652
+ files: this.files,
1653
+ value: this._inputElement.value,
1654
+ };
1655
+ this._updateProxyInputAttributes('required');
1656
+ this._updateValueAndValidityAttribute(detail.value);
1851
1657
 
1852
- handleColorChange(event) {
1853
- const selectedColor = event.detail.color;
1854
- if (selectedColor !== this._inputElement.value) {
1855
- this._setInputValue(selectedColor);
1856
- this._updateValueAndValidityAttribute(selectedColor);
1857
- this.focus();
1858
- this._dispatchChangeEventWithDetail({ value: selectedColor });
1859
- this._dispatchCommitEvent();
1860
- }
1861
- this.template
1862
- .querySelector('lightning-primitive-colorpicker-button')
1863
- .focus();
1658
+ this.dispatchEvent(
1659
+ new CustomEvent('change', {
1660
+ composed: true,
1661
+ bubbles: true,
1662
+ detail,
1663
+ })
1664
+ );
1864
1665
  }
1865
1666
 
1866
- _clearAndSetFocusOnInput(event) {
1867
- // TODO: Discuss this, it seems the wrong thing to do.
1868
- // button is removed from template, but
1869
- // event still is propagated, For example, captured by panel,
1870
- // then cause panel think is clicked outside.
1871
- event.stopPropagation();
1872
-
1667
+ handlePrimitiveInputSimpleChange() {
1873
1668
  this.interactingState.enter();
1874
- this._setInputValue('');
1875
- this._updateValueAndValidityAttribute('');
1876
-
1877
- this._inputElement.focus();
1878
-
1879
- this._dispatchChangeEventWithDetail({
1880
- value: this._value,
1881
- });
1882
-
1883
- this._dispatchCommitEvent();
1669
+ this._updateProxyInputAttributes('value');
1884
1670
  }
1885
1671
 
1886
1672
  _dispatchCommitEvent() {
@@ -1917,7 +1703,11 @@ export default class LightningInput extends LightningElement {
1917
1703
  }
1918
1704
  }
1919
1705
 
1920
- _validateRequiredAttributes() {
1706
+ /**
1707
+ * Label is a required attribute.
1708
+ * Throw error if an invalid value is passed to the label attribute
1709
+ */
1710
+ validateRequiredAttributes() {
1921
1711
  const { label } = this;
1922
1712
  assert(
1923
1713
  typeof label === 'string' && label.length,
@@ -1939,6 +1729,8 @@ export default class LightningInput extends LightningElement {
1939
1729
  }
1940
1730
 
1941
1731
  _dispatchChangeEvent() {
1732
+ // TODO: investigate removing this in a future update
1733
+ // possibly phase out the interactingState entirely
1942
1734
  this.interactingState.enter();
1943
1735
 
1944
1736
  const detail = {};
@@ -1946,20 +1738,10 @@ export default class LightningInput extends LightningElement {
1946
1738
  if (this.isTypeCheckable) {
1947
1739
  this._updateCheckedAndValidityAttribute(this._inputElement.checked);
1948
1740
  detail.checked = this._checked;
1949
- } else if (this.isTypeFile) {
1950
- this._files = this._inputElement.files;
1951
-
1952
- // LWC does not proxy dom elements any more. So there is no need to call lwc.unwrap here anymore
1953
- detail.files = this._files;
1954
-
1955
- this._updateProxyInputAttributes('required');
1956
1741
  }
1957
1742
 
1958
1743
  if (!this.isTypeCheckable) {
1959
- if (this.isTypeNumber) {
1960
- this._numberRawValue = this._inputElement.value;
1961
- detail.value = toIsoDecimal(this._inputElement.value);
1962
- } else {
1744
+ if (!this.isTypeNumber) {
1963
1745
  detail.value = this._inputElement.value;
1964
1746
  }
1965
1747
 
@@ -2013,36 +1795,9 @@ export default class LightningInput extends LightningElement {
2013
1795
  }
2014
1796
 
2015
1797
  /**
2016
- * Increases (if increment is positive, decreases otherwise) the number value of the input by the increment
2017
- * multiple of the given 'step'. Additionally dispatches the 'change' and 'commit' events.
2018
- *
2019
- * @param {Number} increment A multiple of the step to increase, when step is 'any',
2020
- * the step is assumed to be 1.
2021
- * @private
1798
+ * Updates the class list on the host element based on the variant
2022
1799
  */
2023
- _numberStepUpAndDispatchEvents(increment) {
2024
- if (this._readOnly || this._disabled) {
2025
- return;
2026
- }
2027
- this._value = increaseNumberByStep({
2028
- value: this._value,
2029
- step: this.step,
2030
- increment,
2031
- fractionDigits: this._buildFormatNumberOptions(this.formatter)
2032
- .minimumFractionDigits,
2033
- });
2034
-
2035
- // Raw value is the value the user entered (we preserve a user's input),
2036
- // since we're generating a new value we're overriding it
2037
- this._numberRawValue = fromIsoDecimal(this._value);
2038
-
2039
- this._setInputValue(this._displayedValue);
2040
-
2041
- this._dispatchChangeEvent();
2042
- this._dispatchCommitEvent();
2043
- }
2044
-
2045
- _updateClassList() {
1800
+ updateClassListForVariant() {
2046
1801
  classListMutation(this.classList, {
2047
1802
  'slds-form-element_stacked': this.variant === VARIANT.LABEL_STACKED,
2048
1803
  'slds-form-element_horizontal':
@@ -2050,39 +1805,6 @@ export default class LightningInput extends LightningElement {
2050
1805
  });
2051
1806
  }
2052
1807
 
2053
- _updateNumberValue(value) {
2054
- const newValue = stringifyNumber(value);
2055
- this._value = newValue;
2056
- this._numberRawValue = fromIsoDecimal(newValue);
2057
- }
2058
-
2059
- _buildFormatNumberOptions(formatter) {
2060
- const options = {
2061
- style: formatter,
2062
- };
2063
- // Use the min/max fraction digits from the formatFractionDigits provided by the user if available.
2064
- // Otherwise, use the number of digits calculated from step
2065
- if (this._formatFractionDigits !== undefined) {
2066
- options.minimumFractionDigits = this._formatFractionDigits;
2067
- options.maximumFractionDigits = this._formatFractionDigits;
2068
- } else {
2069
- let digitsFromStep = calculateFractionDigitsFromStep(this._step);
2070
- // if formatting percentages, when calculating digits from step, take into
2071
- // consideration that the formatted number is effectively multiplied by 10^2, ie. 0.1 is 10%
2072
- // so we need to subtract 2 digits;
2073
- if (formatter === 'percent' && typeof digitsFromStep === 'number') {
2074
- digitsFromStep -= 2;
2075
- if (digitsFromStep < 0) {
2076
- digitsFromStep = 0;
2077
- }
2078
- }
2079
-
2080
- options.minimumFractionDigits = digitsFromStep;
2081
- options.maximumFractionDigits = digitsFromStep;
2082
- }
2083
- return options;
2084
- }
2085
-
2086
1808
  _normalizeDateTimeString(value) {
2087
1809
  let result = value;
2088
1810
  if (this.isTypeDate) {
@@ -2095,19 +1817,11 @@ export default class LightningInput extends LightningElement {
2095
1817
  return result;
2096
1818
  }
2097
1819
 
2098
- _updateInputA11y(elem) {
2099
- synchronizeAttrs(elem, {
2100
- [ARIA_LABELLEDBY]: this.computedAriaLabelledBy,
2101
- [ARIA_DESCRIBEDBY]: this.computedAriaDescribedBy,
2102
- [ARIA_LABEL]: this.computedAriaLabel,
2103
- });
2104
- }
2105
-
2106
1820
  _updateDateOrTimePickerA11y(elem) {
2107
1821
  synchronizeAttrs(elem, {
2108
- ariaLabelledByElement: this.ariaLabelledBy,
2109
- ariaDescribedByElements: this.ariaDescribedBy,
2110
- ariaControlsElement: this.ariaControls,
1822
+ ariaLabelledByElement: this._ariaLabelledBy,
1823
+ ariaDescribedByElements: this._ariaDescribedBy,
1824
+ ariaControlsElement: this._ariaControls,
2111
1825
  [ARIA_LABEL]: this.computedAriaLabel,
2112
1826
  });
2113
1827
  }
@@ -2130,7 +1844,6 @@ export default class LightningInput extends LightningElement {
2130
1844
  _synchronizeA11y() {
2131
1845
  // each of these templates are mutually exclusive and are selected
2132
1846
  // depending on the [type] of input.
2133
- const input = this.template.querySelector('input');
2134
1847
  const datepicker = this.template.querySelector('lightning-datepicker');
2135
1848
  const timepicker = this.template.querySelector('lightning-timepicker');
2136
1849
  const datetimepicker = this.template.querySelector(
@@ -2138,9 +1851,7 @@ export default class LightningInput extends LightningElement {
2138
1851
  );
2139
1852
  // determine which template type is present,
2140
1853
  // and update a11y props accordingly
2141
- if (input) {
2142
- this._updateInputA11y(input);
2143
- } else if (datepicker) {
1854
+ if (datepicker) {
2144
1855
  this._updateDateOrTimePickerA11y(datepicker);
2145
1856
  } else if (timepicker) {
2146
1857
  this._updateDateOrTimePickerA11y(timepicker);