lightning-base-components 1.14.2-alpha → 1.14.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.
- package/metadata/raptor.json +1 -0
- package/package.json +17 -1
- 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/src/lightning/ariaObserver/__docs__/ariaObserver.md +142 -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/columns-shared.js +1 -1
- package/src/lightning/datatable/datatable.js +97 -24
- package/src/lightning/datatable/errors.js +20 -9
- package/src/lightning/datatable/headerActions.js +77 -49
- package/src/lightning/datatable/inlineEdit.js +505 -370
- package/src/lightning/datatable/inlineEditShared.js +24 -0
- package/src/lightning/datatable/keyboard.js +1 -1
- package/src/lightning/datatable/renderManager.js +241 -129
- 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 +16 -5
- package/src/lightning/datatable/state.js +10 -1
- package/src/lightning/datatable/templates/div/div.css +4 -0
- package/src/lightning/datatable/templates/div/div.html +1 -0
- package/src/lightning/datatable/utils.js +14 -0
- package/src/lightning/dualListbox/dualListbox.html +1 -1
- package/src/lightning/dualListbox/dualListbox.js +42 -0
- 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/staticMap/staticMap.html +1 -0
- package/src/lightning/staticMap/staticMap.js +39 -2
- package/src/lightning/utils/classSet.js +4 -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
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file exists in order to get around circular dependencies.
|
|
3
|
+
* In this case, rowSelection.js has a dependency on rows.js;
|
|
4
|
+
* but rows.js also has a dependency on rowSelection.js for
|
|
5
|
+
* `isSelectedRow()` among others.
|
|
6
|
+
*
|
|
7
|
+
* We split out the functions that could cause circular dependencies with
|
|
8
|
+
* `rowSelection.js` into the `*Shared.js` files.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Returns whether or not the row is selected using the state and the rowKeyValue
|
|
13
|
+
* The state maintains the list of selected rows from which
|
|
14
|
+
* this value can be retrieved.
|
|
15
|
+
*
|
|
16
|
+
* @param {Object} state - datatable state object
|
|
17
|
+
* @param {String} rowKeyValue
|
|
18
|
+
* @returns
|
|
19
|
+
*/
|
|
20
|
+
export function isSelectedRow(state, rowKeyValue) {
|
|
21
|
+
return !!state.selectedRowsKeys[rowKeyValue];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Returns whether the row (whose row key value is specified)
|
|
26
|
+
* should be disabled or not.
|
|
27
|
+
* Should not disable if the row is selected.
|
|
28
|
+
* If the particular row is not selected, the row should be disabled
|
|
29
|
+
* when max-row-selection > 1 and the selection limit is reached
|
|
30
|
+
*
|
|
31
|
+
* Note: Do not disable selection when max-row-selection = 1 and
|
|
32
|
+
* a row has been selected.
|
|
33
|
+
*
|
|
34
|
+
* @param {Object} state
|
|
35
|
+
* @param {String} rowKeyValue
|
|
36
|
+
* @returns {Boolean} whether the row should be disabled or not
|
|
37
|
+
*/
|
|
38
|
+
export function isDisabledRow(state, rowKeyValue) {
|
|
39
|
+
if (!isSelectedRow(state, rowKeyValue)) {
|
|
40
|
+
const maxRowSelection = getMaxRowSelection(state);
|
|
41
|
+
|
|
42
|
+
// when selection is 1, we should not disable selection
|
|
43
|
+
return (
|
|
44
|
+
maxRowSelection !== 1 &&
|
|
45
|
+
getCurrentSelectionLength(state) === maxRowSelection
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Returns which input type to use for row selection.
|
|
54
|
+
* If max-row-selection = 1, use radio buttons,
|
|
55
|
+
* otherwise, use checkboxes.
|
|
56
|
+
*
|
|
57
|
+
* @param {Object} state - datatable's state object
|
|
58
|
+
* @returns
|
|
59
|
+
*/
|
|
60
|
+
export function getRowSelectionInputType(state) {
|
|
61
|
+
if (getMaxRowSelection(state) === 1) {
|
|
62
|
+
return 'radio';
|
|
63
|
+
}
|
|
64
|
+
return 'checkbox';
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function getMaxRowSelection(state) {
|
|
68
|
+
return state.maxRowSelection;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function getCurrentSelectionLength(state) {
|
|
72
|
+
return getSelectedRowsKeys(state).length;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function getSelectedRowsKeys(state) {
|
|
76
|
+
return Object.keys(state.selectedRowsKeys).filter(
|
|
77
|
+
(key) => state.selectedRowsKeys[key]
|
|
78
|
+
);
|
|
79
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { assert } from 'lightning/utilsPrivate';
|
|
2
|
-
import { classSet, isObjectLike } from './utils';
|
|
2
|
+
import { classSet, isObjectLike, styleToString } from './utils';
|
|
3
3
|
import { isTreeType, getAttributesNames } from './types';
|
|
4
4
|
import {
|
|
5
5
|
isSelectedRow,
|
|
6
6
|
isDisabledRow,
|
|
7
7
|
getRowSelectionInputType,
|
|
8
|
-
} from './
|
|
8
|
+
} from './rowSelectionShared';
|
|
9
9
|
import { getTreeStateIndicatorFieldNames, getStateTreeColumn } from './tree';
|
|
10
10
|
import {
|
|
11
11
|
getColumns,
|
|
@@ -17,7 +17,8 @@ import {
|
|
|
17
17
|
} from './columns';
|
|
18
18
|
import { isRowNumberColumn, getRowNumberErrorColumnDef } from './rowNumber';
|
|
19
19
|
import { getRowError } from './errors';
|
|
20
|
-
import {
|
|
20
|
+
import { getDirtyValueFromCell } from './inlineEditShared';
|
|
21
|
+
import { DEFAULT_ROW_HEIGHT } from './renderManager';
|
|
21
22
|
|
|
22
23
|
export function getData(state) {
|
|
23
24
|
return state.data;
|
|
@@ -114,7 +115,7 @@ export function uniqueRowKeyGenerator(keyField) {
|
|
|
114
115
|
* @param {object} state - the current datatable state
|
|
115
116
|
*/
|
|
116
117
|
export function updateRowsAndCellIndexes() {
|
|
117
|
-
const { state, privateTypes: types } = this;
|
|
118
|
+
const { state, privateTypes: types, _virtualize } = this;
|
|
118
119
|
const { keyField, renderModeRoleBased } = state;
|
|
119
120
|
const data = getData(state);
|
|
120
121
|
const columns = getColumns(state);
|
|
@@ -141,11 +142,21 @@ export function updateRowsAndCellIndexes() {
|
|
|
141
142
|
row.classnames = resolveRowClassNames(row);
|
|
142
143
|
Object.assign(row, getRowStateForTree(rowData, state));
|
|
143
144
|
row.tabIndex = -1;
|
|
145
|
+
if (_virtualize) {
|
|
146
|
+
row.style = styleToString({
|
|
147
|
+
position: 'absolute',
|
|
148
|
+
top: `${rowIndex * DEFAULT_ROW_HEIGHT}px`,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
144
151
|
|
|
145
152
|
columns.reduce((currentRow, colData, colIndex) => {
|
|
146
153
|
const { fieldName } = colData;
|
|
147
154
|
const colKeyValue = generateColKeyValue(colData, colIndex);
|
|
148
|
-
const dirtyValue =
|
|
155
|
+
const dirtyValue = getDirtyValueFromCell(
|
|
156
|
+
state,
|
|
157
|
+
row.key,
|
|
158
|
+
colKeyValue
|
|
159
|
+
);
|
|
149
160
|
const cellHasErrors = hasCellErrors(
|
|
150
161
|
rowErrors,
|
|
151
162
|
colData.fieldName,
|
|
@@ -17,8 +17,9 @@ export const getDefaultState = function () {
|
|
|
17
17
|
rows: [],
|
|
18
18
|
indexes: {},
|
|
19
19
|
|
|
20
|
-
//
|
|
20
|
+
// row selection
|
|
21
21
|
selectedRowsKeys: {},
|
|
22
|
+
lastSelectedRowKey: undefined,
|
|
22
23
|
maxRowSelection: undefined,
|
|
23
24
|
|
|
24
25
|
headerIndexes: {},
|
|
@@ -59,7 +60,15 @@ export const getDefaultState = function () {
|
|
|
59
60
|
|
|
60
61
|
// inline edit
|
|
61
62
|
inlineEdit: {
|
|
63
|
+
rowKeyValue: undefined,
|
|
64
|
+
colKeyValue: undefined,
|
|
65
|
+
columnDef: {},
|
|
62
66
|
dirtyValues: {},
|
|
67
|
+
editedValue: undefined,
|
|
68
|
+
isPanelVisible: false,
|
|
69
|
+
massEditEnabled: false,
|
|
70
|
+
massEditSelectedRows: undefined,
|
|
71
|
+
resolvedAttributeTypes: {},
|
|
63
72
|
},
|
|
64
73
|
|
|
65
74
|
// errors
|
|
@@ -109,3 +109,17 @@ export function getScrollOffsetFromTableEnd(el) {
|
|
|
109
109
|
el.scrollHeight - el.parentNode.scrollTop - el.parentNode.clientHeight
|
|
110
110
|
);
|
|
111
111
|
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Utility for converting arrays and plain objects to style strings
|
|
115
|
+
* @param {Array|Object} style
|
|
116
|
+
* @returns {string} representing array/object as a string
|
|
117
|
+
*/
|
|
118
|
+
export function styleToString(style) {
|
|
119
|
+
if (!Array.isArray(style)) {
|
|
120
|
+
return Object.entries(style)
|
|
121
|
+
.map(([key, value]) => `${key}:${value}`)
|
|
122
|
+
.join(';');
|
|
123
|
+
}
|
|
124
|
+
return style.join(';');
|
|
125
|
+
}
|
|
@@ -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
|
}
|
|
@@ -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
|
|
|
@@ -21,28 +21,33 @@ const i18n = {
|
|
|
21
21
|
showActions: labelShowActions,
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
+
/**
|
|
25
|
+
* A cell-level action.
|
|
26
|
+
*/
|
|
24
27
|
export default class PrimitiveCellActions extends LightningElement {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
@api rowKeyValue;
|
|
28
|
-
@api colKeyValue;
|
|
29
|
-
@api rowActions;
|
|
30
|
-
|
|
28
|
+
// Tracked objects
|
|
31
29
|
@track containerRect;
|
|
32
30
|
@track _actions = [];
|
|
33
31
|
|
|
32
|
+
// Private variables
|
|
33
|
+
static delegatesFocus = true;
|
|
34
34
|
_isLoadingActions;
|
|
35
35
|
_menuAlignment = DEFAULT_MENU_ALIGNMENT;
|
|
36
36
|
_internalTabIndex = false;
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
this._connected = true;
|
|
40
|
-
}
|
|
38
|
+
/************************** PUBLIC ATTRIBUTES ***************************/
|
|
41
39
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
@api rowKeyValue;
|
|
41
|
+
@api colKeyValue;
|
|
42
|
+
@api rowActions;
|
|
45
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Defines the current menu alignment
|
|
46
|
+
* See `VALID_MENU_ALIGNMENT` for valid menu alignment values
|
|
47
|
+
* See `DEFAULT_MENU_ALIGNMENT` for the default menu alignment
|
|
48
|
+
*
|
|
49
|
+
* @type {string}
|
|
50
|
+
*/
|
|
46
51
|
@api
|
|
47
52
|
get menuAlignment() {
|
|
48
53
|
return this._menuAlignment;
|
|
@@ -55,6 +60,11 @@ export default class PrimitiveCellActions extends LightningElement {
|
|
|
55
60
|
});
|
|
56
61
|
}
|
|
57
62
|
|
|
63
|
+
/************************** PUBLIC METHODS ***************************/
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Sets focus on a lightning-button-menu
|
|
67
|
+
*/
|
|
58
68
|
@api
|
|
59
69
|
focus() {
|
|
60
70
|
if (this._connected) {
|
|
@@ -62,6 +72,9 @@ export default class PrimitiveCellActions extends LightningElement {
|
|
|
62
72
|
}
|
|
63
73
|
}
|
|
64
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Clicks a lightning-button-menu
|
|
77
|
+
*/
|
|
65
78
|
@api
|
|
66
79
|
click() {
|
|
67
80
|
if (this._connected) {
|
|
@@ -73,18 +86,42 @@ export default class PrimitiveCellActions extends LightningElement {
|
|
|
73
86
|
}
|
|
74
87
|
}
|
|
75
88
|
|
|
89
|
+
/************************** PRIVATE GETTERS **************************/
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Returns the computed menu alignment value
|
|
93
|
+
*
|
|
94
|
+
* @return {string} Current computed menu alignment
|
|
95
|
+
*/
|
|
76
96
|
get computedMenuAlignment() {
|
|
77
97
|
return this.menuAlignment;
|
|
78
98
|
}
|
|
79
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Returns the button alternative text in the appropriate language
|
|
102
|
+
*
|
|
103
|
+
* @return {string} Language-specific button alternative text
|
|
104
|
+
*/
|
|
80
105
|
get buttonAlternateText() {
|
|
81
106
|
return `${i18n.showActions}`;
|
|
82
107
|
}
|
|
83
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Returns the spinner alternative text in the appropriate language
|
|
111
|
+
*
|
|
112
|
+
* @return {string} Language-specific spinner alternative text
|
|
113
|
+
*/
|
|
84
114
|
get spinnerAlternateText() {
|
|
85
115
|
return `${i18n.loadingActions}`;
|
|
86
116
|
}
|
|
87
117
|
|
|
118
|
+
/************************ EVENT DISPATCHERS **************************/
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Handles selecting an action
|
|
122
|
+
*
|
|
123
|
+
* @param {Event} event
|
|
124
|
+
*/
|
|
88
125
|
handleActionSelect(event) {
|
|
89
126
|
this.dispatchEvent(
|
|
90
127
|
new CustomEvent('privatecellactiontriggered', {
|
|
@@ -100,6 +137,9 @@ export default class PrimitiveCellActions extends LightningElement {
|
|
|
100
137
|
);
|
|
101
138
|
}
|
|
102
139
|
|
|
140
|
+
/**
|
|
141
|
+
* Handles the opening of an action menu
|
|
142
|
+
*/
|
|
103
143
|
handleMenuOpen() {
|
|
104
144
|
this.elementRect = this.template
|
|
105
145
|
.querySelector('lightning-button-menu')
|
|
@@ -135,6 +175,23 @@ export default class PrimitiveCellActions extends LightningElement {
|
|
|
135
175
|
}
|
|
136
176
|
}
|
|
137
177
|
|
|
178
|
+
/************************** LIFECYCLE HOOKS **************************/
|
|
179
|
+
|
|
180
|
+
connectedCallback() {
|
|
181
|
+
this._connected = true;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
disconnectedCallback() {
|
|
185
|
+
this._connected = false;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/************************* HELPER FUNCTIONS **************************/
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Resets loading state when all actions have been loaded
|
|
192
|
+
*
|
|
193
|
+
* @param {object} actions - Actions displayed in the menu
|
|
194
|
+
*/
|
|
138
195
|
finishLoadingActions(actions) {
|
|
139
196
|
this._isLoadingActions = false;
|
|
140
197
|
this._actions = actions;
|