lightning-base-components 1.14.3-alpha → 1.14.7-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/metadata/raptor.json +37 -4
- package/package.json +11 -4
- package/scopedImports/@salesforce-label-LightningModalBase.cancelandclose.js +1 -0
- package/scopedImports/@salesforce-label-LightningProgressBar.progressBar.js +1 -0
- package/src/lightning/alert/__docs__/alert.md +101 -0
- package/src/lightning/alert/__examples__disabled/basic/basic.css +7 -0
- package/src/lightning/alert/__examples__disabled/basic/basic.html +8 -0
- package/src/lightning/alert/__examples__disabled/basic/basic.js +14 -0
- package/src/lightning/alert/alert.html +3 -0
- package/src/lightning/alert/alert.js +78 -0
- package/src/lightning/alert/alert.js-meta.xml +6 -0
- package/src/lightning/ariaObserver/__component__/ariaObserver.spec.js +9 -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/buttonMenu.js +12 -0
- package/src/lightning/confirm/__docs__/confirm.md +100 -0
- package/src/lightning/confirm/__examples__disabled/basic/basic.css +7 -0
- package/src/lightning/confirm/__examples__disabled/basic/basic.html +8 -0
- package/src/lightning/confirm/__examples__disabled/basic/basic.js +14 -0
- package/src/lightning/confirm/confirm.html +3 -0
- package/src/lightning/confirm/confirm.js +80 -0
- package/src/lightning/confirm/confirm.js-meta.xml +6 -0
- 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.js +166 -71
- package/src/lightning/datatable/datatable.js +132 -60
- package/src/lightning/datatable/fixedWidthStrategy.js +43 -8
- package/src/lightning/datatable/headerActions.js +2 -2
- package/src/lightning/datatable/infiniteLoading.js +100 -28
- package/src/lightning/datatable/inlineEdit.js +21 -30
- package/src/lightning/datatable/keyboard.js +166 -131
- package/src/lightning/datatable/renderManager.js +117 -122
- package/src/lightning/datatable/{datatableResizeObserver.js → resizeObserver.js} +46 -29
- package/src/lightning/datatable/resizeSensor.js +19 -3
- package/src/lightning/datatable/rowSelection.js +1 -1
- package/src/lightning/datatable/rowSelectionShared.js +33 -20
- package/src/lightning/datatable/rows.js +7 -8
- package/src/lightning/datatable/sort.js +8 -8
- package/src/lightning/datatable/state.js +14 -2
- package/src/lightning/datatable/templates/div/div.html +127 -117
- package/src/lightning/datatable/templates/table/table.html +5 -0
- package/src/lightning/datatable/tree.js +25 -0
- package/src/lightning/datatable/types.js +77 -9
- package/src/lightning/datatable/utils.js +51 -24
- package/src/lightning/datatable/virtualization.js +319 -0
- package/src/lightning/datatable/widthManagerShared.js +27 -3
- package/src/lightning/datatable/wrapText.js +115 -48
- 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/iconSvgTemplates/buildTemplates/standard/dashboard_component.html +7 -0
- package/src/lightning/iconSvgTemplates/buildTemplates/standard/slack.html +7 -0
- package/src/lightning/iconSvgTemplates/buildTemplates/standard/tableau.html +7 -0
- package/src/lightning/iconSvgTemplates/buildTemplates/standard/travel_mode.html +2 -2
- package/src/lightning/iconSvgTemplates/buildTemplates/templates.js +8 -1
- package/src/lightning/iconSvgTemplates/buildTemplates/utility/data_model.html +7 -0
- package/src/lightning/iconSvgTemplates/buildTemplates/utility/serialized_product.html +1 -1
- package/src/lightning/iconSvgTemplates/buildTemplates/utility/serialized_product_transaction.html +2 -1
- package/src/lightning/iconSvgTemplates/buildTemplates/utility/slack.html +7 -0
- package/src/lightning/iconSvgTemplates/buildTemplates/utility/tableau.html +7 -0
- package/src/lightning/iconSvgTemplates/buildTemplates/utility/video_off.html +7 -0
- package/src/lightning/iconSvgTemplatesRtl/buildTemplates/standard/dashboard_component.html +7 -0
- package/src/lightning/iconSvgTemplatesRtl/buildTemplates/standard/slack.html +7 -0
- package/src/lightning/iconSvgTemplatesRtl/buildTemplates/standard/tableau.html +7 -0
- package/src/lightning/iconSvgTemplatesRtl/buildTemplates/standard/travel_mode.html +2 -2
- package/src/lightning/iconSvgTemplatesRtl/buildTemplates/templates.js +8 -1
- package/src/lightning/iconSvgTemplatesRtl/buildTemplates/utility/data_model.html +7 -0
- package/src/lightning/iconSvgTemplatesRtl/buildTemplates/utility/serialized_product.html +1 -1
- package/src/lightning/iconSvgTemplatesRtl/buildTemplates/utility/serialized_product_transaction.html +2 -1
- package/src/lightning/iconSvgTemplatesRtl/buildTemplates/utility/slack.html +7 -0
- package/src/lightning/iconSvgTemplatesRtl/buildTemplates/utility/tableau.html +7 -0
- package/src/lightning/iconSvgTemplatesRtl/buildTemplates/utility/video_off.html +7 -0
- package/src/lightning/iconSvgTemplatesStandard/buildTemplates/standard/dashboard_component.html +7 -0
- package/src/lightning/iconSvgTemplatesStandard/buildTemplates/standard/slack.html +7 -0
- package/src/lightning/iconSvgTemplatesStandard/buildTemplates/standard/tableau.html +7 -0
- package/src/lightning/iconSvgTemplatesStandard/buildTemplates/standard/travel_mode.html +2 -2
- package/src/lightning/iconSvgTemplatesStandard/buildTemplates/templates.js +4 -1
- package/src/lightning/iconSvgTemplatesStandardRtl/buildTemplates/standard/dashboard_component.html +7 -0
- package/src/lightning/iconSvgTemplatesStandardRtl/buildTemplates/standard/slack.html +7 -0
- package/src/lightning/iconSvgTemplatesStandardRtl/buildTemplates/standard/tableau.html +7 -0
- package/src/lightning/iconSvgTemplatesStandardRtl/buildTemplates/standard/travel_mode.html +2 -2
- package/src/lightning/iconSvgTemplatesStandardRtl/buildTemplates/templates.js +4 -1
- package/src/lightning/iconSvgTemplatesUtility/buildTemplates/templates.js +5 -1
- package/src/lightning/iconSvgTemplatesUtility/buildTemplates/utility/data_model.html +7 -0
- package/src/lightning/iconSvgTemplatesUtility/buildTemplates/utility/serialized_product.html +1 -1
- package/src/lightning/iconSvgTemplatesUtility/buildTemplates/utility/serialized_product_transaction.html +2 -1
- package/src/lightning/iconSvgTemplatesUtility/buildTemplates/utility/slack.html +7 -0
- package/src/lightning/iconSvgTemplatesUtility/buildTemplates/utility/tableau.html +7 -0
- package/src/lightning/iconSvgTemplatesUtility/buildTemplates/utility/video_off.html +7 -0
- package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/templates.js +5 -1
- package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/utility/data_model.html +7 -0
- package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/utility/serialized_product.html +1 -1
- package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/utility/serialized_product_transaction.html +2 -1
- package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/utility/slack.html +7 -0
- package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/utility/tableau.html +7 -0
- package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/utility/video_off.html +7 -0
- package/src/lightning/input/__docs__/input.md +2 -0
- package/src/lightning/input/input.html +2 -5
- package/src/lightning/interactiveDialogBase/interactiveDialogBase.css +494 -0
- package/src/lightning/interactiveDialogBase/interactiveDialogBase.html +63 -0
- package/src/lightning/interactiveDialogBase/interactiveDialogBase.js +200 -0
- package/src/lightning/menuItem/menuItem.js +4 -1
- package/src/lightning/modalBase/modalBase.css +20 -0
- package/src/lightning/modalBase/modalBase.html +54 -0
- package/src/lightning/modalBase/modalBase.js +1039 -0
- package/src/lightning/overlay/__docs__/overlay.md +90 -0
- package/src/lightning/overlay/__examples__/alert/alert.html +27 -0
- package/src/lightning/overlay/__examples__/alert/alert.js +33 -0
- package/src/lightning/overlay/__examples__/basic/basic.css +7 -0
- package/src/lightning/overlay/__examples__/basic/basic.html +18 -0
- package/src/lightning/overlay/__examples__/basic/basic.js +61 -0
- package/src/lightning/overlay/__examples__/demo/demo.html +29 -0
- package/src/lightning/overlay/__examples__/demo/demo.js +40 -0
- package/src/lightning/overlay/__examples__/panel/panel.html +17 -0
- package/src/lightning/overlay/__examples__/panel/panel.js +21 -0
- package/src/lightning/overlay/overlay.html +3 -0
- package/src/lightning/overlay/overlay.js +45 -0
- package/src/lightning/overlayContainer/__docs__/overlayContainer.md +0 -0
- package/src/lightning/overlayContainer/overlayContainer.html +3 -0
- package/src/lightning/overlayContainer/overlayContainer.js +138 -0
- package/src/lightning/overlayManager/overlayManager.js +54 -0
- package/src/lightning/overlayUtils/overlayUtils.js +17 -0
- package/src/lightning/progressBar/progressBar.html +2 -1
- package/src/lightning/progressBar/progressBar.js +18 -1
- package/src/lightning/prompt/__docs__/prompt.md +102 -0
- package/src/lightning/prompt/__examples__disabled/basic/basic.css +7 -0
- package/src/lightning/prompt/__examples__disabled/basic/basic.html +8 -0
- package/src/lightning/prompt/__examples__disabled/basic/basic.js +15 -0
- package/src/lightning/prompt/prompt.css +81 -0
- package/src/lightning/prompt/prompt.html +8 -0
- package/src/lightning/prompt/prompt.js +92 -0
- package/src/lightning/prompt/prompt.js-meta.xml +6 -0
- package/src/lightning/spinner/spinner.html +1 -1
- package/src/lightning/spinner/spinner.js +12 -0
- package/src/lightning/utilsPrivate/phonify.js +1 -1
- package/scopedImports/@salesforce-label-LightningModalBase.close.js +0 -1
|
@@ -102,35 +102,66 @@ const EDITABLE_STANDARD_TYPES = {
|
|
|
102
102
|
date: true,
|
|
103
103
|
};
|
|
104
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Determines if a supplied type is a valid datatable type.
|
|
107
|
+
*
|
|
108
|
+
* @param {String} typeName The type to validate
|
|
109
|
+
* @returns {Boolean} Whether the supplied type is valid
|
|
110
|
+
*/
|
|
105
111
|
export function isValidType(typeName) {
|
|
106
112
|
return !!STANDARD_TYPES[typeName];
|
|
107
113
|
}
|
|
108
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Determines if a supplied type is a tree type.
|
|
117
|
+
*
|
|
118
|
+
* @param {String} typeName The type to validate
|
|
119
|
+
* @returns {Boolean} Whether the supplied type is a tree type
|
|
120
|
+
*/
|
|
109
121
|
export function isTreeType(typeName) {
|
|
110
122
|
return typeName === 'tree';
|
|
111
123
|
}
|
|
112
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Determines if a supplied type is valid for a tree type datatable.
|
|
127
|
+
*
|
|
128
|
+
* @param {String} typeName The type to validate
|
|
129
|
+
* @returns {Boolean} Whether the supplied type is valid for a tree
|
|
130
|
+
*/
|
|
131
|
+
export function isValidTypeForTree(typeName) {
|
|
132
|
+
return !!TREE_SUPPORTED_TYPES[typeName];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Retrieves the attributes for a given type. Additionally, verifies
|
|
137
|
+
* the supplied type is valid.
|
|
138
|
+
*
|
|
139
|
+
* @param {String} typeName The type to get the attributes for
|
|
140
|
+
* @returns {Array} An array of attributes for the supplied type
|
|
141
|
+
*/
|
|
113
142
|
export function getAttributesNames(typeName) {
|
|
114
143
|
assert(
|
|
115
144
|
isValidType(typeName),
|
|
116
|
-
`
|
|
145
|
+
`You are trying to access an invalid type (${typeName})`
|
|
117
146
|
);
|
|
118
|
-
|
|
119
|
-
return Array.isArray(STANDARD_TYPES[typeName])
|
|
120
|
-
? STANDARD_TYPES[typeName]
|
|
121
|
-
: [];
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export function isValidTypeForTree(dataType) {
|
|
125
|
-
return !!TREE_SUPPORTED_TYPES[dataType];
|
|
147
|
+
return getStandardTypeAttributesNames(typeName);
|
|
126
148
|
}
|
|
127
149
|
|
|
150
|
+
/**
|
|
151
|
+
* Retrieves the attributes for a given type.
|
|
152
|
+
*
|
|
153
|
+
* @param {String} typeName The type to get the attributes for
|
|
154
|
+
* @returns {Array} An array of attributes for the supplied type
|
|
155
|
+
*/
|
|
128
156
|
function getStandardTypeAttributesNames(typeName) {
|
|
129
157
|
return Array.isArray(STANDARD_TYPES[typeName])
|
|
130
158
|
? STANDARD_TYPES[typeName]
|
|
131
159
|
: [];
|
|
132
160
|
}
|
|
133
161
|
|
|
162
|
+
/**
|
|
163
|
+
* A class for handling valid datatable types.
|
|
164
|
+
*/
|
|
134
165
|
export default class DatatableTypes {
|
|
135
166
|
privateCustomTypes = {};
|
|
136
167
|
isValidTypeForTree = isValidTypeForTree;
|
|
@@ -156,6 +187,13 @@ export default class DatatableTypes {
|
|
|
156
187
|
}
|
|
157
188
|
}
|
|
158
189
|
|
|
190
|
+
/**
|
|
191
|
+
* Retrieves a type. If the specified type is not a custom type,
|
|
192
|
+
* lookup the type in our standard types. Otherwise, return undefined.
|
|
193
|
+
*
|
|
194
|
+
* @param {String} typeName The type to retrieve
|
|
195
|
+
* @returns {Object | Undefined} The type metadata
|
|
196
|
+
*/
|
|
159
197
|
getType(typeName) {
|
|
160
198
|
if (this.privateCustomTypes[typeName]) {
|
|
161
199
|
return this.privateCustomTypes[typeName];
|
|
@@ -169,6 +207,12 @@ export default class DatatableTypes {
|
|
|
169
207
|
return undefined;
|
|
170
208
|
}
|
|
171
209
|
|
|
210
|
+
/**
|
|
211
|
+
* Retrieves a custom type's edit template if it exists.
|
|
212
|
+
*
|
|
213
|
+
* @param {String} typeName The custom type to retrieve
|
|
214
|
+
* @returns {Object | Undefined} The custom type's edit template
|
|
215
|
+
*/
|
|
172
216
|
getCustomTypeEditTemplate(typeName) {
|
|
173
217
|
if (this.privateCustomTypes[typeName]) {
|
|
174
218
|
return this.privateCustomTypes[typeName].editTemplate;
|
|
@@ -176,10 +220,22 @@ export default class DatatableTypes {
|
|
|
176
220
|
return undefined;
|
|
177
221
|
}
|
|
178
222
|
|
|
223
|
+
/**
|
|
224
|
+
* Determines if a type is a valid custom or standard type.
|
|
225
|
+
*
|
|
226
|
+
* @param {String} typeName The type to validate
|
|
227
|
+
* @returns {Boolean} Whether the type is valid
|
|
228
|
+
*/
|
|
179
229
|
isValidType(typeName) {
|
|
180
230
|
return !!this.getType(typeName);
|
|
181
231
|
}
|
|
182
232
|
|
|
233
|
+
/**
|
|
234
|
+
* Determines if a given type is editable.
|
|
235
|
+
*
|
|
236
|
+
* @param {String} typeName The type to test
|
|
237
|
+
* @returns {Boolean} Whether the type is editable
|
|
238
|
+
*/
|
|
183
239
|
isEditableType(typeName) {
|
|
184
240
|
return (
|
|
185
241
|
!!EDITABLE_STANDARD_TYPES[typeName] ||
|
|
@@ -187,12 +243,24 @@ export default class DatatableTypes {
|
|
|
187
243
|
);
|
|
188
244
|
}
|
|
189
245
|
|
|
246
|
+
/**
|
|
247
|
+
* Determines if a given type is a non-standard type.
|
|
248
|
+
*
|
|
249
|
+
* @param {String} typeName The type to test
|
|
250
|
+
* @returns {Boolean} Whether the type is a non-standard type
|
|
251
|
+
*/
|
|
190
252
|
isCustomType(typeName) {
|
|
191
253
|
return (
|
|
192
254
|
this.getType(typeName) && this.getType(typeName).type === 'custom'
|
|
193
255
|
);
|
|
194
256
|
}
|
|
195
257
|
|
|
258
|
+
/**
|
|
259
|
+
* Determines whether or not a given custom type is using a standard cell layout.
|
|
260
|
+
*
|
|
261
|
+
* @param {String} typeName The custom type to test
|
|
262
|
+
* @returns {Boolean} Whether the custom type is using a standard cell layout
|
|
263
|
+
*/
|
|
196
264
|
isStandardCellLayoutForCustomType(typeName) {
|
|
197
265
|
return (
|
|
198
266
|
this.isCustomType(typeName) &&
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
return typeof value === 'object' && value !== null;
|
|
3
|
-
};
|
|
4
|
-
|
|
5
|
-
const proto = {
|
|
1
|
+
const CLASSSET_PROTOTYPE = {
|
|
6
2
|
add(className) {
|
|
7
3
|
if (typeof className === 'string') {
|
|
8
4
|
this[className] = true;
|
|
@@ -24,32 +20,59 @@ const proto = {
|
|
|
24
20
|
},
|
|
25
21
|
};
|
|
26
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Determines if a given value is object-like.
|
|
25
|
+
*
|
|
26
|
+
* @param {*} value Any value to check for object-like status
|
|
27
|
+
* @returns {Boolean} Whether the value is object-like
|
|
28
|
+
*/
|
|
29
|
+
export const isObjectLike = function (value) {
|
|
30
|
+
return typeof value === 'object' && value !== null;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Creates an object of CSS class names based on a given config.
|
|
35
|
+
* Then, attaches an interface for managing the classes.
|
|
36
|
+
*
|
|
37
|
+
* @param {String | Object} config The initial class configuration
|
|
38
|
+
* @returns An interface, as defined in the `proto` method.
|
|
39
|
+
*/
|
|
27
40
|
export const classSet = function (config) {
|
|
28
41
|
if (typeof config === 'string') {
|
|
29
42
|
const key = config;
|
|
30
43
|
config = {};
|
|
31
44
|
config[key] = true;
|
|
32
45
|
}
|
|
33
|
-
return Object.assign(Object.create(
|
|
46
|
+
return Object.assign(Object.create(CLASSSET_PROTOTYPE), config);
|
|
34
47
|
};
|
|
35
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Clamps a value between a minimum and maximum value
|
|
51
|
+
*
|
|
52
|
+
* @param {Number} num The input number
|
|
53
|
+
* @param {Number} min The minimum value the number can be
|
|
54
|
+
* @param {Number} max The maximum value the number can be
|
|
55
|
+
* @returns The clamped number
|
|
56
|
+
*/
|
|
36
57
|
export const clamp = function (num, min, max) {
|
|
37
58
|
return num <= min ? min : num >= max ? max : num;
|
|
38
59
|
};
|
|
39
60
|
|
|
40
61
|
/**
|
|
41
|
-
* Tests if the value passed in is a value greater than 0
|
|
42
|
-
*
|
|
43
|
-
* @
|
|
62
|
+
* Tests if the value passed in is a value greater than 0.
|
|
63
|
+
*
|
|
64
|
+
* @param {Integer} value Value to test
|
|
65
|
+
* @returns {Boolean} Whether the value is greater than 0
|
|
44
66
|
*/
|
|
45
67
|
export const isPositiveInteger = function (value) {
|
|
46
68
|
return /^[0-9]*[1-9][0-9]*$/.test(value);
|
|
47
69
|
};
|
|
48
70
|
|
|
49
71
|
/**
|
|
50
|
-
* Tests if the value passed in is 0 or a number greater than 0
|
|
51
|
-
*
|
|
52
|
-
* @
|
|
72
|
+
* Tests if the value passed in is 0 or a number greater than 0.
|
|
73
|
+
*
|
|
74
|
+
* @param {Integer} value Value to test
|
|
75
|
+
* @returns {Boolean} Whether the value is greater than or equal to 0
|
|
53
76
|
*/
|
|
54
77
|
export const isNonNegativeInteger = function (value) {
|
|
55
78
|
return /^\d+$/.test(value);
|
|
@@ -62,11 +85,11 @@ export const isNonNegativeInteger = function (value) {
|
|
|
62
85
|
* b. numberType - non-negative: if value >= 0
|
|
63
86
|
* If the value fails the test, the fallback value is returned
|
|
64
87
|
*
|
|
65
|
-
* @param {String} attrName
|
|
66
|
-
* @param {Integer
|
|
67
|
-
* @param {String} numberType
|
|
68
|
-
* @param {Integer} fallback
|
|
69
|
-
* @returns {Integer}
|
|
88
|
+
* @param {String} attrName Name of attribute to normalize
|
|
89
|
+
* @param {Integer | String} value Value to normalize
|
|
90
|
+
* @param {String} numberType Number type to validate against: positive / non-negative
|
|
91
|
+
* @param {Integer} fallback Value to return if validation fails
|
|
92
|
+
* @returns {Integer} Returns normalized value if validation passes; else returns fallback
|
|
70
93
|
*/
|
|
71
94
|
export function normalizeNumberAttribute(
|
|
72
95
|
attrName,
|
|
@@ -98,11 +121,14 @@ export function normalizeNumberAttribute(
|
|
|
98
121
|
return fallback;
|
|
99
122
|
}
|
|
100
123
|
|
|
101
|
-
// TODO: move into scroller-specific utility when more scroll-related functionality
|
|
102
|
-
// needs to be shared between libraries
|
|
103
124
|
/**
|
|
104
|
-
* Utility for calculating the scroll offset
|
|
105
|
-
*
|
|
125
|
+
* Utility for calculating the scroll offset.
|
|
126
|
+
*
|
|
127
|
+
* TODO: move into scroller-specific utility when more scroll-related functionality
|
|
128
|
+
* needs to be shared between libraries.
|
|
129
|
+
*
|
|
130
|
+
* @param {HTMLElement} el Target element of the scroll
|
|
131
|
+
* @returns {Number} The scroll offset from the table's end
|
|
106
132
|
*/
|
|
107
133
|
export function getScrollOffsetFromTableEnd(el) {
|
|
108
134
|
return (
|
|
@@ -111,9 +137,10 @@ export function getScrollOffsetFromTableEnd(el) {
|
|
|
111
137
|
}
|
|
112
138
|
|
|
113
139
|
/**
|
|
114
|
-
* Utility for converting arrays and plain objects to style strings
|
|
115
|
-
*
|
|
116
|
-
* @
|
|
140
|
+
* Utility for converting arrays and plain objects to style strings.
|
|
141
|
+
*
|
|
142
|
+
* @param {Array | Object} style The CSS style array/object
|
|
143
|
+
* @returns {String} Representing array/object as a string
|
|
117
144
|
*/
|
|
118
145
|
export function styleToString(style) {
|
|
119
146
|
if (!Array.isArray(style)) {
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import { styleToString } from './utils';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* sets an initial table height in the datatable state
|
|
5
|
+
*
|
|
6
|
+
* @param {Object} state - datatable state
|
|
7
|
+
*/
|
|
8
|
+
export function resetTableHeight(state) {
|
|
9
|
+
state.tableHeight = state.rowHeight * state.rows.length;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* resets state properties relevant to virtualization
|
|
14
|
+
* rowHeights when fixedHeight is false
|
|
15
|
+
*
|
|
16
|
+
* @param {Object} state - datatable state
|
|
17
|
+
*/
|
|
18
|
+
export function resetRowHeights(state) {
|
|
19
|
+
state.heightCache = {};
|
|
20
|
+
state.offsets = [0];
|
|
21
|
+
state.offsetRanges = [];
|
|
22
|
+
if (state.virtualize && state.rows.length) {
|
|
23
|
+
resetTableHeight(state);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* updates state properties relevant to virtualization
|
|
29
|
+
* rowHeights when fixedHeight is false
|
|
30
|
+
*
|
|
31
|
+
* @param {Node} template - the custom element root `this.template` from datatable.js
|
|
32
|
+
* @param {Object} state - datatable state
|
|
33
|
+
* @param {Array} renderedRows - array of rows currently being rendered
|
|
34
|
+
*/
|
|
35
|
+
export function handleVariableRowHeights(template, state, renderedRows) {
|
|
36
|
+
const currentRange = {
|
|
37
|
+
start: renderedRows[0].rowIndex,
|
|
38
|
+
end: renderedRows[renderedRows.length - 1].rowIndex + 1,
|
|
39
|
+
};
|
|
40
|
+
let adjustFromIndex;
|
|
41
|
+
let adjustmentValue = 0;
|
|
42
|
+
let offsetRangeIndex = findOffsetRangeIndex(
|
|
43
|
+
state.offsetRanges,
|
|
44
|
+
currentRange.start
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
renderedRows.forEach((row) => {
|
|
48
|
+
if (!state.heightCache[row.key]) {
|
|
49
|
+
// need to get row actual element so we can find its height
|
|
50
|
+
const rowElement = template.querySelector(
|
|
51
|
+
`[data-row-key-value="${row.key}"]`
|
|
52
|
+
);
|
|
53
|
+
if (rowElement) {
|
|
54
|
+
// first rendered row needs height increased by 1 to account for missing border
|
|
55
|
+
let height = rowElement.getBoundingClientRect().height;
|
|
56
|
+
if (row.rowIndex === currentRange.start) {
|
|
57
|
+
height++;
|
|
58
|
+
}
|
|
59
|
+
state.heightCache[row.key] = height;
|
|
60
|
+
|
|
61
|
+
// calculate estimate of row offset
|
|
62
|
+
setOffset(state, row, offsetRangeIndex, height);
|
|
63
|
+
|
|
64
|
+
// update variables used to adjust later row offsets
|
|
65
|
+
adjustmentValue += height - state.rowHeight;
|
|
66
|
+
adjustFromIndex = row.rowIndex + 2;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
state.tableHeight += adjustmentValue;
|
|
71
|
+
updateOffsetRanges(
|
|
72
|
+
state,
|
|
73
|
+
offsetRangeIndex,
|
|
74
|
+
currentRange,
|
|
75
|
+
adjustFromIndex,
|
|
76
|
+
adjustmentValue
|
|
77
|
+
);
|
|
78
|
+
updateVirtualizeStyles(template, state, renderedRows);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* uses binary search with offsets and offsetRange
|
|
83
|
+
* to determine what the first visible index should be
|
|
84
|
+
* for a given scrollTop value
|
|
85
|
+
*/
|
|
86
|
+
export function findFirstVisibleIndex(state, scrollTop) {
|
|
87
|
+
const { offsetRanges, offsets, rowHeight, fixedHeight, virtualize } = state;
|
|
88
|
+
if (virtualize && fixedHeight) {
|
|
89
|
+
return scrollTop / rowHeight;
|
|
90
|
+
}
|
|
91
|
+
let start = 0;
|
|
92
|
+
let end = offsetRanges.length - 1;
|
|
93
|
+
|
|
94
|
+
while (start <= end) {
|
|
95
|
+
let mid = Math.floor((start + end) / 2);
|
|
96
|
+
const prevRange = offsetRanges[mid];
|
|
97
|
+
const nextRange = offsetRanges[mid + 1];
|
|
98
|
+
const startOffset = offsets[prevRange.start];
|
|
99
|
+
const endOffset = offsets[prevRange.end];
|
|
100
|
+
|
|
101
|
+
const scrollTopAfterPrevStart = startOffset <= scrollTop;
|
|
102
|
+
const scrollTopInPrevRange =
|
|
103
|
+
scrollTopAfterPrevStart && scrollTop <= endOffset;
|
|
104
|
+
const scrollTopBeforeNextRange =
|
|
105
|
+
!nextRange || scrollTop < offsets[nextRange.start];
|
|
106
|
+
const scrollTopBetweenRanges =
|
|
107
|
+
scrollTopAfterPrevStart && scrollTopBeforeNextRange;
|
|
108
|
+
|
|
109
|
+
// check if scrollTop is in prevAdj offset values
|
|
110
|
+
// or between prevAdj and nextAdj offsetValues
|
|
111
|
+
if (scrollTopInPrevRange) {
|
|
112
|
+
// find offset in prevRange to use for firstVisibleIndex
|
|
113
|
+
return searchForOffset(state, prevRange, scrollTop);
|
|
114
|
+
} else if (scrollTopBetweenRanges) {
|
|
115
|
+
// use scrollTop and rowHeight to calculate firstVisibleIndex
|
|
116
|
+
const diff = scrollTop - endOffset;
|
|
117
|
+
const extraRows = Math.floor(diff / rowHeight);
|
|
118
|
+
state._firstRowOffset = diff % rowHeight;
|
|
119
|
+
return prevRange.end + extraRows;
|
|
120
|
+
}
|
|
121
|
+
// update start or end for next round of binary search
|
|
122
|
+
if (scrollTop < startOffset) {
|
|
123
|
+
end = mid - 1;
|
|
124
|
+
} else {
|
|
125
|
+
start = mid + 1;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return -1;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* determines the rowIndex for given scrollTop
|
|
133
|
+
* within a provided offset range using binary search
|
|
134
|
+
* also sets firstRowOffset to correct value
|
|
135
|
+
*
|
|
136
|
+
* @param {object} range - object with start and end index for binary search
|
|
137
|
+
* @param {number} scrollTop - value to find offset rowIndex for
|
|
138
|
+
* @returns {number} representing firstVisibleIndex for given scrollTop
|
|
139
|
+
*/
|
|
140
|
+
function searchForOffset(state, range, scrollTop) {
|
|
141
|
+
let { start, end } = range;
|
|
142
|
+
const offsets = state.offsets;
|
|
143
|
+
|
|
144
|
+
while (start <= end) {
|
|
145
|
+
const mid = Math.floor((start + end) / 2);
|
|
146
|
+
const currentOffsetUnderScrollTop = offsets[mid] <= scrollTop;
|
|
147
|
+
const nextOffsetUnderScrollTop =
|
|
148
|
+
offsets[mid + 1] && offsets[mid + 1] <= scrollTop;
|
|
149
|
+
|
|
150
|
+
if (currentOffsetUnderScrollTop && !nextOffsetUnderScrollTop) {
|
|
151
|
+
// store how many pixels scrollTop is from top of row
|
|
152
|
+
state.firstRowOffset = scrollTop - offsets[mid];
|
|
153
|
+
return mid;
|
|
154
|
+
} else if (currentOffsetUnderScrollTop) {
|
|
155
|
+
start = mid + 1;
|
|
156
|
+
} else {
|
|
157
|
+
end = mid - 1;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return -1;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* uses a binary search to find the offsetRange index that
|
|
165
|
+
* encompasses the provided row index, or the one immediately
|
|
166
|
+
* before if no offsetRange encompasses the provided rowIndex
|
|
167
|
+
*/
|
|
168
|
+
function findOffsetRangeIndex(offsetRanges, rowIndex) {
|
|
169
|
+
let start = 0;
|
|
170
|
+
let end = offsetRanges.length - 1;
|
|
171
|
+
while (start <= end) {
|
|
172
|
+
let mid = Math.floor((start + end) / 2);
|
|
173
|
+
const currentRangeStartsBeforeRowIndex =
|
|
174
|
+
offsetRanges[mid].start <= rowIndex;
|
|
175
|
+
const nextRangeStartsBeforeRowIndex =
|
|
176
|
+
offsetRanges[mid + 1] && offsetRanges[mid + 1].start <= rowIndex;
|
|
177
|
+
|
|
178
|
+
// check if rowIndex is between start of range at "mid"
|
|
179
|
+
// and start of range at "mid + 1" (or if there is no "mid + 1")
|
|
180
|
+
if (
|
|
181
|
+
currentRangeStartsBeforeRowIndex &&
|
|
182
|
+
!nextRangeStartsBeforeRowIndex
|
|
183
|
+
) {
|
|
184
|
+
return mid;
|
|
185
|
+
} else if (currentRangeStartsBeforeRowIndex) {
|
|
186
|
+
// look for earlier offsetRanges
|
|
187
|
+
start = mid + 1;
|
|
188
|
+
} else {
|
|
189
|
+
// look for later offsetRanges
|
|
190
|
+
end = mid - 1;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return -1;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* sets the offset value for a given row and the next
|
|
198
|
+
* based on the closest set offset value, the default
|
|
199
|
+
* row height and the height of the current row
|
|
200
|
+
*
|
|
201
|
+
* @param {object} state - datatable state
|
|
202
|
+
* @param {object} row - specific row object from state
|
|
203
|
+
* @param {number} offsetRangeIndex - index of offset range to use for row
|
|
204
|
+
* @param {number} height - height of row's node
|
|
205
|
+
*/
|
|
206
|
+
function setOffset(state, row, offsetRangeIndex, height) {
|
|
207
|
+
let currentRange = state.offsetRanges[offsetRangeIndex];
|
|
208
|
+
let currentOffset = state.offsets[row.rowIndex];
|
|
209
|
+
// if no offset is set for current row, estimate it
|
|
210
|
+
// based on most recent offset and default rowHeight
|
|
211
|
+
if (!currentOffset) {
|
|
212
|
+
currentOffset = 0;
|
|
213
|
+
if (currentRange) {
|
|
214
|
+
const baseOffset = state.offsets[currentRange.end];
|
|
215
|
+
const estimatedRowOffsets =
|
|
216
|
+
(row.rowIndex - currentRange.end) * state.rowHeight;
|
|
217
|
+
currentOffset = baseOffset + estimatedRowOffsets;
|
|
218
|
+
state.offsets[row.rowIndex] = currentOffset;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// set next offset based on current offset and height
|
|
222
|
+
state.offsets[row.rowIndex + 1] = currentOffset + height;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* merges or adds new offset range and
|
|
227
|
+
* updates offsets and range values as needed
|
|
228
|
+
*
|
|
229
|
+
* @param {number} offsetRangeIndex
|
|
230
|
+
* @param {*} state - datatable state
|
|
231
|
+
* @param {object} currentRange - range for current rendered rows
|
|
232
|
+
* @param {number} adjustFromIndex - first index to increase by rangeValue
|
|
233
|
+
* @param {number} rangeValue - amount to increase offsets after adjustFromIndex
|
|
234
|
+
*/
|
|
235
|
+
function updateOffsetRanges(
|
|
236
|
+
state,
|
|
237
|
+
offsetRangeIndex,
|
|
238
|
+
currentRange,
|
|
239
|
+
adjustFromIndex,
|
|
240
|
+
adjustmentValue
|
|
241
|
+
) {
|
|
242
|
+
const { offsets, offsetRanges } = state;
|
|
243
|
+
let prevRange = offsetRanges[offsetRangeIndex];
|
|
244
|
+
let nextRange = offsetRanges[offsetRangeIndex + 1];
|
|
245
|
+
const overlapsWithPrevRange =
|
|
246
|
+
prevRange && checkOverlap(prevRange, currentRange);
|
|
247
|
+
const overlapsWithNextRange =
|
|
248
|
+
nextRange && checkOverlap(currentRange, nextRange);
|
|
249
|
+
|
|
250
|
+
// update remaining values in next range by
|
|
251
|
+
// adjustment value if we're overlapping it
|
|
252
|
+
if (overlapsWithNextRange && adjustmentValue) {
|
|
253
|
+
for (let i = adjustFromIndex; i <= nextRange.end; i++) {
|
|
254
|
+
offsets[i] = offsets[i] + adjustmentValue;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// update state.offsetRanges
|
|
259
|
+
if (overlapsWithPrevRange && overlapsWithNextRange) {
|
|
260
|
+
nextRange.start = prevRange.start;
|
|
261
|
+
nextRange.end = Math.max(currentRange.end, nextRange.end);
|
|
262
|
+
state.offsetRanges.splice(offsetRangeIndex, 1); // removes prevRange
|
|
263
|
+
} else if (overlapsWithPrevRange) {
|
|
264
|
+
prevRange.end = Math.max(prevRange.end, currentRange.end);
|
|
265
|
+
} else if (overlapsWithNextRange) {
|
|
266
|
+
nextRange.start = currentRange.start;
|
|
267
|
+
nextRange.end = Math.max(currentRange.end, nextRange.end);
|
|
268
|
+
// increase offsetRangeIndex; since it's values have already been updated
|
|
269
|
+
// we want to skip it when adjusting offsets in later ranges
|
|
270
|
+
offsetRangeIndex = offsetRangeIndex + 1;
|
|
271
|
+
} else {
|
|
272
|
+
state.offsetRanges.splice(offsetRangeIndex + 1, 0, currentRange);
|
|
273
|
+
// need to increase offsetRangeIndex so we don't
|
|
274
|
+
// unnecessarily add adjustmentValue to currentRange
|
|
275
|
+
offsetRangeIndex = offsetRangeIndex + 1;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// loop through every offset range after the current one
|
|
279
|
+
// and increase the offset for each index by adjustmentValue
|
|
280
|
+
if (offsetRangeIndex >= 0) {
|
|
281
|
+
for (let i = offsetRangeIndex + 1; i < offsetRanges.length; i++) {
|
|
282
|
+
const { start: rangeStart, end: rangeEnd } = offsetRanges[i];
|
|
283
|
+
for (let j = rangeStart; j <= rangeEnd; j++) {
|
|
284
|
+
offsets[j] = offsets[j] + adjustmentValue;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* compares start/end of two ranges to see if the values overlap
|
|
292
|
+
* used to determine if renderedRows are part of an existent offsetRange
|
|
293
|
+
* or if a new offsetRange will need to be added
|
|
294
|
+
*/
|
|
295
|
+
function checkOverlap(range1, range2) {
|
|
296
|
+
return (
|
|
297
|
+
(range1.start <= range2.start && range2.start <= range1.end) ||
|
|
298
|
+
(range1.start <= range2.end && range2.end <= range1.end)
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* updates scrollTop and top values for rows when
|
|
304
|
+
* using virtualization with fixedHeight of false
|
|
305
|
+
*/
|
|
306
|
+
function updateVirtualizeStyles(template, state, renderedRows) {
|
|
307
|
+
// update scrollTop so firstVisibleIndex is correctly placed in viewport
|
|
308
|
+
const scrollerY = template.querySelector('.slds-scrollable_y');
|
|
309
|
+
scrollerY.scrollTop =
|
|
310
|
+
state.offsets[state.firstVisibleIndex] + state.firstRowOffset;
|
|
311
|
+
|
|
312
|
+
// update top of rendered rows based on offsets
|
|
313
|
+
renderedRows.forEach((row) => {
|
|
314
|
+
row.style = styleToString({
|
|
315
|
+
position: 'absolute',
|
|
316
|
+
top: `${state.offsets[row.rowIndex]}px`,
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
}
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates and returns a metadata object the contains information about the
|
|
3
|
+
* number of fixed, flexible, and resized columns in the table
|
|
4
|
+
*
|
|
5
|
+
* @param {Object} columnWidthMetaData The initial column widths metadata
|
|
6
|
+
* @param {Object} columnDefs The column definition object
|
|
7
|
+
* @returns {Object} The computed metadata
|
|
8
|
+
*/
|
|
1
9
|
export function getTotalWidthsMetadata(columnWidthMetaData, columnDefs) {
|
|
2
10
|
const initial = {
|
|
3
11
|
totalFixedWidth: 0,
|
|
@@ -28,14 +36,24 @@ export function getTotalWidthsMetadata(columnWidthMetaData, columnDefs) {
|
|
|
28
36
|
}
|
|
29
37
|
|
|
30
38
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* @
|
|
39
|
+
* Gets the width of a DOM element.
|
|
40
|
+
*
|
|
41
|
+
* @param {Node} element Target DOM element
|
|
42
|
+
* @returns {Number} The width of the DOM element
|
|
34
43
|
*/
|
|
35
44
|
export function getDomWidth(element) {
|
|
36
45
|
return element.offsetWidth;
|
|
37
46
|
}
|
|
38
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Gets the width of a column. If the column has a fixed width,
|
|
50
|
+
* it will always return that value. If the column does not have a fixed
|
|
51
|
+
* width, it will return the resized value (if applicable), otherwise
|
|
52
|
+
* the initial width.
|
|
53
|
+
*
|
|
54
|
+
* @param {Object} column The column object
|
|
55
|
+
* @returns {Number} The fixed width, resized width, or initial width of the column (in that priority order)
|
|
56
|
+
*/
|
|
39
57
|
export function getColumnWidthFromDef(column) {
|
|
40
58
|
let resizedWidth;
|
|
41
59
|
if (column.isResized) {
|
|
@@ -44,6 +62,12 @@ export function getColumnWidthFromDef(column) {
|
|
|
44
62
|
return column.fixedWidth || resizedWidth || column.initialWidth;
|
|
45
63
|
}
|
|
46
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Creates a width CSS style string from a numeric value
|
|
67
|
+
*
|
|
68
|
+
* @param {Number} pixels Number of pixels
|
|
69
|
+
* @returns {String} The CSS width definition
|
|
70
|
+
*/
|
|
47
71
|
export function buildCSSWidthStyle(pixels) {
|
|
48
72
|
return pixels > 0 ? `width:${pixels}px` : '';
|
|
49
73
|
}
|