@genesislcap/grid-tabulator 14.281.2 → 14.282.0
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/dist/custom-elements.json +57 -7
- package/dist/dts/cell-formatters/action.formatter.d.ts +5 -5
- package/dist/dts/cell-formatters/action.formatter.d.ts.map +1 -1
- package/dist/dts/cell-formatters/actions-menu.formatter.d.ts +10 -7
- package/dist/dts/cell-formatters/actions-menu.formatter.d.ts.map +1 -1
- package/dist/dts/cell-formatters/boolean.formatter.d.ts +4 -4
- package/dist/dts/cell-formatters/boolean.formatter.d.ts.map +1 -1
- package/dist/dts/cell-formatters/editable.formatter.d.ts +4 -4
- package/dist/dts/cell-formatters/editable.formatter.d.ts.map +1 -1
- package/dist/dts/cell-formatters/select.formatter.d.ts +14 -8
- package/dist/dts/cell-formatters/select.formatter.d.ts.map +1 -1
- package/dist/dts/cell-formatters/text.formatter.d.ts +3 -3
- package/dist/dts/cell-formatters/text.formatter.d.ts.map +1 -1
- package/dist/dts/types.d.ts +1 -0
- package/dist/dts/types.d.ts.map +1 -1
- package/dist/dts/utils/index.d.ts +1 -0
- package/dist/dts/utils/index.d.ts.map +1 -1
- package/dist/dts/utils/test-id-utils.d.ts +10 -0
- package/dist/dts/utils/test-id-utils.d.ts.map +1 -0
- package/dist/esm/cell-formatters/action.formatter.js +4 -2
- package/dist/esm/cell-formatters/actions-menu.formatter.js +11 -4
- package/dist/esm/cell-formatters/boolean.formatter.js +3 -1
- package/dist/esm/cell-formatters/editable.formatter.js +4 -1
- package/dist/esm/cell-formatters/select.formatter.js +170 -21
- package/dist/esm/cell-formatters/text.formatter.js +4 -1
- package/dist/esm/utils/index.js +1 -0
- package/dist/esm/utils/test-id-utils.js +15 -0
- package/dist/grid-tabulator.api.json +193 -43
- package/dist/grid-tabulator.d.ts +48 -28
- package/docs/api/grid-tabulator.actionformatter.md +2 -2
- package/docs/api/grid-tabulator.actionsmenuformatter.md +2 -2
- package/docs/api/grid-tabulator.booleanformatter.md +2 -2
- package/docs/api/grid-tabulator.editableformatter.md +2 -2
- package/docs/api/grid-tabulator.md +1 -1
- package/docs/api/grid-tabulator.selectformatter.md +4 -4
- package/docs/api/grid-tabulator.textformatter.md +2 -2
- package/docs/api-report.md +32 -24
- package/package.json +13 -13
|
@@ -1,32 +1,181 @@
|
|
|
1
|
+
import { DOM } from '@microsoft/fast-element';
|
|
2
|
+
import { getDataTestId } from '../utils';
|
|
1
3
|
/**
|
|
2
|
-
*
|
|
3
|
-
|
|
4
|
+
* Set up global styles for selects only once
|
|
5
|
+
*/
|
|
6
|
+
function setupGlobalStyles() {
|
|
7
|
+
const styleId = 'tabulator-select-styles';
|
|
8
|
+
if (!document.getElementById(styleId)) {
|
|
9
|
+
const style = document.createElement('style');
|
|
10
|
+
style.id = styleId;
|
|
11
|
+
style.textContent = `
|
|
12
|
+
.tabulator-row {
|
|
13
|
+
overflow: visible !important;
|
|
14
|
+
}
|
|
15
|
+
.tabulator {
|
|
16
|
+
overflow: visible !important;
|
|
17
|
+
}
|
|
18
|
+
/* All select wrappers need these styles */
|
|
19
|
+
.select-wrapper {
|
|
20
|
+
overflow: visible !important;
|
|
21
|
+
}
|
|
22
|
+
/* Target select dropdown part */
|
|
23
|
+
.select-renderer::part(listbox) {
|
|
24
|
+
position: fixed !important;
|
|
25
|
+
z-index: 99999 !important;
|
|
26
|
+
}
|
|
27
|
+
/* Force dropdown options to wrap text */
|
|
28
|
+
.select-renderer::part(option) {
|
|
29
|
+
white-space: normal !important;
|
|
30
|
+
word-break: break-word !important;
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
document.head.appendChild(style);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Handle positioning and width of the dropdown when it opens
|
|
38
|
+
*/
|
|
39
|
+
function setupSelectDropdownHandler(selectElement, cellElement) {
|
|
40
|
+
// Function to update listbox dimensions
|
|
41
|
+
const updateListboxDimensions = () => {
|
|
42
|
+
var _a;
|
|
43
|
+
const listbox = (_a = selectElement.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('[part="listbox"]');
|
|
44
|
+
if (listbox) {
|
|
45
|
+
const cellWidth = cellElement.offsetWidth;
|
|
46
|
+
listbox.style.width = `${cellWidth}px`;
|
|
47
|
+
listbox.style.maxWidth = `${cellWidth}px`;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
// Setup a mutation observer to catch when the listbox is added to the DOM
|
|
51
|
+
const observer = new MutationObserver((mutations) => {
|
|
52
|
+
mutations.forEach((mutation) => {
|
|
53
|
+
if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
|
|
54
|
+
updateListboxDimensions();
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
// Start observing the shadow DOM
|
|
59
|
+
if (selectElement.shadowRoot) {
|
|
60
|
+
observer.observe(selectElement.shadowRoot, { childList: true, subtree: true });
|
|
61
|
+
}
|
|
62
|
+
// Handle the click event to ensure proper positioning
|
|
63
|
+
selectElement.addEventListener('click', updateListboxDimensions);
|
|
64
|
+
// Clean up observer when select is removed
|
|
65
|
+
const cleanupObserver = () => {
|
|
66
|
+
observer.disconnect();
|
|
67
|
+
selectElement.removeEventListener('click', updateListboxDimensions);
|
|
68
|
+
};
|
|
69
|
+
// Setup cleanup when element is removed from DOM
|
|
70
|
+
if (typeof window.MutationObserver !== 'undefined') {
|
|
71
|
+
const documentObserver = new MutationObserver((mutations) => {
|
|
72
|
+
if (!document.body.contains(selectElement)) {
|
|
73
|
+
cleanupObserver();
|
|
74
|
+
documentObserver.disconnect();
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
documentObserver.observe(document.body, { childList: true, subtree: true });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Formatter that displays a select component with options.
|
|
82
|
+
* Returns a wrapped div containing the select, similar to boolean.formatter.
|
|
4
83
|
*
|
|
5
84
|
* @param cell - The cell component provided by Tabulator
|
|
6
85
|
* @param formatterParams - Select formatter parameters
|
|
7
|
-
* @returns
|
|
86
|
+
* @returns An empty string, as the component is added directly to the cell element
|
|
8
87
|
* @public
|
|
9
88
|
*/
|
|
10
89
|
export function selectFormatter(cell, formatterParams) {
|
|
11
90
|
const value = cell.getValue();
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
91
|
+
const rowData = cell.getRow().getData();
|
|
92
|
+
const { options = [], prefix = 'foundation', nullText = '', dataTestId, onChange, } = formatterParams;
|
|
93
|
+
// Ensure global styles are set up
|
|
94
|
+
setupGlobalStyles();
|
|
95
|
+
// Create a div wrapper like in boolean.formatter.ts
|
|
96
|
+
const wrapper = document.createElement('div');
|
|
97
|
+
wrapper.className = 'select-wrapper';
|
|
98
|
+
wrapper.style.cssText =
|
|
99
|
+
'align-items: center; display: flex; height: 100%; width: 100%; position: relative; overflow: visible;';
|
|
100
|
+
// Create the select element
|
|
101
|
+
const selectElementTag = `${prefix}-select`;
|
|
102
|
+
const optionElementTag = `${prefix}-option`;
|
|
103
|
+
// Create the select component
|
|
104
|
+
const selectElement = document.createElement(selectElementTag);
|
|
105
|
+
selectElement.className = 'select-renderer';
|
|
106
|
+
selectElement.style.cssText = 'width: 100%; height: 100%; min-width: 0;';
|
|
107
|
+
// Set high z-index for dropdown
|
|
108
|
+
selectElement.style.setProperty('--listbox-z-index', '99999');
|
|
109
|
+
selectElement.style.setProperty('--listbox-position', 'fixed');
|
|
110
|
+
selectElement.style.setProperty('--listbox-max-height', '200px');
|
|
111
|
+
// Add data-test-id if provided
|
|
112
|
+
const testId = getDataTestId(dataTestId, rowData);
|
|
113
|
+
if (testId) {
|
|
114
|
+
selectElement.setAttribute('data-test-id', testId);
|
|
115
|
+
}
|
|
116
|
+
// Add event listener for changes if onChange is provided
|
|
117
|
+
if (onChange) {
|
|
118
|
+
selectElement.addEventListener('change', (e) => {
|
|
119
|
+
const newValue = e.target.value;
|
|
120
|
+
onChange(newValue, rowData);
|
|
121
|
+
// Update the cell value if field exists
|
|
122
|
+
if (cell.getField()) {
|
|
123
|
+
cell.getData()[cell.getField()] = newValue;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
20
126
|
}
|
|
21
|
-
//
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
127
|
+
// Create default option
|
|
128
|
+
const defaultOption = document.createElement(optionElementTag);
|
|
129
|
+
defaultOption.value = '';
|
|
130
|
+
defaultOption.textContent = nullText || 'Select option';
|
|
131
|
+
defaultOption.style.display = 'none';
|
|
132
|
+
defaultOption.defaultSelected = true;
|
|
133
|
+
// Append default option to select
|
|
134
|
+
selectElement.appendChild(defaultOption);
|
|
135
|
+
// Process all options
|
|
136
|
+
options.forEach((option) => {
|
|
137
|
+
const optionElement = document.createElement(optionElementTag);
|
|
138
|
+
optionElement.value = String(option.value);
|
|
139
|
+
optionElement.textContent = option.label;
|
|
140
|
+
// Set selected state
|
|
141
|
+
if (value === option.value) {
|
|
142
|
+
optionElement.selected = true;
|
|
143
|
+
}
|
|
144
|
+
// Handle disabled state
|
|
145
|
+
if (typeof option.isDisabled === 'function') {
|
|
146
|
+
try {
|
|
147
|
+
const isDisabled = option.isDisabled(rowData);
|
|
148
|
+
if (isDisabled) {
|
|
149
|
+
optionElement.disabled = true;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
console.error('Error executing select option isDisabled callback:', error);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// Add option to select element
|
|
157
|
+
selectElement.appendChild(optionElement);
|
|
158
|
+
});
|
|
159
|
+
// Set the current value if exists
|
|
160
|
+
if (value !== undefined && value !== null) {
|
|
161
|
+
selectElement.value = String(value);
|
|
27
162
|
}
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
163
|
+
// Add select to wrapper
|
|
164
|
+
wrapper.appendChild(selectElement);
|
|
165
|
+
// Get the cell element and ensure overflow visibility
|
|
166
|
+
const cellElement = cell.getElement();
|
|
167
|
+
cellElement.style.overflow = 'visible';
|
|
168
|
+
// Use DOM.queueUpdate to properly handle component initialization
|
|
169
|
+
DOM.queueUpdate(() => {
|
|
170
|
+
// Clear any existing content first
|
|
171
|
+
while (cellElement.firstChild) {
|
|
172
|
+
cellElement.removeChild(cellElement.firstChild);
|
|
173
|
+
}
|
|
174
|
+
// Add our wrapper with the select
|
|
175
|
+
cellElement.appendChild(wrapper);
|
|
176
|
+
// Setup dropdown handler
|
|
177
|
+
setupSelectDropdownHandler(selectElement, cellElement);
|
|
178
|
+
});
|
|
179
|
+
// Return empty string since we've appended the component directly
|
|
180
|
+
return '';
|
|
32
181
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getDataTestId } from '../utils';
|
|
1
2
|
/**
|
|
2
3
|
* Text formatter for customized display of values.
|
|
3
4
|
* Styled to match grid-pro text renderer.
|
|
@@ -9,9 +10,11 @@
|
|
|
9
10
|
*/
|
|
10
11
|
export function textFormatter(cell, formatterParams = {}) {
|
|
11
12
|
const value = cell.getValue();
|
|
13
|
+
const rowData = cell.getData();
|
|
12
14
|
const { specialValue = 2012, specialColor = 'orange', specialFontWeight = 'bold', prefix = 'foundation', dataTestId, nullText = '', } = formatterParams;
|
|
13
15
|
// Generate test ID if needed
|
|
14
|
-
const
|
|
16
|
+
const testId = getDataTestId(dataTestId, rowData);
|
|
17
|
+
const testIdAttr = testId ? ` data-test-id="${testId}"` : '';
|
|
15
18
|
// Handle null/undefined values
|
|
16
19
|
if (value === null || value === undefined) {
|
|
17
20
|
return `<div style="display: flex; width: 100%; height: 100%; align-items: center;">
|
package/dist/esm/utils/index.js
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves a dataTestId value that can be either a string or a function
|
|
3
|
+
*
|
|
4
|
+
* @param dataTestId - The dataTestId value (string or function)
|
|
5
|
+
* @param rowData - The row data to pass to the function if dataTestId is a function
|
|
6
|
+
* @returns The resolved test ID string or undefined if not provided
|
|
7
|
+
* @alpha
|
|
8
|
+
*/
|
|
9
|
+
export function getDataTestId(dataTestId, rowData) {
|
|
10
|
+
if (!dataTestId)
|
|
11
|
+
return undefined;
|
|
12
|
+
if (typeof dataTestId === 'function')
|
|
13
|
+
return dataTestId(rowData);
|
|
14
|
+
return dataTestId;
|
|
15
|
+
}
|