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.
- package/metadata/raptor.json +33 -1
- package/package.json +20 -4
- package/scopedImports/@salesforce-label-LightningDualListbox.movedOptionsPlural.js +1 -0
- package/scopedImports/@salesforce-label-LightningDualListbox.movedOptionsSingular.js +1 -0
- package/scopedImports/@salesforce-label-LightningErrorMessage.validitySelectAtleastOne.js +1 -0
- package/scopedImports/@salesforce-label-LightningMap.titleWithAddress.js +1 -0
- package/scopedImports/@salesforce-label-LightningModalBase.cancelandclose.js +1 -0
- package/src/lightning/ariaObserver/__component__/ariaObserver.spec.js +9 -0
- package/src/lightning/ariaObserver/__docs__/ariaObserver.md +142 -0
- package/src/lightning/ariaObserver/ariaObserver.js +24 -35
- package/src/lightning/baseFormattedText/baseFormattedText.html +6 -1
- package/src/lightning/baseFormattedText/baseFormattedText.js +5 -0
- package/src/lightning/buttonMenu/keyboard.js +0 -10
- package/src/lightning/card/card.html +6 -0
- package/src/lightning/checkboxGroup/checkboxGroup.html +2 -2
- package/src/lightning/checkboxGroup/checkboxGroup.js +6 -1
- package/src/lightning/colorPickerCustom/colorPickerCustom.js +20 -1
- package/src/lightning/datatable/__docs__/datatable.md +55 -0
- package/src/lightning/datatable/__examples__/basic/basic.html +1 -1
- package/src/lightning/datatable/__examples__/withInfiniteLoading/fetchDataHelper.js +21 -0
- package/src/lightning/datatable/__examples__/withInfiniteLoading/withInfiniteLoading.html +13 -0
- package/src/lightning/datatable/__examples__/withInfiniteLoading/withInfiniteLoading.js +42 -0
- package/src/lightning/datatable/autoWidthStrategy.js +170 -61
- package/src/lightning/datatable/{resizer.js → columnResizer.js} +0 -0
- package/src/lightning/datatable/columnWidthManager.js +226 -44
- package/src/lightning/datatable/columns-shared.js +1 -1
- package/src/lightning/datatable/datatable.js +104 -33
- package/src/lightning/datatable/errors.js +20 -9
- package/src/lightning/datatable/fixedWidthStrategy.js +43 -8
- package/src/lightning/datatable/headerActions.js +77 -49
- package/src/lightning/datatable/infiniteLoading.js +100 -28
- package/src/lightning/datatable/inlineEdit.js +505 -379
- package/src/lightning/datatable/inlineEditShared.js +24 -0
- package/src/lightning/datatable/keyboard.js +162 -127
- package/src/lightning/datatable/renderManager.js +208 -133
- package/src/lightning/datatable/{datatableResizeObserver.js → resizeObserver.js} +46 -29
- package/src/lightning/datatable/resizeSensor.js +8 -0
- package/src/lightning/datatable/rowLevelActions.js +17 -13
- package/src/lightning/datatable/rowNumber.js +54 -20
- package/src/lightning/datatable/rowSelection.js +760 -0
- package/src/lightning/datatable/rowSelectionShared.js +79 -0
- package/src/lightning/datatable/rows.js +17 -6
- package/src/lightning/datatable/state.js +16 -2
- package/src/lightning/datatable/templates/div/div.css +4 -0
- package/src/lightning/datatable/templates/div/div.html +128 -117
- package/src/lightning/datatable/templates/table/table.html +5 -0
- package/src/lightning/datatable/utils.js +14 -0
- package/src/lightning/datatable/widthManagerShared.js +27 -3
- package/src/lightning/datatable/wrapText.js +77 -47
- package/src/lightning/dualListbox/dualListbox.html +1 -1
- package/src/lightning/dualListbox/dualListbox.js +42 -0
- package/src/lightning/formattedDateTime/__docs__/formattedDateTime.md +36 -3
- package/src/lightning/formattedDateTime/__examples__/datetime/datetime.html +2 -2
- package/src/lightning/formattedDateTime/__examples__/datetime/datetime.js +3 -1
- package/src/lightning/formattedDateTime/__examples__/time/time.html +1 -1
- package/src/lightning/formattedDateTime/__examples__/time/time.js +3 -1
- package/src/lightning/formattedDateTime/formattedDateTime.js +1 -0
- package/src/lightning/input/input.html +2 -5
- package/src/lightning/inputUtils/validity.js +12 -1
- package/src/lightning/pillContainer/__docs__/pillContainer.md +45 -1
- package/src/lightning/positionLibrary/positionLibrary.js +31 -43
- package/src/lightning/primitiveCellActions/primitiveCellActions.js +69 -12
- package/src/lightning/primitiveCellFactory/cellWithStandardLayout.html +13 -11
- package/src/lightning/primitiveCellFactory/primitiveCellFactory.js +13 -8
- package/src/lightning/primitiveDatatableIeditPanel/primitiveDatatableIeditPanel.html +17 -14
- package/src/lightning/primitiveDatatableIeditPanel/primitiveDatatableIeditPanel.js +167 -98
- package/src/lightning/primitiveDatatableIeditTypeFactory/primitiveDatatableIeditTypeFactory.js +94 -69
- package/src/lightning/primitiveDatatableStatusBar/primitiveDatatableStatusBar.html +4 -4
- package/src/lightning/primitiveDatatableStatusBar/primitiveDatatableStatusBar.js +4 -4
- package/src/lightning/primitiveHeaderActions/primitiveHeaderActions.js +99 -37
- package/src/lightning/progressIndicator/progressIndicator.js +1 -1
- package/src/lightning/progressStep/progressStep.js +1 -1
- package/src/lightning/spinner/spinner.html +1 -1
- package/src/lightning/spinner/spinner.js +12 -0
- package/src/lightning/staticMap/staticMap.html +1 -0
- package/src/lightning/staticMap/staticMap.js +39 -2
- package/src/lightning/utils/classSet.js +4 -1
- package/src/lightning/utilsPrivate/phonify.js +1 -1
- package/scopedImports/@salesforce-label-LightningModalBase.close.js +0 -1
- package/src/lightning/datatable/inlineEdit-shared.js +0 -14
- package/src/lightning/datatable/selector-shared.js +0 -38
- 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
|
|
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
|
-
|
|
24
|
-
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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 (
|
|
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
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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"
|
|
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
|
|
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"
|
|
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=
|
|
9
|
+
minute="2-digit" time-zone="UTC" time-zone-name="short" hour12={ampm}></lightning-formatted-date-time></p>
|
|
10
10
|
</div>
|
|
11
11
|
</template>
|
|
@@ -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=
|
|
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>
|
|
@@ -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 '
|
|
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
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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
|
|