lightning-base-components 1.14.2-alpha → 1.14.6-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/metadata/raptor.json +33 -1
  2. package/package.json +20 -4
  3. package/scopedImports/@salesforce-label-LightningDualListbox.movedOptionsPlural.js +1 -0
  4. package/scopedImports/@salesforce-label-LightningDualListbox.movedOptionsSingular.js +1 -0
  5. package/scopedImports/@salesforce-label-LightningErrorMessage.validitySelectAtleastOne.js +1 -0
  6. package/scopedImports/@salesforce-label-LightningMap.titleWithAddress.js +1 -0
  7. package/scopedImports/@salesforce-label-LightningModalBase.cancelandclose.js +1 -0
  8. package/src/lightning/ariaObserver/__component__/ariaObserver.spec.js +9 -0
  9. package/src/lightning/ariaObserver/__docs__/ariaObserver.md +142 -0
  10. package/src/lightning/ariaObserver/ariaObserver.js +24 -35
  11. package/src/lightning/baseFormattedText/baseFormattedText.html +6 -1
  12. package/src/lightning/baseFormattedText/baseFormattedText.js +5 -0
  13. package/src/lightning/buttonMenu/keyboard.js +0 -10
  14. package/src/lightning/card/card.html +6 -0
  15. package/src/lightning/checkboxGroup/checkboxGroup.html +2 -2
  16. package/src/lightning/checkboxGroup/checkboxGroup.js +6 -1
  17. package/src/lightning/colorPickerCustom/colorPickerCustom.js +20 -1
  18. package/src/lightning/datatable/__docs__/datatable.md +55 -0
  19. package/src/lightning/datatable/__examples__/basic/basic.html +1 -1
  20. package/src/lightning/datatable/__examples__/withInfiniteLoading/fetchDataHelper.js +21 -0
  21. package/src/lightning/datatable/__examples__/withInfiniteLoading/withInfiniteLoading.html +13 -0
  22. package/src/lightning/datatable/__examples__/withInfiniteLoading/withInfiniteLoading.js +42 -0
  23. package/src/lightning/datatable/autoWidthStrategy.js +170 -61
  24. package/src/lightning/datatable/{resizer.js → columnResizer.js} +0 -0
  25. package/src/lightning/datatable/columnWidthManager.js +226 -44
  26. package/src/lightning/datatable/columns-shared.js +1 -1
  27. package/src/lightning/datatable/datatable.js +104 -33
  28. package/src/lightning/datatable/errors.js +20 -9
  29. package/src/lightning/datatable/fixedWidthStrategy.js +43 -8
  30. package/src/lightning/datatable/headerActions.js +77 -49
  31. package/src/lightning/datatable/infiniteLoading.js +100 -28
  32. package/src/lightning/datatable/inlineEdit.js +505 -379
  33. package/src/lightning/datatable/inlineEditShared.js +24 -0
  34. package/src/lightning/datatable/keyboard.js +162 -127
  35. package/src/lightning/datatable/renderManager.js +208 -133
  36. package/src/lightning/datatable/{datatableResizeObserver.js → resizeObserver.js} +46 -29
  37. package/src/lightning/datatable/resizeSensor.js +8 -0
  38. package/src/lightning/datatable/rowLevelActions.js +17 -13
  39. package/src/lightning/datatable/rowNumber.js +54 -20
  40. package/src/lightning/datatable/rowSelection.js +760 -0
  41. package/src/lightning/datatable/rowSelectionShared.js +79 -0
  42. package/src/lightning/datatable/rows.js +17 -6
  43. package/src/lightning/datatable/state.js +16 -2
  44. package/src/lightning/datatable/templates/div/div.css +4 -0
  45. package/src/lightning/datatable/templates/div/div.html +128 -117
  46. package/src/lightning/datatable/templates/table/table.html +5 -0
  47. package/src/lightning/datatable/utils.js +14 -0
  48. package/src/lightning/datatable/widthManagerShared.js +27 -3
  49. package/src/lightning/datatable/wrapText.js +77 -47
  50. package/src/lightning/dualListbox/dualListbox.html +1 -1
  51. package/src/lightning/dualListbox/dualListbox.js +42 -0
  52. package/src/lightning/formattedDateTime/__docs__/formattedDateTime.md +36 -3
  53. package/src/lightning/formattedDateTime/__examples__/datetime/datetime.html +2 -2
  54. package/src/lightning/formattedDateTime/__examples__/datetime/datetime.js +3 -1
  55. package/src/lightning/formattedDateTime/__examples__/time/time.html +1 -1
  56. package/src/lightning/formattedDateTime/__examples__/time/time.js +3 -1
  57. package/src/lightning/formattedDateTime/formattedDateTime.js +1 -0
  58. package/src/lightning/input/input.html +2 -5
  59. package/src/lightning/inputUtils/validity.js +12 -1
  60. package/src/lightning/pillContainer/__docs__/pillContainer.md +45 -1
  61. package/src/lightning/positionLibrary/positionLibrary.js +31 -43
  62. package/src/lightning/primitiveCellActions/primitiveCellActions.js +69 -12
  63. package/src/lightning/primitiveCellFactory/cellWithStandardLayout.html +13 -11
  64. package/src/lightning/primitiveCellFactory/primitiveCellFactory.js +13 -8
  65. package/src/lightning/primitiveDatatableIeditPanel/primitiveDatatableIeditPanel.html +17 -14
  66. package/src/lightning/primitiveDatatableIeditPanel/primitiveDatatableIeditPanel.js +167 -98
  67. package/src/lightning/primitiveDatatableIeditTypeFactory/primitiveDatatableIeditTypeFactory.js +94 -69
  68. package/src/lightning/primitiveDatatableStatusBar/primitiveDatatableStatusBar.html +4 -4
  69. package/src/lightning/primitiveDatatableStatusBar/primitiveDatatableStatusBar.js +4 -4
  70. package/src/lightning/primitiveHeaderActions/primitiveHeaderActions.js +99 -37
  71. package/src/lightning/progressIndicator/progressIndicator.js +1 -1
  72. package/src/lightning/progressStep/progressStep.js +1 -1
  73. package/src/lightning/spinner/spinner.html +1 -1
  74. package/src/lightning/spinner/spinner.js +12 -0
  75. package/src/lightning/staticMap/staticMap.html +1 -0
  76. package/src/lightning/staticMap/staticMap.js +39 -2
  77. package/src/lightning/utils/classSet.js +4 -1
  78. package/src/lightning/utilsPrivate/phonify.js +1 -1
  79. package/scopedImports/@salesforce-label-LightningModalBase.close.js +0 -1
  80. package/src/lightning/datatable/inlineEdit-shared.js +0 -14
  81. package/src/lightning/datatable/selector-shared.js +0 -38
  82. package/src/lightning/datatable/selector.js +0 -527
@@ -3,8 +3,10 @@ import labelWrapText from '@salesforce/label/LightningDatatable.wrapText';
3
3
  import { getStateColumnIndex, getColumns } from './columns';
4
4
  import { normalizeBoolean } from 'lightning/utilsPrivate';
5
5
  import { normalizeNumberAttribute } from './utils';
6
+ import { getDefaultState } from './state';
6
7
 
7
- const nonWrapableTypes = [
8
+ const WRAP_TEXT_DEFAULT = false;
9
+ const NON_WRAPPABLE_TYPES = [
8
10
  'action',
9
11
  'boolean',
10
12
  'button',
@@ -13,17 +15,33 @@ const nonWrapableTypes = [
13
15
  'rowNumber',
14
16
  ];
15
17
 
16
- const WRAP_TEXT_DEFAULT = false;
17
-
18
18
  const i18n = {
19
19
  clipText: labelClipText,
20
20
  wrapText: labelWrapText,
21
21
  };
22
22
 
23
- function isWrapableType(type) {
24
- return nonWrapableTypes.indexOf(type) < 0;
23
+ /************************** WRAP TEXT STATE **************************/
24
+
25
+ // Returns a boolean representing whether or not the column should be text wrapped
26
+ export function getWrapTextState(state = getDefaultState(), colKeyValue) {
27
+ return state.wrapText[colKeyValue] || WRAP_TEXT_DEFAULT;
25
28
  }
26
29
 
30
+ // Sets a boolean value in state's wrapText object against the column key value
31
+ // representing whether or not the column is text wrapped
32
+ export function setWrapTextState(state = getDefaultState(), columnDefinition) {
33
+ const { colKeyValue, type, wrapText } = columnDefinition;
34
+
35
+ if (isWrappableType(type)) {
36
+ state.wrapText[colKeyValue] =
37
+ normalizeBoolean(wrapText) || WRAP_TEXT_DEFAULT;
38
+ }
39
+ }
40
+
41
+ /************************** WRAP TEXT MAX LINES **************************/
42
+
43
+ // Normalizes and sets wrapTextMaxLines in datatable's state object
44
+ // The normalized value should be a positive integer or it'll fall back to undefined
27
45
  export function setWrapTextMaxLines(state, value) {
28
46
  state.wrapTextMaxLines = normalizeNumberAttribute(
29
47
  'wrapTextMaxLines',
@@ -33,6 +51,8 @@ export function setWrapTextMaxLines(state, value) {
33
51
  );
34
52
  }
35
53
 
54
+ // Sets the `wrapText` and `wrapTextMaxLines` values in the cell object for all cells in a column
55
+ // These values are used by primitiveCellFactory to set the required classes on the cell for wrapping
36
56
  function updateWrapTextAndMaxLinesValuesInCells(state, colIndex, colKeyValue) {
37
57
  state.rows.forEach((row) => {
38
58
  const cell = row.cells[colIndex];
@@ -43,39 +63,17 @@ function updateWrapTextAndMaxLinesValuesInCells(state, colIndex, colKeyValue) {
43
63
  });
44
64
  }
45
65
 
46
- function updateSelectedOptionInHeaderActions(state, colKeyValue) {
47
- const columns = getColumns(state);
48
- const colIndex = getStateColumnIndex(state, colKeyValue);
49
- const colData = columns[colIndex];
50
-
51
- colData.actions.internalActions.forEach((action) => {
52
- if (action.name === 'wrapText') {
53
- action.checked = state.wrapText[colKeyValue];
54
- }
55
- if (action.name === 'clipText') {
56
- action.checked = !state.wrapText[colKeyValue];
57
- }
58
- });
59
-
60
- updateWrapTextAndMaxLinesValuesInCells(state, colIndex, colKeyValue);
61
-
62
- // lets force a refresh on this column, because the wrapText checked value changed.
63
- colData.actions = Object.assign({}, colData.actions);
64
- }
65
-
66
- export function getWrapTextState(state = getDefaultState(), colKeyValue) {
67
- return state.wrapText[colKeyValue] || WRAP_TEXT_DEFAULT;
68
- }
69
-
70
- export function setWrapTextState(state = getDefaultState(), columnDefinition) {
71
- const { colKeyValue, type, wrapText } = columnDefinition;
72
-
73
- if (isWrapableType(type)) {
74
- state.wrapText[colKeyValue] =
75
- normalizeBoolean(wrapText) || WRAP_TEXT_DEFAULT;
76
- }
77
- }
78
-
66
+ /************************** HEADER ACTIONS **************************/
67
+
68
+ /**
69
+ * Returns an object representing the two internal header actions that datatable
70
+ * provides - Wrap Text and Clip Text.
71
+ * Each header action contains a label, title, action name and its selected value (checked)
72
+ *
73
+ * @param {Object} state - datatable's state object
74
+ * @param {Object} columnDefinition - datatable's column definitions
75
+ * @returns
76
+ */
79
77
  export function getActions(state, columnDefinition) {
80
78
  const wrapTextActions = [];
81
79
  const { hideDefaultActions, type, colKeyValue } = columnDefinition;
@@ -84,7 +82,7 @@ export function getActions(state, columnDefinition) {
84
82
  setWrapTextState(state, columnDefinition);
85
83
 
86
84
  // if not hidden and isWrapable, sets the internal actions
87
- if (isWrapableType(type) && !hideDefaultActions) {
85
+ if (isWrappableType(type) && !hideDefaultActions) {
88
86
  const isTextWrapped = getWrapTextState(state, colKeyValue);
89
87
 
90
88
  wrapTextActions.push({
@@ -105,19 +103,51 @@ export function getActions(state, columnDefinition) {
105
103
  return wrapTextActions;
106
104
  }
107
105
 
106
+ /**
107
+ * If the action is an internal action and if the wrapText value for a column
108
+ * needs to be changed in the state, change it to the new value and update
109
+ * the check mark to represent the currently selected action
110
+ *
111
+ * @param {Object} state - datatable's state object
112
+ * @param {String} action - action that was selected/triggered
113
+ * @param {String} colKeyValue - column key value
114
+ */
108
115
  export function handleTriggeredAction(state, action, colKeyValue) {
109
- if (action.name === 'wrapText' || action.name === 'clipText') {
110
- // If will change state
111
- if (state.wrapText[colKeyValue] !== (action.name === 'wrapText')) {
112
- state.wrapText[colKeyValue] = action.name === 'wrapText';
116
+ const actionName = action.name;
117
+ if (actionName === 'wrapText' || actionName === 'clipText') {
118
+ // If state should be changed
119
+ if (state.wrapText[colKeyValue] !== (actionName === 'wrapText')) {
120
+ state.wrapText[colKeyValue] = actionName === 'wrapText';
113
121
 
114
122
  updateSelectedOptionInHeaderActions(state, colKeyValue);
115
123
  }
116
124
  }
117
125
  }
118
126
 
119
- export function getDefaultState() {
120
- return {
121
- wrapText: {},
122
- };
127
+ // Update the 'checked' value of the each action to show which action is selected
128
+ // and which action is not selected
129
+ function updateSelectedOptionInHeaderActions(state, colKeyValue) {
130
+ const columns = getColumns(state);
131
+ const colIndex = getStateColumnIndex(state, colKeyValue);
132
+ const colData = columns[colIndex];
133
+
134
+ colData.actions.internalActions.forEach((action) => {
135
+ if (action.name === 'wrapText') {
136
+ action.checked = state.wrapText[colKeyValue];
137
+ }
138
+ if (action.name === 'clipText') {
139
+ action.checked = !state.wrapText[colKeyValue];
140
+ }
141
+ });
142
+
143
+ updateWrapTextAndMaxLinesValuesInCells(state, colIndex, colKeyValue);
144
+
145
+ // Force a refresh on this column, because the wrapText checked value changed.
146
+ colData.actions = Object.assign({}, colData.actions);
147
+ }
148
+
149
+ /************************** HELPER FUNCTIONS **************************/
150
+
151
+ function isWrappableType(type) {
152
+ return NON_WRAPPABLE_TYPES.indexOf(type) < 0;
123
153
  }
@@ -9,7 +9,7 @@
9
9
  <lightning-helptext if:true={fieldLevelHelp} content={fieldLevelHelp}></lightning-helptext>
10
10
  <div class="slds-form-element__control">
11
11
  <div class="slds-dueling-list" onfocusin={handleFocus} onfocusout={handleBlur}>
12
- <div class="slds-assistive-text" id="assertive-thing" aria-live="assertive"></div>
12
+ <div class="slds-assistive-text" id="assertive-thing" aria-live="assertive">{_messageToDisplay}</div>
13
13
  <div class="slds-assistive-text" id="keyboard-interacton">{i18n.componentAssistiveText}</div>
14
14
  <div class={computedLeftColumnClass}>
15
15
  <span class="slds-form-element__label" id="source-list-label">{sourceLabel}</span>
@@ -14,6 +14,8 @@ import labelRequiredOptionError from '@salesforce/label/LightningDualListbox.req
14
14
  import labelUpButtonAssistiveText from '@salesforce/label/LightningDualListbox.upButtonAssistiveText';
15
15
  import labelMoveSelectionToAssistiveText from '@salesforce/label/LightningDualListbox.moveSelectionToAssistiveText';
16
16
  import labelLoadingText from '@salesforce/label/LightningCombobox.loadingText';
17
+ import labelMovedOptionsSingular from '@salesforce/label/LightningDualListbox.movedOptionsSingular';
18
+ import labelMovedOptionsPlural from '@salesforce/label/LightningDualListbox.movedOptionsPlural';
17
19
  import { LightningElement, api, track } from 'lwc';
18
20
  import { handleKeyDownOnOption } from './keyboard';
19
21
  import { classSet, formatLabel } from 'lightning/utils';
@@ -47,6 +49,8 @@ const i18n = {
47
49
  upButtonAssistiveText: labelUpButtonAssistiveText,
48
50
  moveSelectionToAssistiveText: labelMoveSelectionToAssistiveText,
49
51
  loadingText: labelLoadingText,
52
+ movedOptionsSingular: labelMovedOptionsSingular,
53
+ movedOptionsPlural: labelMovedOptionsPlural,
50
54
  };
51
55
 
52
56
  /**
@@ -117,6 +121,9 @@ export default class LightningDualListbox extends LightningElement {
117
121
  @track highlightedOptions = [];
118
122
  @track focusableInSource;
119
123
  @track focusableInSelected;
124
+ @track highlightedOptionsLabel = [];
125
+
126
+ _messageToDisplay = '';
120
127
 
121
128
  isFocusOnList = false;
122
129
 
@@ -705,6 +712,8 @@ export default class LightningDualListbox extends LightningElement {
705
712
  );
706
713
  }
707
714
 
715
+ this.movedOptions(addToSelect);
716
+
708
717
  const oldSelectedValues = this._selectedValues;
709
718
  this._selectedValues = newValues;
710
719
  const invalidMove =
@@ -730,6 +739,7 @@ export default class LightningDualListbox extends LightningElement {
730
739
  this.interactingState.leave();
731
740
  this.isFocusOnList = false;
732
741
  this.highlightedOptions = [];
742
+ this.highlightedOptionsLabel = [];
733
743
  this.optionToFocus = null;
734
744
  }
735
745
 
@@ -785,6 +795,7 @@ export default class LightningDualListbox extends LightningElement {
785
795
  const start = all ? options.length : this.lastSelected;
786
796
  let val, select;
787
797
  this.highlightedOptions = [];
798
+ this.highlightedOptionsLabel = [];
788
799
  for (let i = 0; i < options.length; i++) {
789
800
  select = (i - start) * (i - end) <= 0;
790
801
  if (select) {
@@ -889,6 +900,7 @@ export default class LightningDualListbox extends LightningElement {
889
900
  if (this.selectedList !== currentList || !isMultiple) {
890
901
  if (this.selectedList) {
891
902
  this.highlightedOptions = [];
903
+ this.highlightedOptionsLabel = [];
892
904
  this.lastSelected = -1;
893
905
  }
894
906
  this.selectedList = currentList;
@@ -1013,6 +1025,36 @@ export default class LightningDualListbox extends LightningElement {
1013
1025
  }
1014
1026
  if (!isSame) {
1015
1027
  this.highlightedOptions = [];
1028
+ this.highlightedOptionsLabel = [];
1029
+ }
1030
+ }
1031
+
1032
+ movedOptions(addToSelect) {
1033
+ const listName = addToSelect ? this.selectedLabel : this.sourceLabel;
1034
+
1035
+ for (let i = 0; i < this.highlightedOptions.length; i++) {
1036
+ let selectedOption = addToSelect
1037
+ ? this.computedSourceList.filter(
1038
+ (item) => item.value === this.highlightedOptions[i]
1039
+ )
1040
+ : this.computedSelectedList.filter(
1041
+ (item) => item.value === this.highlightedOptions[i]
1042
+ );
1043
+ this.highlightedOptionsLabel.push(selectedOption[0].label);
1044
+ }
1045
+
1046
+ if (this.highlightedOptions.length) {
1047
+ const strToFormat =
1048
+ this.highlightedOptions.length > 1
1049
+ ? i18n.movedOptionsPlural
1050
+ : i18n.movedOptionsSingular;
1051
+ this._messageToDisplay = formatLabel(
1052
+ strToFormat,
1053
+ this.highlightedOptionsLabel.join(', '),
1054
+ listName
1055
+ );
1056
+ } else {
1057
+ this._messageToDisplay = '';
1016
1058
  }
1017
1059
  }
1018
1060
  }
@@ -45,11 +45,11 @@ are specified, the component uses the default date format based on the user's lo
45
45
 
46
46
  The locale determines the order and format of the month, day, and year. For example, the English (United States) locale's date format is Oct 14, 2020 and the French (France) locale's date format is 14 Oct 2020. The locale doesn't determine the time zone. Time zone is a separate setting.
47
47
 
48
- The locale also determines whether to display time as 24-hour time or 12-hour time with AM and PM.
48
+ The locale also determines whether to display time as 24-hour time or 12-hour time with AM and PM. You can override the locale default with the `hour12` attribute. See _Date and Time Display Examples_ for more information.
49
49
 
50
- Specify optional attributes to modify the date and time display, overriding the locale's default formatting.
50
+ Specify optional attributes listed in the Specification tab to modify the date and time display, overriding the locale's default formatting.
51
51
 
52
- In the Component Library's Playground and the Mini-Playground in the Examples tab, the component is limited to the en-US locale.
52
+ In the Mini-Playground in the Examples tab, the component is limited to the en-US locale.
53
53
 
54
54
  #### Time Zone Considerations
55
55
 
@@ -132,6 +132,35 @@ Displays: 1/11/2019, 6:53 PM EST
132
132
  </template>
133
133
  ```
134
134
 
135
+ Displays: 1/11/2019, 18:53 EST
136
+
137
+ ```html
138
+ <template>
139
+ <lightning-formatted-date-time
140
+ value="1547250828000"
141
+ year="numeric"
142
+ month="numeric"
143
+ day="numeric"
144
+ hour="2-digit"
145
+ hour12={ampm}
146
+ minute="2-digit"
147
+ time-zone-name="short"
148
+ time-zone="America/New_York"
149
+ >
150
+ </lightning-formatted-date-time>
151
+ </template>
152
+ ```
153
+
154
+ Set the `hour12` attribute using a variable. If set to `false` or any other string directly, the component interprets its value as true.
155
+
156
+ ```js
157
+ import { LightningElement } from 'lwc';
158
+
159
+ export default class FormattedDateTimeHour12 extends LightningElement {
160
+ ampm = false;
161
+ }
162
+ ```
163
+
135
164
  #### Date and Time Stored in Salesforce
136
165
 
137
166
  Salesforce uses the ISO8601 format `YYYY-MM-DD` to store date fields, which store a date without time, and includes no time zone information.
@@ -186,6 +215,10 @@ Displays: December 03, 2017, 12:00 PM
186
215
  </template>
187
216
  ```
188
217
 
218
+ #### Usage Considerations
219
+
220
+ This component has usage differences from its Aura counterpart. See [Base Components: Aura Vs Lightning Web Components](docs/component-library/documentation/lwc/lwc.migrate_map_aura_lwc_components) in the Lightning Web Components Developer Guide.
221
+
189
222
  #### Source Code
190
223
 
191
224
  `lightning-formatted-date-time` is available in the [Base Components Recipes GitHub repository](https://github.com/salesforce/base-components-recipes#documentation). It's transpiled into the `c` namespace so that you can use it in your own projects.
@@ -4,8 +4,8 @@
4
4
  <p><lightning-formatted-date-time value="1547250828000" year="2-digit" month="short" day="2-digit" hour="numeric"
5
5
  weekday="long" era="short"></lightning-formatted-date-time></p>
6
6
  <p><lightning-formatted-date-time value="1547250828000" year="numeric" month="numeric" day="numeric" hour="2-digit"
7
- minute="2-digit" time-zone-name="short" hour12="true"></lightning-formatted-date-time></p>
7
+ minute="2-digit" time-zone-name="short"></lightning-formatted-date-time></p>
8
8
  <p><lightning-formatted-date-time value="1547250828000" year="numeric" month="numeric" day="numeric" hour="2-digit"
9
- minute="2-digit" time-zone="UTC" time-zone-name="short" hour12="false"></lightning-formatted-date-time></p>
9
+ minute="2-digit" time-zone="UTC" time-zone-name="short" hour12={ampm}></lightning-formatted-date-time></p>
10
10
  </div>
11
11
  </template>
@@ -1,3 +1,5 @@
1
1
  import { LightningElement } from 'lwc';
2
2
 
3
- export default class FormattedDateTimeDateTime extends LightningElement {}
3
+ export default class FormattedDateTimeDateTime extends LightningElement {
4
+ ampm = false;
5
+ }
@@ -5,7 +5,7 @@
5
5
  <p><lightning-formatted-date-time value="1547250828000" hour="2-digit" second="2-digit"></lightning-formatted-date-time></p>
6
6
  <p><lightning-formatted-date-time value="1547250828000" hour="2-digit" minute="2-digit" time-zone="UTC"
7
7
  time-zone-name="short"></lightning-formatted-date-time></p>
8
- <p><lightning-formatted-date-time value="1547250828000" hour="2-digit" minute="2-digit" second="2-digit" hour12="false"
8
+ <p><lightning-formatted-date-time value="1547250828000" hour="2-digit" minute="2-digit" second="2-digit" hour12={ampm}
9
9
  time-zone-name="long"></lightning-formatted-date-time></p>
10
10
  </div>
11
11
  </template>
@@ -1,3 +1,5 @@
1
1
  import { LightningElement } from 'lwc';
2
2
 
3
- export default class FormattedDateTimeTime extends LightningElement {}
3
+ export default class FormattedDateTimeTime extends LightningElement {
4
+ ampm = false;
5
+ }
@@ -92,6 +92,7 @@ export default class LightningFormattedDateTime extends LightningElement {
92
92
 
93
93
  /**
94
94
  * Determines whether time is displayed as 12-hour. If false, time displays as 24-hour. The default setting is determined by the user's locale.
95
+ * Set the value using a variable. If set to any string directly, the component interprets its value as true.
95
96
  * @type {boolean}
96
97
  *
97
98
  */
@@ -186,7 +186,7 @@
186
186
  required={required}
187
187
  readonly={readOnly}
188
188
  disabled={disabled}>
189
- <label id="file-selector-label" data-file-selector-label for="input-file"
189
+ <label id="file-selector-label" data-file-selector-label for="input-file" aria-hidden="true"
190
190
  class="slds-file-selector__body">
191
191
  <span class="slds-file-selector__button slds-button slds-button_neutral">
192
192
  <lightning-primitive-icon icon-name="utility:upload" variant="bare" svg-class="slds-button__icon slds-button__icon_left">
@@ -202,7 +202,6 @@
202
202
  </div>
203
203
  </template>
204
204
 
205
-
206
205
  <template if:true={isTypeColor}>
207
206
  <div class="slds-color-picker">
208
207
  <div class="slds-form-element slds-color-picker__summary">
@@ -213,6 +212,7 @@
213
212
  </template>
214
213
  {label}
215
214
  </label>
215
+ <lightning-helptext if:true={fieldLevelHelp} content={fieldLevelHelp} alternative-text={helptextAlternativeText}></lightning-helptext>
216
216
  </template>
217
217
  <div class="slds-form-element__control">
218
218
  <lightning-primitive-colorpicker-button
@@ -239,9 +239,6 @@
239
239
  oninput={handleInput}>
240
240
  </div>
241
241
  </div>
242
- <template if:false={hasExternalLabel}>
243
- <lightning-helptext if:true={fieldLevelHelp} content={fieldLevelHelp} alternative-text={helptextAlternativeText}></lightning-helptext>
244
- </template>
245
242
  </div>
246
243
  </div>
247
244
  </template>
@@ -7,6 +7,7 @@ import labelTooLong from '@salesforce/label/LightningErrorMessage.validityTooLon
7
7
  import labelTooShort from '@salesforce/label/LightningErrorMessage.validityTooShort';
8
8
  import labelTypeMismatch from '@salesforce/label/LightningErrorMessage.validityTypeMismatch';
9
9
  import labelValueMissing from '@salesforce/label/LightningErrorMessage.validityValueMissing';
10
+ import labelSelectAtleastOneValue from '@salesforce/label/LightningErrorMessage.validitySelectAtleastOne';
10
11
  import { assert } from 'lightning/utilsPrivate';
11
12
 
12
13
  const constraintsSortedByPriority = [
@@ -20,6 +21,7 @@ const constraintsSortedByPriority = [
20
21
  'tooShort',
21
22
  'typeMismatch',
22
23
  'valueMissing',
24
+ 'selectAtleastOneValue',
23
25
  ];
24
26
 
25
27
  const defaultLabels = {
@@ -33,6 +35,7 @@ const defaultLabels = {
33
35
  tooShort: labelTooShort,
34
36
  typeMismatch: labelTypeMismatch,
35
37
  valueMissing: labelValueMissing,
38
+ selectAtleastOneValue: labelSelectAtleastOneValue,
36
39
  };
37
40
 
38
41
  function resolveBestMatch(validity) {
@@ -103,6 +106,12 @@ function newValidityState(constraintsProvider) {
103
106
  get badInput() {
104
107
  return computeConstraint(constraintsProvider, 'badInput');
105
108
  }
109
+ get selectAtleastOneValue() {
110
+ return computeConstraint(
111
+ constraintsProvider,
112
+ 'validitySelectAtleastOneValue'
113
+ );
114
+ }
106
115
 
107
116
  get valid() {
108
117
  return !(
@@ -115,7 +124,8 @@ function newValidityState(constraintsProvider) {
115
124
  this.rangeOverflow ||
116
125
  this.stepMismatch ||
117
126
  this.customError ||
118
- this.badInput
127
+ this.badInput ||
128
+ this.selectAtleastOneValue
119
129
  );
120
130
  }
121
131
  }
@@ -200,6 +210,7 @@ export class FieldConstraintApi {
200
210
  tooLong: this.inputComponent.messageWhenTooLong,
201
211
  typeMismatch: this.inputComponent.messageWhenTypeMismatch,
202
212
  valueMissing: this.inputComponent.messageWhenValueMissing,
213
+ selectAtleastOneValue: this.inputComponent.messageWhenValueMissing,
203
214
  });
204
215
  }
205
216
 
@@ -14,6 +14,7 @@ selections when filtering a list, such as from a multi-select picklist.
14
14
  To specify the pills, set the `items` attribute to an array of values in your component's JavaScript.
15
15
 
16
16
  By default, all pills in the container are displayed and wrap to additional lines if they can't fit on one line.
17
+ For information about changing the behavior, see **Managing Pill Layout in the Container**.
17
18
 
18
19
  This example creates three pills: a text-only pill, a pill with an avatar, and
19
20
  a pill with an icon.
@@ -70,7 +71,7 @@ To create a pill with an avatar, use the following attributes.
70
71
  To create a pill with an icon, use the following attributes.
71
72
 
72
73
  - `type`: The media type. Use `icon`.
73
- - `iconName`: Required. The Lightning Design System name of the icon. Names are written in the format '\utility:down\' where 'utility' is the category, and 'down' is the specific icon to be displayed. Only utility icons can be used in this component.
74
+ - `iconName`: Required. The Lightning Design System name of the icon. Names are written in the format 'utility:down' where 'utility' is the category, and 'down' is the specific icon to be displayed. Only utility icons can be used for the `iconName`.
74
75
  - `alternativeText`: The alternative text used to describe the icon. Describe what happens when you click the button, for example 'Upload File', not what the icon looks like, 'Paperclip'.
75
76
 
76
77
  `lightning-pill-container` provides two variants: `bare` and `standard` (default). They are visually the same. However, the `standard` variant renders pills in an unordered list element. For more information, see the **Accessibility** section.
@@ -135,9 +136,12 @@ set to false by default, which makes all pills display and wrap to multiple line
135
136
  - `single-line`: Specifies that the pill container can display one line of pills. By default, if pills can't fit on one line, they are wrapped to additional lines to fit the container. Set `single-line` to true to limit pill display to one line. This attribute overrides `is-collapsible` and `is-expanded`.
136
137
 
137
138
  If all pills aren't displayed, the component shows a text button indicating how many more pills there are.
139
+ For example, if there are five more pills that aren’t displayed, the text button shows `+5 more`. The text button fires the `focus` event when you click it.
138
140
 
139
141
  To display a long list of pills as collapsed, set `is-collapsible` to true and optionally set `is-expanded` to false. Otherwise, pills are displayed expanded.
140
142
 
143
+ ##### Expand and Collapse Pills Programmatically
144
+
141
145
  Use `is-collapsible` and `is-expanded` to programmatically expand and collapse the pills.
142
146
 
143
147
  This example sets `is-collapsible` and uses a button to change the value of `is-expanded`.
@@ -175,6 +179,46 @@ export default class PillContainerCanCollapse extends LightningElement {
175
179
  ];
176
180
  }
177
181
  ```
182
+ ##### Display All Pills With the `+n more` Button
183
+
184
+ If all pills aren't displayed, the component shows a text button labeled `+n more` to indicate more pills can be displayed. By default, `lightning-pill-container` doesn’t handle the `focus` event that’s fired when you click the button. You can handle the event to display more pills or write logic to do something else when the button is clicked.
185
+
186
+ This example sets the pills to be collapsible but not expanded and handles the focus event.
187
+
188
+ ```html
189
+ <template>
190
+ <div style="width: 600px">
191
+ <lightning-pill-container
192
+ items={items}
193
+ is-collapsible={collapsible}
194
+ is-expanded={expanded}
195
+ onfocus={handlePillExpansion}
196
+ >
197
+ </lightning-pill-container>
198
+ </div>
199
+ </template>
200
+ ```
201
+
202
+ The list of pills is initially collapsed. When there are too many pills to be displayed, the text button labeled `+n more` displays. The handler for the `focus` event enables all the pills to display.
203
+
204
+ ```javascript
205
+ import { LightningElement } from 'lwc';
206
+
207
+ export default class PillContainerMoreButtonExpands extends LightningElement {
208
+ collapsible = true;
209
+ expanded = false;
210
+
211
+ handlePillExpansion(){
212
+ this.expanded = true;
213
+ }
214
+
215
+ items = [
216
+ {
217
+ //define the pills
218
+ }
219
+ ];
220
+ }
221
+ ```
178
222
 
179
223
  #### Component Styling
180
224
 
@@ -131,50 +131,38 @@ function createRelationship(
131
131
  );
132
132
 
133
133
  const autoShrink = config.autoShrink.height || config.autoShrink.width;
134
- const modal = new OverlayDetector(originalConfig.target);
135
- if (
136
- (config.scrollableParentBound && scrollableParent) ||
137
- (modal.isInsideModal && modal.overlay && autoShrink)
138
- ) {
139
- let parent;
140
- if (config.scrollableParentBound && scrollableParent) {
141
- parent = normalizeElement(scrollableParent);
142
- } else if (modal.isInsideModal && modal.overlay) {
143
- parent = normalizeElement(modal.overlay);
144
- }
145
- if (parent) {
146
- const boxConfig = {
147
- element: config.element,
148
- enabled: config.enabled,
149
- target: createProxy(parent),
150
- align: {},
151
- targetAlign: {},
152
- pad: 3,
153
- boxDirections: {
154
- top: true,
155
- bottom: true,
156
- left: true,
157
- right: true,
158
- },
159
- };
160
-
161
- if (autoShrink) {
162
- const style = boxConfig.element.getNode().style;
163
- if (!style.minHeight) {
164
- style.minHeight = config.minHeight;
165
- boxConfig.element._removeMinHeight = true;
166
- }
167
-
168
- boxConfig.boxDirections = {
169
- top: !!config.autoShrink.height,
170
- bottom: !!config.autoShrink.height,
171
- left: !!config.autoShrink.width,
172
- right: !!config.autoShrink.width,
173
- };
174
- constraintList.push(new Constraint('shrinking box', boxConfig));
175
- } else {
176
- constraintList.push(new Constraint('bounding box', boxConfig));
134
+ if (config.scrollableParentBound && scrollableParent) {
135
+ const parent = normalizeElement(scrollableParent);
136
+ const boxConfig = {
137
+ element: config.element,
138
+ enabled: config.enabled,
139
+ target: createProxy(parent),
140
+ align: {},
141
+ targetAlign: {},
142
+ pad: 3,
143
+ boxDirections: {
144
+ top: true,
145
+ bottom: true,
146
+ left: true,
147
+ right: true,
148
+ },
149
+ };
150
+ if (autoShrink) {
151
+ const style = boxConfig.element.getNode().style;
152
+ if (!style.minHeight) {
153
+ style.minHeight = config.minHeight;
154
+ boxConfig.element._removeMinHeight = true;
177
155
  }
156
+
157
+ boxConfig.boxDirections = {
158
+ top: !!config.autoShrink.height,
159
+ bottom: !!config.autoShrink.height,
160
+ left: !!config.autoShrink.width,
161
+ right: !!config.autoShrink.width,
162
+ };
163
+ constraintList.push(new Constraint('shrinking box', boxConfig));
164
+ } else {
165
+ constraintList.push(new Constraint('bounding box', boxConfig));
178
166
  }
179
167
  }
180
168