@linzjs/step-ag-grid 8.4.2 → 9.0.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/README.md +4 -4
- package/dist/index.css +3 -0
- package/dist/src/components/gridForm/GridFormMultiSelect.d.ts +5 -4
- package/dist/src/lui/TextAreaInput.d.ts +1 -0
- package/dist/src/lui/TextInputFormatted.d.ts +1 -0
- package/dist/src/react-menu3/components/FocusableItem.d.ts +1 -1
- package/dist/src/react-menu3/components/MenuItem.d.ts +3 -1
- package/dist/src/react-menu3/components/SubMenu.d.ts +1 -1
- package/dist/src/react-menu3/utils/withHovering.d.ts +2 -2
- package/dist/src/utils/textMatcher.d.ts +1 -1
- package/dist/src/utils/textMatcher.test.d.ts +1 -0
- package/dist/step-ag-grid.esm.js +502 -735
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +42 -42
- package/src/components/Grid.tsx +29 -27
- package/src/components/gridForm/GridFormDropDown.tsx +12 -14
- package/src/components/gridForm/GridFormMultiSelect.tsx +31 -29
- package/src/components/gridForm/GridFormPopoverMenu.tsx +18 -22
- package/src/components/gridForm/GridFormSubComponentTextArea.tsx +1 -1
- package/src/components/gridForm/GridFormSubComponentTextInput.tsx +1 -1
- package/src/components/gridForm/GridFormTextArea.tsx +1 -1
- package/src/components/gridForm/GridFormTextInput.tsx +1 -1
- package/src/lui/TextAreaInput.tsx +3 -1
- package/src/lui/TextInputFormatted.tsx +3 -1
- package/src/react-menu3/components/ControlledMenu.tsx +19 -6
- package/src/react-menu3/components/MenuItem.tsx +1 -1
- package/src/react-menu3/utils/withHovering.tsx +3 -3
- package/src/stories/grid/GridKeyboardInteractions.stories.tsx +261 -0
- package/src/stories/grid/{GridPopoutBearing.stories.tsx → GridPopoverEditBearing.stories.tsx} +4 -4
- package/src/stories/grid/{GridPopoutEditDropDown.stories.tsx → GridPopoverEditDropDown.stories.tsx} +10 -2
- package/src/stories/grid/{GridPopoutEditMultiSelect.stories.tsx → GridPopoverEditMultiSelect.stories.tsx} +0 -0
- package/src/stories/grid/gridFormInteraction/GridFormDropDownInteraction.stories.tsx +137 -0
- package/src/stories/grid/gridFormInteraction/GridFormEditBearingCorrectionInteraction.stories.tsx +92 -0
- package/src/stories/grid/gridFormInteraction/GridFormEditBearingInteraction.stories.tsx +91 -0
- package/src/stories/grid/gridFormInteraction/GridFormMultiSelectInteraction.stories.tsx +153 -0
- package/src/stories/grid/gridFormInteraction/GridFormPopoverMenuInteraction.stories.tsx +171 -0
- package/src/stories/grid/gridFormInteraction/GridFormTextAreaInteraction.stories.tsx +78 -0
- package/src/stories/grid/gridFormInteraction/GridFormTextInputInteraction.stories.tsx +85 -0
- package/src/stories/grid/{gridForm → gridFormStatic}/GridFormDropDown.stories.tsx +1 -1
- package/src/stories/grid/{gridForm → gridFormStatic}/GridFormEditBearing.stories.tsx +1 -1
- package/src/stories/grid/{gridForm → gridFormStatic}/GridFormEditBearingCorrection.stories.tsx +1 -1
- package/src/stories/grid/{gridForm → gridFormStatic}/GridFormMessage.stories.tsx +1 -1
- package/src/stories/grid/{gridForm → gridFormStatic}/GridFormMultiSelect.stories.tsx +1 -1
- package/src/stories/grid/{gridForm → gridFormStatic}/GridFormPopoverMenu.stories.tsx +1 -1
- package/src/stories/grid/{gridForm → gridFormStatic}/GridFormTextArea.stories.tsx +1 -1
- package/src/stories/grid/{gridForm → gridFormStatic}/GridFormTextInput.stories.tsx +1 -1
- package/src/stories/react-menu/ReactMenu.stories.tsx +66 -3
- package/src/styles/Grid.scss +3 -0
- package/src/utils/testUtil.ts +1 -0
- package/src/utils/textMatcher.test.ts +38 -0
- package/src/utils/textMatcher.ts +9 -2
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@linzjs/step-ag-grid",
|
|
3
3
|
"repository": "github:linz/step-ag-grid.git",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "9.0.0",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"aggrid",
|
|
8
8
|
"ag-grid",
|
|
@@ -81,76 +81,76 @@
|
|
|
81
81
|
]
|
|
82
82
|
},
|
|
83
83
|
"devDependencies": {
|
|
84
|
-
"@rollup/plugin-commonjs": "^
|
|
85
|
-
"@rollup/plugin-json": "^
|
|
84
|
+
"@rollup/plugin-commonjs": "^24.0.1",
|
|
85
|
+
"@rollup/plugin-json": "^6.0.0",
|
|
86
86
|
"@rollup/plugin-node-resolve": "^15.0.1",
|
|
87
|
-
"@semantic-release/changelog": "^6.0.
|
|
87
|
+
"@semantic-release/changelog": "^6.0.2",
|
|
88
88
|
"@semantic-release/git": "^10.0.1",
|
|
89
|
-
"@storybook/addon-
|
|
90
|
-
"@storybook/addon-essentials": "^6.5.
|
|
91
|
-
"@storybook/
|
|
92
|
-
"@storybook/addon-links": "^6.5.13",
|
|
89
|
+
"@storybook/addon-interactions": "^6.5.16",
|
|
90
|
+
"@storybook/addon-essentials": "^6.5.16",
|
|
91
|
+
"@storybook/builder-webpack5": "^6.5.16",
|
|
93
92
|
"@storybook/jest": "^0.0.10",
|
|
94
|
-
"@storybook/
|
|
95
|
-
"@storybook/
|
|
93
|
+
"@storybook/manager-webpack5": "^6.5.16",
|
|
94
|
+
"@storybook/preset-create-react-app": "^4.1.2",
|
|
95
|
+
"@storybook/react": "^6.5.16",
|
|
96
|
+
"@storybook/test-runner": "^0.9.4",
|
|
96
97
|
"@storybook/testing-library": "^0.0.13",
|
|
97
|
-
"@testing-library/dom": "^8.
|
|
98
|
+
"@testing-library/dom": "^8.20.0",
|
|
98
99
|
"@testing-library/jest-dom": "^5.16.5",
|
|
99
100
|
"@testing-library/react": "^12.1.5",
|
|
100
101
|
"@testing-library/user-event": "^13.5.0",
|
|
101
|
-
"@types/debounce-promise": "^3.1.
|
|
102
|
-
"@types/jest": "^29.
|
|
102
|
+
"@types/debounce-promise": "^3.1.6",
|
|
103
|
+
"@types/jest": "^29.4.0",
|
|
103
104
|
"@types/lodash-es": "^4.17.6",
|
|
104
|
-
"@types/node": "^18.
|
|
105
|
-
"@types/react": "^17.0.
|
|
105
|
+
"@types/node": "^18.13.0",
|
|
106
|
+
"@types/react": "^17.0.53",
|
|
106
107
|
"@types/react-dom": "^17.0.18",
|
|
107
|
-
"@types/uuid": "^
|
|
108
|
-
"@typescript-eslint/parser": "^5.
|
|
109
|
-
"babel-jest": "^29.
|
|
108
|
+
"@types/uuid": "^9.0.0",
|
|
109
|
+
"@typescript-eslint/parser": "^5.51.0",
|
|
110
|
+
"babel-jest": "^29.4.2",
|
|
110
111
|
"babel-preset-react-app": "^10.0.1",
|
|
111
|
-
"chromatic": "^6.
|
|
112
|
+
"chromatic": "^6.17.0",
|
|
112
113
|
"conventional-changelog-conventionalcommits": "^5.0.0",
|
|
113
|
-
"eslint": "^8.
|
|
114
|
-
"eslint-config-prettier": "^8.
|
|
114
|
+
"eslint": "^8.33.0",
|
|
115
|
+
"eslint-config-prettier": "^8.6.0",
|
|
115
116
|
"eslint-config-react-app": "^7.0.1",
|
|
116
|
-
"eslint-plugin-deprecation": "^1.3.
|
|
117
|
-
"eslint-plugin-import": "^2.
|
|
118
|
-
"eslint-plugin-jest": "^27.1
|
|
119
|
-
"eslint-plugin-jsx-a11y": "^6.
|
|
117
|
+
"eslint-plugin-deprecation": "^1.3.3",
|
|
118
|
+
"eslint-plugin-import": "^2.27.5",
|
|
119
|
+
"eslint-plugin-jest": "^27.2.1",
|
|
120
|
+
"eslint-plugin-jsx-a11y": "^6.7.1",
|
|
120
121
|
"eslint-plugin-prettier": "^4.2.1",
|
|
121
|
-
"eslint-plugin-react": "^7.
|
|
122
|
+
"eslint-plugin-react": "^7.32.2",
|
|
122
123
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
123
|
-
"eslint-plugin-testing-library": "^5.
|
|
124
|
-
"jest": "^29.
|
|
124
|
+
"eslint-plugin-testing-library": "^5.10.1",
|
|
125
|
+
"jest": "^29.4.2",
|
|
125
126
|
"jest-canvas-mock": "^2.4.0",
|
|
126
|
-
"jest-environment-jsdom": "^29.
|
|
127
|
+
"jest-environment-jsdom": "^29.4.2",
|
|
127
128
|
"jest-expect-message": "^1.1.3",
|
|
128
|
-
"mkdirp": "^1.
|
|
129
|
+
"mkdirp": "^2.1.3",
|
|
129
130
|
"npm-run-all": "^4.1.5",
|
|
130
|
-
"postcss": "^8.4.
|
|
131
|
-
"postcss-loader": "^7.0.
|
|
132
|
-
"postcss-scss": "^4.0.
|
|
133
|
-
"prettier": "^2.
|
|
131
|
+
"postcss": "^8.4.21",
|
|
132
|
+
"postcss-loader": "^7.0.2",
|
|
133
|
+
"postcss-scss": "^4.0.6",
|
|
134
|
+
"prettier": "^2.8.4",
|
|
134
135
|
"react-app-polyfill": "^3.0.0",
|
|
135
136
|
"react-scripts": "^5.0.1",
|
|
136
|
-
"rollup": "^3.
|
|
137
|
+
"rollup": "^3.14.0",
|
|
137
138
|
"rollup-plugin-copy": "^3.4.0",
|
|
138
139
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
139
140
|
"rollup-plugin-postcss": "^4.0.2",
|
|
140
141
|
"rollup-plugin-typescript2": "^0.34.1",
|
|
141
|
-
"sass": "^1.
|
|
142
|
-
"sass-loader": "
|
|
142
|
+
"sass": "^1.58.0",
|
|
143
|
+
"sass-loader": "^13.2.0",
|
|
143
144
|
"semantic-release": "^19.0.5",
|
|
144
|
-
"
|
|
145
|
-
"
|
|
146
|
-
"stylelint": "^
|
|
147
|
-
"stylelint-config-prettier": "^9.0.3",
|
|
145
|
+
"style-loader": "^3.3.1",
|
|
146
|
+
"stylelint": "^14.16.1",
|
|
147
|
+
"stylelint-config-prettier": "^9.0.4",
|
|
148
148
|
"stylelint-config-recommended-scss": "^8.0.0",
|
|
149
149
|
"stylelint-config-standard": "^29.0.0",
|
|
150
150
|
"stylelint-prettier": "^2.0.0",
|
|
151
151
|
"stylelint-scss": "^4.3.0",
|
|
152
152
|
"tsconfig-paths-webpack-plugin": "^4.0.0",
|
|
153
|
-
"typescript": "^4.
|
|
153
|
+
"typescript": "^4.9.5"
|
|
154
154
|
},
|
|
155
155
|
"babel": {
|
|
156
156
|
"presets": [
|
package/src/components/Grid.tsx
CHANGED
|
@@ -340,33 +340,35 @@ export const Grid = (params: GridProps): JSX.Element => {
|
|
|
340
340
|
/>
|
|
341
341
|
</div>
|
|
342
342
|
)}
|
|
343
|
-
<
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
343
|
+
<div style={{ flex: 1 }}>
|
|
344
|
+
<AgGridReact
|
|
345
|
+
animateRows={params.animateRows}
|
|
346
|
+
rowClassRules={params.rowClassRules}
|
|
347
|
+
defaultColDef={params.defaultColDef}
|
|
348
|
+
getRowId={(params) => `${params.data.id}`}
|
|
349
|
+
suppressRowClickSelection={true}
|
|
350
|
+
rowSelection={params.rowSelection ?? "multiple"}
|
|
351
|
+
suppressBrowserResizeObserver={true}
|
|
352
|
+
colResizeDefault={"shift"}
|
|
353
|
+
onFirstDataRendered={sizeColumnsToFit}
|
|
354
|
+
onGridSizeChanged={sizeColumnsToFit}
|
|
355
|
+
suppressClickEdit={true}
|
|
356
|
+
onCellKeyPress={onCellKeyPress}
|
|
357
|
+
onCellClicked={onCellClicked}
|
|
358
|
+
onCellDoubleClicked={onCellDoubleClick}
|
|
359
|
+
onCellEditingStarted={refreshSelectedRows}
|
|
360
|
+
domLayout={params.domLayout}
|
|
361
|
+
columnDefs={columnDefs}
|
|
362
|
+
rowData={params.rowData}
|
|
363
|
+
noRowsOverlayComponent={noRowsOverlayComponent}
|
|
364
|
+
onGridReady={onGridReady}
|
|
365
|
+
onSortChanged={ensureSelectedRowIsVisible}
|
|
366
|
+
postSortRows={params.postSortRows ?? postSortRows}
|
|
367
|
+
onSelectionChanged={synchroniseExternalStateToGridSelection}
|
|
368
|
+
onColumnMoved={params.onColumnMoved}
|
|
369
|
+
alwaysShowVerticalScroll={params.alwaysShowVerticalScroll}
|
|
370
|
+
/>
|
|
371
|
+
</div>
|
|
370
372
|
</div>
|
|
371
373
|
);
|
|
372
374
|
};
|
|
@@ -8,9 +8,10 @@ import { CellEditorCommon } from "../GridCell";
|
|
|
8
8
|
import { useGridPopoverHook } from "../GridPopoverHook";
|
|
9
9
|
import { useGridPopoverContext } from "../../contexts/GridPopoverContext";
|
|
10
10
|
import { GridSubComponentContext } from "../../contexts/GridSubComponentContext";
|
|
11
|
-
import { ClickEvent
|
|
11
|
+
import { ClickEvent } from "../../react-menu3/types";
|
|
12
12
|
import { FormError } from "../../lui/FormError";
|
|
13
13
|
import { isNotEmpty } from "../../utils/util";
|
|
14
|
+
import { textMatch } from "../../utils/textMatcher";
|
|
14
15
|
|
|
15
16
|
export interface GridPopoutEditDropDownSelectedItem<RowType> {
|
|
16
17
|
// Note the row that was clicked on will be first
|
|
@@ -136,8 +137,7 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormDro
|
|
|
136
137
|
console.error("Cannot filter non-string labels", option);
|
|
137
138
|
return undefined;
|
|
138
139
|
}
|
|
139
|
-
|
|
140
|
-
return str.toLowerCase().indexOf(filter.toLowerCase()) !== -1 ? option : undefined;
|
|
140
|
+
return textMatch((option.label as string) || "", filter) ? option : undefined;
|
|
141
141
|
})
|
|
142
142
|
.filter((r) => r !== undefined),
|
|
143
143
|
);
|
|
@@ -270,19 +270,17 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormDro
|
|
|
270
270
|
title={item.disabled && typeof item.disabled !== "boolean" ? item.disabled : ""}
|
|
271
271
|
value={item.value}
|
|
272
272
|
onFocus={() => {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
subComponentIsValid.current = true;
|
|
276
|
-
subComponentInitialValue.current = null;
|
|
277
|
-
} else {
|
|
273
|
+
if (selectedItem !== item) {
|
|
274
|
+
setSelectedItem(item);
|
|
278
275
|
setSubSelectedValue(null);
|
|
279
276
|
subComponentIsValid.current = true;
|
|
277
|
+
if (item.subComponent) {
|
|
278
|
+
subComponentInitialValue.current = null;
|
|
279
|
+
}
|
|
280
280
|
}
|
|
281
281
|
}}
|
|
282
282
|
onClick={(e: ClickEvent) => {
|
|
283
|
-
|
|
284
|
-
e.keepOpen = true;
|
|
285
|
-
}
|
|
283
|
+
e.keepOpen = !!item.subComponent;
|
|
286
284
|
}}
|
|
287
285
|
>
|
|
288
286
|
{item.label ?? (item.value == null ? `<${item.value}>` : `${item.value}`)}
|
|
@@ -291,7 +289,7 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormDro
|
|
|
291
289
|
|
|
292
290
|
{item.subComponent && selectedItem === item && (
|
|
293
291
|
<FocusableItem className={"LuiDeprecatedForms"} key={`${item.label}_subcomponent`}>
|
|
294
|
-
{(
|
|
292
|
+
{() => (
|
|
295
293
|
<GridSubComponentContext.Provider
|
|
296
294
|
value={{
|
|
297
295
|
context: { options },
|
|
@@ -308,13 +306,13 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormDro
|
|
|
308
306
|
subComponentIsValid.current = valid;
|
|
309
307
|
},
|
|
310
308
|
triggerSave: async () => {
|
|
311
|
-
|
|
309
|
+
// empty
|
|
312
310
|
},
|
|
313
311
|
}}
|
|
314
312
|
>
|
|
315
313
|
{item.subComponent && (
|
|
316
314
|
<div className={"subComponent"}>
|
|
317
|
-
<item.subComponent
|
|
315
|
+
<item.subComponent />
|
|
318
316
|
</div>
|
|
319
317
|
)}
|
|
320
318
|
</GridSubComponentContext.Provider>
|
|
@@ -41,6 +41,11 @@ export interface GridFormMultiSelectGroup {
|
|
|
41
41
|
filter?: string;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
export interface GridFormMultiSelectSaveProps<RowType extends GridBaseRow> {
|
|
45
|
+
selectedRows: RowType[];
|
|
46
|
+
selectedOptions: MultiSelectOption[];
|
|
47
|
+
}
|
|
48
|
+
|
|
44
49
|
export interface GridFormMultiSelectProps<RowType extends GridBaseRow> extends CellEditorCommon {
|
|
45
50
|
className?:
|
|
46
51
|
| "GridMultiSelect-containerSmall"
|
|
@@ -54,7 +59,7 @@ export interface GridFormMultiSelectProps<RowType extends GridBaseRow> extends C
|
|
|
54
59
|
filterHelpText?: string | ((filter: string, options: MultiSelectOption[]) => string | undefined);
|
|
55
60
|
noOptionsMessage?: string;
|
|
56
61
|
onSelectFilter?: (props: { filter: string; options: MultiSelectOption[] }) => void;
|
|
57
|
-
onSave?: (props:
|
|
62
|
+
onSave?: (props: GridFormMultiSelectSaveProps<RowType>) => Promise<boolean>;
|
|
58
63
|
headers?: GridFormMultiSelectGroup[];
|
|
59
64
|
options: MultiSelectOption[] | ((selectedRows: RowType[]) => Promise<MultiSelectOption[]> | MultiSelectOption[]);
|
|
60
65
|
invalid?: (selectedRows: RowType[], selectedOptions: MultiSelectOption[]) => boolean;
|
|
@@ -164,11 +169,12 @@ export const GridFormMultiSelect = <RowType extends GridBaseRow>(props: GridForm
|
|
|
164
169
|
filterPlaceholder={props.filterPlaceholder}
|
|
165
170
|
/>
|
|
166
171
|
)}
|
|
167
|
-
{headerGroups &&
|
|
168
|
-
|
|
169
|
-
{
|
|
170
|
-
|
|
171
|
-
|
|
172
|
+
{headerGroups &&
|
|
173
|
+
(isEmpty(headerGroups) || !toPairs(headerGroups).some(([_, options]) => !isEmpty(options))) && (
|
|
174
|
+
<MenuItem key={"noOptions"} className={"GridMultiSelect-noOptions"} disabled={true}>
|
|
175
|
+
{props.noOptionsMessage ?? "No Options"}
|
|
176
|
+
</MenuItem>
|
|
177
|
+
)}
|
|
172
178
|
{headerGroups && !isEmpty(headerGroups) && (
|
|
173
179
|
<div className={"GridFormMultiSelect-options"}>
|
|
174
180
|
{headers.map((header, index) => {
|
|
@@ -397,29 +403,25 @@ const MenuSubComponent = (props: {
|
|
|
397
403
|
const { data, item, options, setOptions, subComponentIsValid, triggerSave } = props;
|
|
398
404
|
return (
|
|
399
405
|
<FocusableItem className={"LuiDeprecatedForms"} key={`${item.value}_subcomponent`}>
|
|
400
|
-
{(
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
>
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
</div>
|
|
420
|
-
</GridSubComponentContext.Provider>
|
|
421
|
-
)
|
|
422
|
-
}
|
|
406
|
+
{() => (
|
|
407
|
+
<GridSubComponentContext.Provider
|
|
408
|
+
value={{
|
|
409
|
+
context: { options },
|
|
410
|
+
data,
|
|
411
|
+
value: item.subValue,
|
|
412
|
+
setValue: (value: any) => {
|
|
413
|
+
item.subValue = value;
|
|
414
|
+
setOptions([...options]);
|
|
415
|
+
},
|
|
416
|
+
setValid: (valid: boolean) => {
|
|
417
|
+
subComponentIsValid[`${item.value}`] = valid;
|
|
418
|
+
},
|
|
419
|
+
triggerSave,
|
|
420
|
+
}}
|
|
421
|
+
>
|
|
422
|
+
<div className={"subComponent"}>{item.subComponent && <item.subComponent />}</div>
|
|
423
|
+
</GridSubComponentContext.Provider>
|
|
424
|
+
)}
|
|
423
425
|
</FocusableItem>
|
|
424
426
|
);
|
|
425
427
|
};
|
|
@@ -143,28 +143,24 @@ export const GridFormPopoverMenu = <RowType extends GridBaseRow>(props: GridForm
|
|
|
143
143
|
</MenuItem>
|
|
144
144
|
{item.subComponent && subComponentSelected === item && (
|
|
145
145
|
<FocusableItem className={"LuiDeprecatedForms"} key={`${item.label}_subcomponent`}>
|
|
146
|
-
{(
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
>
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
</div>
|
|
165
|
-
</GridSubComponentContext.Provider>
|
|
166
|
-
)
|
|
167
|
-
}
|
|
146
|
+
{() => (
|
|
147
|
+
<GridSubComponentContext.Provider
|
|
148
|
+
value={{
|
|
149
|
+
context: {},
|
|
150
|
+
data,
|
|
151
|
+
value: subSelectedValue,
|
|
152
|
+
setValue: (value: any) => {
|
|
153
|
+
setSubSelectedValue(value);
|
|
154
|
+
},
|
|
155
|
+
setValid: (valid: boolean) => {
|
|
156
|
+
subComponentIsValid.current = valid;
|
|
157
|
+
},
|
|
158
|
+
triggerSave,
|
|
159
|
+
}}
|
|
160
|
+
>
|
|
161
|
+
<div className={"subComponent"}>{item.subComponent && <item.subComponent />}</div>
|
|
162
|
+
</GridSubComponentContext.Provider>
|
|
163
|
+
)}
|
|
168
164
|
</FocusableItem>
|
|
169
165
|
)}
|
|
170
166
|
</Fragment>
|
|
@@ -42,8 +42,8 @@ export const GridFormSubComponentTextArea = <RowType extends GridBaseRow>(
|
|
|
42
42
|
onChange={(e) => setValue(e.target.value)}
|
|
43
43
|
error={invalid()}
|
|
44
44
|
helpText={helpText}
|
|
45
|
-
autoFocus={true}
|
|
46
45
|
placeholder={props.placeholder}
|
|
46
|
+
allowTabToSave={true}
|
|
47
47
|
/>
|
|
48
48
|
</div>
|
|
49
49
|
);
|
|
@@ -38,9 +38,9 @@ export const GridFormSubComponentTextInput = <RowType extends GridBaseRow>(
|
|
|
38
38
|
error={invalid()}
|
|
39
39
|
onChange={(e) => setValue(e.target.value)}
|
|
40
40
|
helpText={helpText}
|
|
41
|
-
autoFocus={true}
|
|
42
41
|
placeholder={props.placeholder}
|
|
43
42
|
style={{ width: "100%" }}
|
|
43
|
+
allowTabToSave={true}
|
|
44
44
|
/>
|
|
45
45
|
);
|
|
46
46
|
};
|
|
@@ -55,7 +55,7 @@ export const GridFormTextArea = <RowType extends GridBaseRow>(props: GridFormTex
|
|
|
55
55
|
value={value}
|
|
56
56
|
onChange={(e) => setValue(e.target.value)}
|
|
57
57
|
error={invalid()}
|
|
58
|
-
placeholder={props.placeholder}
|
|
58
|
+
placeholder={props.placeholder ?? "Type here"}
|
|
59
59
|
helpText={helpText}
|
|
60
60
|
/>
|
|
61
61
|
</div>,
|
|
@@ -57,7 +57,7 @@ export const GridFormTextInput = <RowType extends GridBaseRow>(props: GridFormTe
|
|
|
57
57
|
error={invalid()}
|
|
58
58
|
formatted={props.units}
|
|
59
59
|
style={{ width: props.width ?? 240 }}
|
|
60
|
-
placeholder={props.placeholder}
|
|
60
|
+
placeholder={props.placeholder ?? "Type here"}
|
|
61
61
|
helpText={helpText}
|
|
62
62
|
/>
|
|
63
63
|
</div>,
|
|
@@ -18,6 +18,7 @@ export interface LuiTextAreaInputProps extends InputHTMLAttributes<HTMLTextAreaE
|
|
|
18
18
|
mandatory?: boolean;
|
|
19
19
|
helpText?: string;
|
|
20
20
|
error?: JSX.Element | string | boolean | null;
|
|
21
|
+
allowTabToSave?: boolean;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
export const TextAreaInput = (props: LuiTextAreaInputProps) => {
|
|
@@ -39,7 +40,7 @@ export const TextAreaInput = (props: LuiTextAreaInputProps) => {
|
|
|
39
40
|
{/* wrapper div used for error styling */}
|
|
40
41
|
<textarea
|
|
41
42
|
rows={5}
|
|
42
|
-
{...omit(props, ["error", "value", "helpText", "formatted", "className"])}
|
|
43
|
+
{...omit(props, ["error", "value", "helpText", "formatted", "className", "allowTabToSave"])}
|
|
43
44
|
id={id}
|
|
44
45
|
value={props.value ?? ""}
|
|
45
46
|
spellCheck={true}
|
|
@@ -50,6 +51,7 @@ export const TextAreaInput = (props: LuiTextAreaInputProps) => {
|
|
|
50
51
|
}
|
|
51
52
|
props.onMouseEnter && props.onMouseEnter(e);
|
|
52
53
|
}}
|
|
54
|
+
data-allowtabtosave={props.allowTabToSave}
|
|
53
55
|
>
|
|
54
56
|
{props.value}
|
|
55
57
|
</textarea>
|
|
@@ -14,6 +14,7 @@ export interface LuiTextInputProps extends DetailedHTMLProps<InputHTMLAttributes
|
|
|
14
14
|
helpText?: string;
|
|
15
15
|
error?: JSX.Element | string | boolean | null;
|
|
16
16
|
formatted?: string;
|
|
17
|
+
allowTabToSave?: boolean;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export const TextInputFormatted = (props: LuiTextInputProps): JSX.Element => {
|
|
@@ -25,12 +26,13 @@ export const TextInputFormatted = (props: LuiTextInputProps): JSX.Element => {
|
|
|
25
26
|
type={"text"}
|
|
26
27
|
spellCheck={true}
|
|
27
28
|
defaultValue={props.value}
|
|
28
|
-
{...omit(props, ["error", "value", "helpText", "formatted", "className"])}
|
|
29
|
+
{...omit(props, ["error", "value", "helpText", "formatted", "className", "allowTabToSave"])}
|
|
29
30
|
className={"LuiTextInput-input"}
|
|
30
31
|
onMouseEnter={(e) => {
|
|
31
32
|
e.currentTarget.focus();
|
|
32
33
|
props.onMouseEnter && props.onMouseEnter(e);
|
|
33
34
|
}}
|
|
35
|
+
data-allowtabtosave={props.allowTabToSave}
|
|
34
36
|
/>
|
|
35
37
|
<span className={"LuiTextInput-formatted"}>{props.formatted}</span>
|
|
36
38
|
</span>
|
|
@@ -127,6 +127,25 @@ export const ControlledMenuFr = (
|
|
|
127
127
|
return;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
const invokeSave = (reason: string) => {
|
|
131
|
+
if (!saveButtonRef?.current) return;
|
|
132
|
+
saveButtonRef.current?.setAttribute("data-reason", reason);
|
|
133
|
+
saveButtonRef?.current?.click();
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const allowTabToSave = activeElement.getAttribute("data-allowtabtosave") == "true";
|
|
137
|
+
if (allowTabToSave) {
|
|
138
|
+
if (isDown) {
|
|
139
|
+
ev.preventDefault();
|
|
140
|
+
ev.stopPropagation();
|
|
141
|
+
lastTabDownEl.current = activeElement;
|
|
142
|
+
} else {
|
|
143
|
+
lastTabDownEl.current == activeElement &&
|
|
144
|
+
invokeSave(ev.shiftKey ? CloseReason.TAB_BACKWARD : CloseReason.TAB_FORWARD);
|
|
145
|
+
}
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
130
149
|
const inputElsIterator = thisDocument.querySelectorAll<HTMLElement>(".szh-menu--state-open input,textarea");
|
|
131
150
|
let inputEls: HTMLElement[] = [];
|
|
132
151
|
inputElsIterator.forEach((el) => inputEls.push(el));
|
|
@@ -138,12 +157,6 @@ export const ControlledMenuFr = (
|
|
|
138
157
|
|
|
139
158
|
const isTextArea = activeElement.nodeName === "TEXTAREA";
|
|
140
159
|
const suppressEnterAutoSave = activeElement.getAttribute("data-disableenterautosave") == "true" || isTextArea;
|
|
141
|
-
const allowTabToSave = activeElement.getAttribute("data-allowtabtosave") == "true";
|
|
142
|
-
const invokeSave = (reason: string) => {
|
|
143
|
-
if (!saveButtonRef?.current) return;
|
|
144
|
-
saveButtonRef.current?.setAttribute("data-reason", reason);
|
|
145
|
-
saveButtonRef?.current?.click();
|
|
146
|
-
};
|
|
147
160
|
|
|
148
161
|
switch (activeElement.nodeName) {
|
|
149
162
|
case "TEXTAREA":
|
|
@@ -128,7 +128,7 @@ const MenuItemFr = ({
|
|
|
128
128
|
};
|
|
129
129
|
|
|
130
130
|
/**
|
|
131
|
-
* Keyboard events are triggered on up, otherwise
|
|
131
|
+
* Keyboard events are triggered on up, otherwise subcomponents get spaces and enters typed in them
|
|
132
132
|
*/
|
|
133
133
|
const handleKeyUp = (e: KeyboardEvent) => {
|
|
134
134
|
if (!isHovering) return;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { memo, forwardRef, useContext, useRef, MutableRefObject } from "react";
|
|
1
|
+
import { memo, forwardRef, useContext, useRef, MutableRefObject, PropsWithRef } from "react";
|
|
2
2
|
import { HoverItemContext } from "../contexts/HoverItemContext";
|
|
3
3
|
|
|
4
4
|
export interface withHoveringResultProps {
|
|
@@ -7,9 +7,9 @@ export interface withHoveringResultProps {
|
|
|
7
7
|
menuItemRef?: MutableRefObject<any>;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export const withHovering = (name: string, WrappedComponent: (
|
|
10
|
+
export const withHovering = <T,>(name: string, WrappedComponent: (props: T) => JSX.Element) => {
|
|
11
11
|
const Component = memo(WrappedComponent);
|
|
12
|
-
const WithHovering = forwardRef
|
|
12
|
+
const WithHovering = forwardRef((props: PropsWithRef<T>, ref) => {
|
|
13
13
|
const menuItemRef = useRef<any>(null);
|
|
14
14
|
return (
|
|
15
15
|
<Component
|