@teselagen/ui 0.7.33-beta.6 → 0.7.33
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/AdvancedOptions.js +33 -0
- package/AssignDefaultsModeContext.js +22 -0
- package/CellDragHandle.js +132 -0
- package/ColumnFilterMenu.js +62 -0
- package/Columns.js +979 -0
- package/DataTable/utils/queryParams.d.ts +14 -7
- package/DisabledLoadingComponent.js +15 -0
- package/DisplayOptions.js +199 -0
- package/DropdownButton.js +36 -0
- package/DropdownCell.js +61 -0
- package/EditableCell.js +44 -0
- package/FillWindow.css +6 -0
- package/FillWindow.js +69 -0
- package/FilterAndSortMenu.js +391 -0
- package/FormSeparator.js +9 -0
- package/LoadingDots.js +14 -0
- package/MatchHeaders.js +234 -0
- package/PagingTool.js +225 -0
- package/RenderCell.js +191 -0
- package/SearchBar.js +69 -0
- package/SimpleStepViz.js +22 -0
- package/SortableColumns.js +100 -0
- package/TableFormTrackerContext.js +10 -0
- package/Tag.js +112 -0
- package/ThComponent.js +44 -0
- package/TimelineEvent.js +31 -0
- package/UploadCsvWizard.css +4 -0
- package/UploadCsvWizard.js +719 -0
- package/Uploader.js +1278 -0
- package/adHoc.js +10 -0
- package/autoTooltip.js +201 -0
- package/basicHandleActionsWithFullState.js +14 -0
- package/browserUtils.js +3 -0
- package/combineReducersWithFullState.js +14 -0
- package/commandControls.js +82 -0
- package/commandUtils.js +112 -0
- package/constants.js +1 -0
- package/convertSchema.js +69 -0
- package/customIcons.js +361 -0
- package/dataTableEnhancer.js +41 -0
- package/defaultFormatters.js +32 -0
- package/defaultValidators.js +40 -0
- package/determineBlackOrWhiteTextColor.js +4 -0
- package/editCellHelper.js +44 -0
- package/formatPasteData.js +16 -0
- package/getAllRows.js +11 -0
- package/getCellCopyText.js +7 -0
- package/getCellInfo.js +36 -0
- package/getCellVal.js +20 -0
- package/getDayjsFormatter.js +35 -0
- package/getFieldPathToField.js +7 -0
- package/getIdOrCodeOrIndex.js +9 -0
- package/getLastSelectedEntity.js +11 -0
- package/getNewEntToSelect.js +25 -0
- package/getNewName.js +31 -0
- package/getRowCopyText.js +28 -0
- package/getTableConfigFromStorage.js +5 -0
- package/getTextFromEl.js +28 -0
- package/getVals.js +8 -0
- package/handleCopyColumn.js +21 -0
- package/handleCopyHelper.js +15 -0
- package/handleCopyRows.js +23 -0
- package/handleCopyTable.js +16 -0
- package/handlerHelpers.js +24 -0
- package/hotkeyUtils.js +131 -0
- package/index.cjs.js +972 -837
- package/index.d.ts +0 -1
- package/index.es.js +972 -837
- package/index.js +196 -0
- package/isBeingCalledExcessively.js +31 -0
- package/isBottomRightCornerOfRectangle.js +20 -0
- package/isEntityClean.js +15 -0
- package/isTruthy.js +12 -0
- package/isValueEmpty.js +3 -0
- package/itemUpload.js +84 -0
- package/menuUtils.js +433 -0
- package/package.json +1 -2
- package/popoverOverflowModifiers.js +11 -0
- package/primarySelectedValue.js +1 -0
- package/pureNoFunc.js +31 -0
- package/queryParams.js +1058 -0
- package/removeCleanRows.js +22 -0
- package/renderOnDoc.js +32 -0
- package/rerenderOnWindowResize.js +26 -0
- package/rowClick.js +181 -0
- package/selection.js +8 -0
- package/showAppSpinner.js +12 -0
- package/showDialogOnDocBody.js +33 -0
- package/showProgressToast.js +22 -0
- package/sortify.js +73 -0
- package/style.css +29 -0
- package/tagUtils.js +45 -0
- package/tgFormValues.js +35 -0
- package/tg_modalState.js +47 -0
- package/throwFormError.js +16 -0
- package/toastr.js +148 -0
- package/tryToMatchSchemas.js +264 -0
- package/typeToCommonType.js +6 -0
- package/useDeepEqualMemo.js +15 -0
- package/useDialog.js +63 -0
- package/useStableReference.js +9 -0
- package/useTableEntities.js +38 -0
- package/useTraceUpdate.js +19 -0
- package/utils.js +37 -0
- package/validateTableWideErrors.js +160 -0
- package/viewColumn.js +97 -0
- package/withField.js +20 -0
- package/withFields.js +11 -0
- package/withLocalStorage.js +11 -0
- package/withSelectTableRecords.js +43 -0
- package/withSelectedEntities.js +65 -0
- package/withStore.js +10 -0
- package/withTableParams.js +301 -0
- package/wrapDialog.js +116 -0
|
@@ -3,6 +3,12 @@ export function getMergedOpts(topLevel?: {}, instanceLevel?: {}): {
|
|
|
3
3
|
defaults: any;
|
|
4
4
|
formName: string;
|
|
5
5
|
};
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @param {object} field
|
|
9
|
+
* @returns the camelCase display name of the field, to be used for filters, sorting, etc
|
|
10
|
+
*/
|
|
11
|
+
export function getCCDisplayName(field: object): string;
|
|
6
12
|
export function getCurrentParamsFromUrl(location: any, isSimple: any): any;
|
|
7
13
|
export function setCurrentParamsOnUrl(newParams: any, replace: any, isSimple: any): void;
|
|
8
14
|
export function makeDataTableHandlers({ setNewParams, defaults, onlyOneFilter }: {
|
|
@@ -19,33 +25,34 @@ export function makeDataTableHandlers({ setNewParams, defaults, onlyOneFilter }:
|
|
|
19
25
|
setOrder: (order: any, isRemove: any, shiftHeld: any) => any;
|
|
20
26
|
setNewParams: any;
|
|
21
27
|
};
|
|
22
|
-
export function getQueryParams({ currentParams, defaults, schema, isInfinite, entities, isLocalCall, additionalFilter, doNotCoercePageSize, noOrderError, ownProps }: {
|
|
28
|
+
export function getQueryParams({ currentParams, urlConnected, defaults, schema, isInfinite, entities, isLocalCall, additionalFilter, additionalOrFilter, doNotCoercePageSize, noOrderError, isCodeModel, ownProps }: {
|
|
23
29
|
currentParams: any;
|
|
30
|
+
urlConnected: any;
|
|
24
31
|
defaults: any;
|
|
25
32
|
schema: any;
|
|
26
33
|
isInfinite: any;
|
|
27
34
|
entities: any;
|
|
28
35
|
isLocalCall: any;
|
|
29
36
|
additionalFilter: any;
|
|
37
|
+
additionalOrFilter: any;
|
|
30
38
|
doNotCoercePageSize: any;
|
|
31
39
|
noOrderError: any;
|
|
40
|
+
isCodeModel: any;
|
|
32
41
|
ownProps: any;
|
|
33
42
|
}): {
|
|
34
43
|
page: any;
|
|
35
44
|
pageSize: any;
|
|
36
|
-
order: any
|
|
45
|
+
order: any;
|
|
37
46
|
filters: any;
|
|
38
47
|
searchTerm: any;
|
|
39
48
|
} | {
|
|
40
49
|
variables: {
|
|
41
|
-
|
|
42
|
-
order_by: {};
|
|
43
|
-
limit: any;
|
|
44
|
-
offset: number;
|
|
50
|
+
sort: never[];
|
|
45
51
|
};
|
|
52
|
+
errorParsingUrlString: unknown;
|
|
46
53
|
page: any;
|
|
47
54
|
pageSize: any;
|
|
48
|
-
order: any
|
|
55
|
+
order: any;
|
|
49
56
|
filters: any;
|
|
50
57
|
searchTerm: any;
|
|
51
58
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ReactTableDefaults } from "@teselagen/react-table";
|
|
3
|
+
const { LoadingComponent } = ReactTableDefaults;
|
|
4
|
+
|
|
5
|
+
function DisabledLoadingComponent({ disabled, loading, loadingText }) {
|
|
6
|
+
return (
|
|
7
|
+
<LoadingComponent
|
|
8
|
+
className={disabled ? "disabled" : ""}
|
|
9
|
+
loading={loading}
|
|
10
|
+
loadingText={disabled ? "" : loadingText}
|
|
11
|
+
/>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default DisabledLoadingComponent;
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { map, isEmpty, noop, startCase } from "lodash-es";
|
|
3
|
+
import {
|
|
4
|
+
Button,
|
|
5
|
+
Checkbox,
|
|
6
|
+
Menu,
|
|
7
|
+
MenuItem,
|
|
8
|
+
Classes,
|
|
9
|
+
InputGroup,
|
|
10
|
+
Popover,
|
|
11
|
+
Switch
|
|
12
|
+
} from "@blueprintjs/core";
|
|
13
|
+
import { getCCDisplayName } from "./utils/queryParams";
|
|
14
|
+
|
|
15
|
+
const DisplayOptions = ({
|
|
16
|
+
compact,
|
|
17
|
+
extraCompact,
|
|
18
|
+
disabled,
|
|
19
|
+
hideDisplayOptionsIcon,
|
|
20
|
+
resetDefaultVisibility = noop,
|
|
21
|
+
updateColumnVisibility = noop,
|
|
22
|
+
updateTableDisplayDensity,
|
|
23
|
+
showForcedHiddenColumns,
|
|
24
|
+
setShowForcedHidden,
|
|
25
|
+
hasOptionForForcedHidden,
|
|
26
|
+
schema
|
|
27
|
+
}) => {
|
|
28
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
29
|
+
const [searchTerms, setSearchTerms] = useState({});
|
|
30
|
+
|
|
31
|
+
const changeTableDensity = e => {
|
|
32
|
+
updateTableDisplayDensity(e.target.value);
|
|
33
|
+
setIsOpen(false);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const toggleForcedHidden = e => setShowForcedHidden(e.target.checked);
|
|
37
|
+
|
|
38
|
+
if (hideDisplayOptionsIcon) {
|
|
39
|
+
return null; //don't show antyhing!
|
|
40
|
+
}
|
|
41
|
+
const { fields } = schema;
|
|
42
|
+
const fieldGroups = {};
|
|
43
|
+
const mainFields = [];
|
|
44
|
+
|
|
45
|
+
fields.forEach(field => {
|
|
46
|
+
if (field.hideInMenu) return;
|
|
47
|
+
if (!field.fieldGroup) return mainFields.push(field);
|
|
48
|
+
if (!fieldGroups[field.fieldGroup]) fieldGroups[field.fieldGroup] = [];
|
|
49
|
+
fieldGroups[field.fieldGroup].push(field);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
let numVisible = 0;
|
|
53
|
+
|
|
54
|
+
const getFieldCheckbox = (field, i) => {
|
|
55
|
+
const { displayName, isHidden, isForcedHidden, path } = field;
|
|
56
|
+
if (isForcedHidden) return;
|
|
57
|
+
if (!isHidden) numVisible++;
|
|
58
|
+
return (
|
|
59
|
+
<Checkbox
|
|
60
|
+
name={`${path}-${i}`}
|
|
61
|
+
key={path || i}
|
|
62
|
+
onChange={() => {
|
|
63
|
+
if (numVisible <= 1 && !isHidden) {
|
|
64
|
+
return window.toastr.warning(
|
|
65
|
+
"We have to display at least one column :)"
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
updateColumnVisibility({ shouldShow: isHidden, path });
|
|
69
|
+
}}
|
|
70
|
+
checked={!isHidden}
|
|
71
|
+
label={displayName}
|
|
72
|
+
/>
|
|
73
|
+
);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
let fieldGroupMenu;
|
|
77
|
+
if (!isEmpty(fieldGroups)) {
|
|
78
|
+
fieldGroupMenu = map(fieldGroups, (groupFields, groupName) => {
|
|
79
|
+
const searchTerm = searchTerms[groupName] || "";
|
|
80
|
+
const anyVisible = groupFields.some(
|
|
81
|
+
field => !field.isHidden && !field.isForcedHidden
|
|
82
|
+
);
|
|
83
|
+
const anyNotForcedHidden = groupFields.some(
|
|
84
|
+
field => !field.isForcedHidden
|
|
85
|
+
);
|
|
86
|
+
if (!anyNotForcedHidden) return;
|
|
87
|
+
return (
|
|
88
|
+
<MenuItem key={groupName} text={groupName}>
|
|
89
|
+
<InputGroup
|
|
90
|
+
leftIcon="search"
|
|
91
|
+
value={searchTerm}
|
|
92
|
+
onChange={e => {
|
|
93
|
+
setSearchTerms(prev => ({
|
|
94
|
+
...prev,
|
|
95
|
+
[groupName]: e.target.value
|
|
96
|
+
}));
|
|
97
|
+
}}
|
|
98
|
+
/>
|
|
99
|
+
<Button
|
|
100
|
+
className={Classes.MINIMAL}
|
|
101
|
+
text={(anyVisible ? "Hide" : "Show") + " All"}
|
|
102
|
+
style={{ margin: "10px 0" }}
|
|
103
|
+
onClick={() => {
|
|
104
|
+
updateColumnVisibility({
|
|
105
|
+
shouldShow: !anyVisible,
|
|
106
|
+
paths: groupFields.map(field => field.path)
|
|
107
|
+
});
|
|
108
|
+
}}
|
|
109
|
+
/>
|
|
110
|
+
{groupFields
|
|
111
|
+
.filter(
|
|
112
|
+
field =>
|
|
113
|
+
startCase(getCCDisplayName(field)) // We have to use startCase with the camelCase here because the displayName is not always a string
|
|
114
|
+
.toLowerCase()
|
|
115
|
+
.indexOf(searchTerm.toLowerCase()) > -1
|
|
116
|
+
)
|
|
117
|
+
.map(getFieldCheckbox)}
|
|
118
|
+
</MenuItem>
|
|
119
|
+
);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return (
|
|
124
|
+
<Popover
|
|
125
|
+
isOpen={isOpen}
|
|
126
|
+
onClose={() => setIsOpen(false)}
|
|
127
|
+
content={
|
|
128
|
+
<Menu>
|
|
129
|
+
<div style={{ padding: 10, paddingLeft: 20, paddingRight: 20 }}>
|
|
130
|
+
<h5 style={{ marginBottom: 10 }}>Display Density:</h5>
|
|
131
|
+
<div className={Classes.SELECT + " tg-table-display-density"}>
|
|
132
|
+
<select
|
|
133
|
+
onChange={changeTableDensity}
|
|
134
|
+
value={
|
|
135
|
+
extraCompact ? "extraCompact" : compact ? "compact" : "normal"
|
|
136
|
+
}
|
|
137
|
+
>
|
|
138
|
+
<option className={Classes.POPOVER_DISMISS} value="normal">
|
|
139
|
+
Comfortable
|
|
140
|
+
</option>
|
|
141
|
+
{/* tnr: as you can see we're calling what was "compact" Normal now in response to https://github.com/TeselaGen/lims/issues/4713 */}
|
|
142
|
+
<option className={Classes.POPOVER_DISMISS} value="compact">
|
|
143
|
+
Normal
|
|
144
|
+
</option>
|
|
145
|
+
<option
|
|
146
|
+
className={Classes.POPOVER_DISMISS}
|
|
147
|
+
value="extraCompact"
|
|
148
|
+
>
|
|
149
|
+
Compact
|
|
150
|
+
</option>
|
|
151
|
+
</select>
|
|
152
|
+
</div>
|
|
153
|
+
<h5 style={{ marginBottom: 10, marginTop: 10 }}>
|
|
154
|
+
Displayed Columns:
|
|
155
|
+
</h5>
|
|
156
|
+
<div style={{ maxHeight: 260, overflowY: "auto", padding: 2 }}>
|
|
157
|
+
{mainFields.map(getFieldCheckbox)}
|
|
158
|
+
</div>
|
|
159
|
+
<div>{fieldGroupMenu}</div>
|
|
160
|
+
{hasOptionForForcedHidden && (
|
|
161
|
+
<div style={{ marginTop: 15 }}>
|
|
162
|
+
<Switch
|
|
163
|
+
label="Show Empty Columns"
|
|
164
|
+
checked={showForcedHiddenColumns}
|
|
165
|
+
onChange={toggleForcedHidden}
|
|
166
|
+
/>
|
|
167
|
+
</div>
|
|
168
|
+
)}
|
|
169
|
+
<div
|
|
170
|
+
style={{
|
|
171
|
+
width: "100%",
|
|
172
|
+
display: "flex",
|
|
173
|
+
justifyContent: "flex-end"
|
|
174
|
+
}}
|
|
175
|
+
>
|
|
176
|
+
<Button
|
|
177
|
+
onClick={resetDefaultVisibility}
|
|
178
|
+
title="Display Options"
|
|
179
|
+
minimal
|
|
180
|
+
>
|
|
181
|
+
Reset
|
|
182
|
+
</Button>
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
</Menu>
|
|
186
|
+
}
|
|
187
|
+
>
|
|
188
|
+
<Button
|
|
189
|
+
className="tg-table-display-options"
|
|
190
|
+
onClick={() => setIsOpen(true)}
|
|
191
|
+
disabled={disabled}
|
|
192
|
+
minimal
|
|
193
|
+
icon="cog"
|
|
194
|
+
/>
|
|
195
|
+
</Popover>
|
|
196
|
+
);
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
export default DisplayOptions;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/* Copyright (C) 2018 TeselaGen Biotechnology, Inc. */
|
|
2
|
+
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { Button, Popover, Position } from "@blueprintjs/core";
|
|
5
|
+
import classnames from "classnames";
|
|
6
|
+
import popoverOverflowModifiers from "./utils/popoverOverflowModifiers";
|
|
7
|
+
|
|
8
|
+
function DropdownButton({
|
|
9
|
+
disabled,
|
|
10
|
+
menu,
|
|
11
|
+
noRightIcon,
|
|
12
|
+
popoverProps,
|
|
13
|
+
className,
|
|
14
|
+
...rest
|
|
15
|
+
}) {
|
|
16
|
+
return (
|
|
17
|
+
<Popover
|
|
18
|
+
minimal
|
|
19
|
+
modifiers={popoverOverflowModifiers}
|
|
20
|
+
disabled={disabled}
|
|
21
|
+
autoFocus={false}
|
|
22
|
+
content={menu}
|
|
23
|
+
position={Position.BOTTOM_LEFT}
|
|
24
|
+
{...popoverProps}
|
|
25
|
+
>
|
|
26
|
+
<Button
|
|
27
|
+
disabled={disabled}
|
|
28
|
+
className={classnames(className, "dropdown-button")}
|
|
29
|
+
rightIcon={noRightIcon ? undefined : "caret-down"}
|
|
30
|
+
{...rest}
|
|
31
|
+
/>
|
|
32
|
+
</Popover>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default DropdownButton;
|
package/DropdownCell.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import classNames from "classnames";
|
|
3
|
+
import TgSelect from "../TgSelect";
|
|
4
|
+
|
|
5
|
+
export const DropdownCell = ({
|
|
6
|
+
options,
|
|
7
|
+
isMulti,
|
|
8
|
+
initialValue,
|
|
9
|
+
finishEdit,
|
|
10
|
+
cancelEdit,
|
|
11
|
+
dataTest
|
|
12
|
+
}) => {
|
|
13
|
+
const [v, setV] = useState(
|
|
14
|
+
isMulti
|
|
15
|
+
? initialValue.split(",").map(v => ({ value: v, label: v }))
|
|
16
|
+
: initialValue
|
|
17
|
+
);
|
|
18
|
+
return (
|
|
19
|
+
<div
|
|
20
|
+
className={classNames("tg-dropdown-cell-edit-container", {
|
|
21
|
+
"tg-dropdown-cell-edit-container-multi": isMulti
|
|
22
|
+
})}
|
|
23
|
+
>
|
|
24
|
+
<TgSelect
|
|
25
|
+
small
|
|
26
|
+
multi={isMulti}
|
|
27
|
+
autoOpen
|
|
28
|
+
value={v}
|
|
29
|
+
onChange={val => {
|
|
30
|
+
if (isMulti) {
|
|
31
|
+
setV(val);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
finishEdit(val ? val.value : null);
|
|
35
|
+
}}
|
|
36
|
+
{...dataTest}
|
|
37
|
+
popoverProps={{
|
|
38
|
+
onClose: e => {
|
|
39
|
+
if (isMulti) {
|
|
40
|
+
if (e && e.key === "Escape") {
|
|
41
|
+
cancelEdit();
|
|
42
|
+
} else {
|
|
43
|
+
finishEdit(
|
|
44
|
+
v && v.map
|
|
45
|
+
? v
|
|
46
|
+
.map(v => v.value)
|
|
47
|
+
.filter(v => v)
|
|
48
|
+
.join(",")
|
|
49
|
+
: v
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
cancelEdit();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}}
|
|
57
|
+
options={options.map(value => ({ label: value, value }))}
|
|
58
|
+
/>
|
|
59
|
+
</div>
|
|
60
|
+
);
|
|
61
|
+
};
|
package/EditableCell.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
2
|
+
|
|
3
|
+
export const EditableCell = ({
|
|
4
|
+
cancelEdit,
|
|
5
|
+
dataTest,
|
|
6
|
+
finishEdit,
|
|
7
|
+
isNumeric,
|
|
8
|
+
initialValue
|
|
9
|
+
}) => {
|
|
10
|
+
const [value, setValue] = useState(initialValue);
|
|
11
|
+
const inputRef = useRef(null);
|
|
12
|
+
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
if (inputRef.current) {
|
|
15
|
+
inputRef.current.focus();
|
|
16
|
+
}
|
|
17
|
+
}, [isNumeric]);
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<input
|
|
21
|
+
style={{
|
|
22
|
+
border: 0,
|
|
23
|
+
width: "95%",
|
|
24
|
+
fontSize: 12,
|
|
25
|
+
background: "none"
|
|
26
|
+
}}
|
|
27
|
+
ref={inputRef}
|
|
28
|
+
{...dataTest}
|
|
29
|
+
autoFocus
|
|
30
|
+
onKeyDown={e => {
|
|
31
|
+
e.stopPropagation();
|
|
32
|
+
if (e.key === "Enter") {
|
|
33
|
+
e.target.blur();
|
|
34
|
+
} else if (e.key === "Escape") {
|
|
35
|
+
cancelEdit();
|
|
36
|
+
}
|
|
37
|
+
}}
|
|
38
|
+
onBlur={() => finishEdit(value)}
|
|
39
|
+
onChange={e => setValue(e.target.value)}
|
|
40
|
+
type={isNumeric ? "number" : undefined}
|
|
41
|
+
value={value}
|
|
42
|
+
/>
|
|
43
|
+
);
|
|
44
|
+
};
|
package/FillWindow.css
ADDED
package/FillWindow.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { createPortal } from "react-dom";
|
|
3
|
+
import { isFunction } from "lodash-es";
|
|
4
|
+
import rerenderOnWindowResize from "./rerenderOnWindowResize";
|
|
5
|
+
import "./FillWindow.css";
|
|
6
|
+
|
|
7
|
+
// use like:
|
|
8
|
+
// <FillWindow>
|
|
9
|
+
// {({ width, height }) => {
|
|
10
|
+
// return <div style={{width, height}}></div>
|
|
11
|
+
// }
|
|
12
|
+
// <FillWindow/>
|
|
13
|
+
|
|
14
|
+
export default class FillWindow extends React.Component {
|
|
15
|
+
constructor(props) {
|
|
16
|
+
super(props);
|
|
17
|
+
rerenderOnWindowResize(this);
|
|
18
|
+
}
|
|
19
|
+
// this is left here for posterity. componentDidMount didn't work before commit ee1853a5ae2e6e27b720dd225650cc2154076db5 "fixing rerenderOnWindowResize to bind this keyword correctly"
|
|
20
|
+
// componentDidMount(){
|
|
21
|
+
// this.setState({thomas: "realCool"})
|
|
22
|
+
// }
|
|
23
|
+
|
|
24
|
+
render() {
|
|
25
|
+
const w = window,
|
|
26
|
+
d = document,
|
|
27
|
+
e = d.documentElement,
|
|
28
|
+
g = d.getElementsByTagName("body")[0],
|
|
29
|
+
width = w.innerWidth || e.clientWidth || g.clientWidth,
|
|
30
|
+
height = w.innerHeight || e.clientHeight || g.clientHeight;
|
|
31
|
+
const windowDimensions = {
|
|
32
|
+
width,
|
|
33
|
+
height
|
|
34
|
+
};
|
|
35
|
+
const {
|
|
36
|
+
containerStyle = {},
|
|
37
|
+
style,
|
|
38
|
+
styleOverrides,
|
|
39
|
+
className,
|
|
40
|
+
asPortal,
|
|
41
|
+
...rest
|
|
42
|
+
} = this.props;
|
|
43
|
+
if (this.props.disabled) return this.props.children(windowDimensions);
|
|
44
|
+
const inner = (
|
|
45
|
+
<div
|
|
46
|
+
className={
|
|
47
|
+
"tg-fillWindow " + (asPortal ? "bp3-portal " : "") + (className || "")
|
|
48
|
+
}
|
|
49
|
+
style={{
|
|
50
|
+
...style,
|
|
51
|
+
width,
|
|
52
|
+
height,
|
|
53
|
+
position: "fixed",
|
|
54
|
+
top: 0,
|
|
55
|
+
left: 0,
|
|
56
|
+
...containerStyle,
|
|
57
|
+
...styleOverrides
|
|
58
|
+
}}
|
|
59
|
+
{...rest}
|
|
60
|
+
>
|
|
61
|
+
{this.props.children && isFunction(this.props.children)
|
|
62
|
+
? this.props.children(windowDimensions)
|
|
63
|
+
: this.props.children}
|
|
64
|
+
</div>
|
|
65
|
+
);
|
|
66
|
+
if (asPortal) return createPortal(inner, window.document.body);
|
|
67
|
+
return inner;
|
|
68
|
+
}
|
|
69
|
+
}
|