@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
package/menuUtils.js
ADDED
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { lifecycle, compose, branch } from "recompose";
|
|
3
|
+
import { withRouter, Link } from "react-router-dom";
|
|
4
|
+
import {
|
|
5
|
+
MenuItem,
|
|
6
|
+
MenuDivider,
|
|
7
|
+
Tooltip,
|
|
8
|
+
KeyCombo,
|
|
9
|
+
ContextMenu,
|
|
10
|
+
Menu,
|
|
11
|
+
Classes,
|
|
12
|
+
Icon
|
|
13
|
+
} from "@blueprintjs/core";
|
|
14
|
+
import {
|
|
15
|
+
startCase,
|
|
16
|
+
omit,
|
|
17
|
+
isNumber,
|
|
18
|
+
flatMap,
|
|
19
|
+
isArray,
|
|
20
|
+
isString,
|
|
21
|
+
noop
|
|
22
|
+
} from "lodash-es";
|
|
23
|
+
import fuzzysearch from "fuzzysearch";
|
|
24
|
+
import classNames from "classnames";
|
|
25
|
+
// https://github.com/palantir/blueprint/issues/2820
|
|
26
|
+
export function MenuItemLink({ text, onClick, icon, navTo, active, disabled }) {
|
|
27
|
+
if (disabled) {
|
|
28
|
+
return (
|
|
29
|
+
<li className={Classes.POPOVER_DISMISS}>
|
|
30
|
+
<MenuItem icon={icon} disabled={true} text={text} />
|
|
31
|
+
</li>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
const handleLinkClick = e => {
|
|
35
|
+
e.target.closest(`.${Classes.POPOVER_DISMISS}`).click();
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<li className={Classes.POPOVER_DISMISS} onClick={onClick}>
|
|
40
|
+
<Link
|
|
41
|
+
onClick={handleLinkClick}
|
|
42
|
+
to={navTo}
|
|
43
|
+
className={classNames(Classes.MENU_ITEM, {
|
|
44
|
+
[Classes.ACTIVE]: active,
|
|
45
|
+
[Classes.INTENT_PRIMARY]: active
|
|
46
|
+
})}
|
|
47
|
+
>
|
|
48
|
+
{icon && <Icon icon={icon} />}
|
|
49
|
+
<div className="bp3-text-overflow-ellipsis bp3-fill">{text}</div>
|
|
50
|
+
</Link>
|
|
51
|
+
</li>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Enhanced MenuItem that supports history-based navigation when passed a
|
|
56
|
+
// `navTo` prop
|
|
57
|
+
export const EnhancedMenuItem = compose(
|
|
58
|
+
lifecycle({
|
|
59
|
+
componentDidMount: function () {
|
|
60
|
+
const { didMount = noop, className } = this.props;
|
|
61
|
+
didMount({ className });
|
|
62
|
+
},
|
|
63
|
+
componentWillUnmount: function () {
|
|
64
|
+
const { willUnmount = noop, className } = this.props;
|
|
65
|
+
willUnmount({ className });
|
|
66
|
+
}
|
|
67
|
+
}),
|
|
68
|
+
branch(({ navTo }) => navTo, withRouter)
|
|
69
|
+
)(function ({
|
|
70
|
+
navTo,
|
|
71
|
+
context,
|
|
72
|
+
staticContext,
|
|
73
|
+
didMount,
|
|
74
|
+
willUnmount,
|
|
75
|
+
...props
|
|
76
|
+
}) {
|
|
77
|
+
let MenuItemComp = MenuItem;
|
|
78
|
+
if (navTo) {
|
|
79
|
+
MenuItemComp = MenuItemLink;
|
|
80
|
+
}
|
|
81
|
+
return (
|
|
82
|
+
<MenuItemComp
|
|
83
|
+
popoverProps={{
|
|
84
|
+
autoFocus: false
|
|
85
|
+
}}
|
|
86
|
+
{...(navTo && { navTo })}
|
|
87
|
+
{...props}
|
|
88
|
+
onClick={
|
|
89
|
+
props.onClick
|
|
90
|
+
? (...args) => {
|
|
91
|
+
return props.onClick(...args, context);
|
|
92
|
+
}
|
|
93
|
+
: undefined
|
|
94
|
+
}
|
|
95
|
+
/>
|
|
96
|
+
);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// First Non-Undefined
|
|
100
|
+
function fnu(...args) {
|
|
101
|
+
return args.find(v => v !== undefined);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Sets a tick icon if items has a `checked` prop
|
|
105
|
+
export const tickMenuEnhancer = def => {
|
|
106
|
+
const out = { ...def };
|
|
107
|
+
if (out.checked !== undefined) {
|
|
108
|
+
out.icon = out.checked ? "small-tick" : "blank";
|
|
109
|
+
}
|
|
110
|
+
return out;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// Derives various menu item props based on command objects matched via the `cmd`
|
|
114
|
+
// prop. Derived props include `text`, `icon`, `hotkey`, `onClick` and `disabled`.
|
|
115
|
+
export const commandMenuEnhancer =
|
|
116
|
+
(commands, config = {}) =>
|
|
117
|
+
(def, context) => {
|
|
118
|
+
const cmdId = typeof def === "string" ? def : def.cmd;
|
|
119
|
+
let item = typeof def === "string" ? { cmd: def } : { ...def };
|
|
120
|
+
|
|
121
|
+
const useTicks = fnu(item.useTicks, config.useTicks);
|
|
122
|
+
delete item.useTicks;
|
|
123
|
+
|
|
124
|
+
if (cmdId && commands[cmdId] && def.divider === undefined) {
|
|
125
|
+
const command = commands[cmdId];
|
|
126
|
+
|
|
127
|
+
const { isActive, isDisabled, isHidden } = command;
|
|
128
|
+
const toggles = isActive !== undefined;
|
|
129
|
+
|
|
130
|
+
item.hidden = fnu(item.hidden, isHidden);
|
|
131
|
+
item.disabled = fnu(item.disabled, isDisabled);
|
|
132
|
+
|
|
133
|
+
item.key = item.key || cmdId;
|
|
134
|
+
item.submenu = item.submenu || command.submenu;
|
|
135
|
+
item.component = item.component || command.component;
|
|
136
|
+
|
|
137
|
+
if (toggles) {
|
|
138
|
+
if (useTicks) {
|
|
139
|
+
item.text = item.text || command.shortName || command.name;
|
|
140
|
+
item.checked = item.checked || isActive;
|
|
141
|
+
} else {
|
|
142
|
+
item.text =
|
|
143
|
+
item.text ||
|
|
144
|
+
(isActive ? command.name : command.inactiveName || command.name);
|
|
145
|
+
item.icon =
|
|
146
|
+
item.icon ||
|
|
147
|
+
(isActive ? command.icon : command.inactiveIcon || command.icon);
|
|
148
|
+
}
|
|
149
|
+
} else {
|
|
150
|
+
item.text = item.text || command.name;
|
|
151
|
+
item.icon = item.icon || command.icon;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
item.hotkey = item.hotkey || command.hotkey;
|
|
155
|
+
if (!item.onClick) {
|
|
156
|
+
item.onClick = event =>
|
|
157
|
+
command.execute({
|
|
158
|
+
event,
|
|
159
|
+
context,
|
|
160
|
+
menuItem: item,
|
|
161
|
+
viaMenu: true
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
} else if (cmdId && !commands[cmdId]) {
|
|
165
|
+
item.text = item.text || startCase(cmdId);
|
|
166
|
+
item.disabled = true;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (config.omitIcons) {
|
|
170
|
+
item.icon = undefined;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (config.forceIconAlignment !== false) {
|
|
174
|
+
item.icon = item.icon || "blank";
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (useTicks) {
|
|
178
|
+
item = tickMenuEnhancer(item);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return item;
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const ident = x => x;
|
|
185
|
+
|
|
186
|
+
const dividerShorthandEnhancer = def =>
|
|
187
|
+
typeof def === "string" && def.startsWith("--")
|
|
188
|
+
? { divider: def.substr(2) }
|
|
189
|
+
: def;
|
|
190
|
+
|
|
191
|
+
// filter out unwanted attributes here! we won't want these to show up on the dom element or react will give nasty warnings
|
|
192
|
+
const unwantedAttrs = [
|
|
193
|
+
"isSimpleText",
|
|
194
|
+
"justText",
|
|
195
|
+
"submenu",
|
|
196
|
+
"component",
|
|
197
|
+
"hotkey",
|
|
198
|
+
"changingProps",
|
|
199
|
+
"showInSearchMenu",
|
|
200
|
+
"hideFromMenuSearch"
|
|
201
|
+
];
|
|
202
|
+
|
|
203
|
+
/** A menu item component that adds many features over the standard MenuItem,
|
|
204
|
+
* and allows for dynamic menu structures that are computed efficiently (only
|
|
205
|
+
* visible sections are computed and rendered).
|
|
206
|
+
* TODO: document and add examples
|
|
207
|
+
*/
|
|
208
|
+
export const DynamicMenuItem = ({
|
|
209
|
+
def,
|
|
210
|
+
enhancers = [ident],
|
|
211
|
+
context,
|
|
212
|
+
doNotEnhanceTopLevelItem
|
|
213
|
+
}) => {
|
|
214
|
+
// If passed an element instead of a menu item definition, return it.
|
|
215
|
+
// This allows mixing menu item elements and menu item defs, and makes it
|
|
216
|
+
// safe to call menu creation utils with their own output.
|
|
217
|
+
if (React.isValidElement(def)) return def;
|
|
218
|
+
|
|
219
|
+
const item = [
|
|
220
|
+
dividerShorthandEnhancer,
|
|
221
|
+
...(doNotEnhanceTopLevelItem ? [ident] : enhancers)
|
|
222
|
+
].reduce((v, f) => f(v, context), def);
|
|
223
|
+
let out;
|
|
224
|
+
if (item.divider !== undefined) {
|
|
225
|
+
out = (
|
|
226
|
+
<MenuDivider
|
|
227
|
+
{...(item.divider
|
|
228
|
+
? { title: item.divider, className: item.className }
|
|
229
|
+
: {})}
|
|
230
|
+
/>
|
|
231
|
+
);
|
|
232
|
+
} else {
|
|
233
|
+
const ItemComponent = item.component || EnhancedMenuItem;
|
|
234
|
+
out = (
|
|
235
|
+
<ItemComponent
|
|
236
|
+
// filter out unwanted attributes here!
|
|
237
|
+
{...omit(item, unwantedAttrs)}
|
|
238
|
+
context={context}
|
|
239
|
+
icon={item.icon || item.iconName}
|
|
240
|
+
labelElement={item.hotkey && <KeyCombo minimal combo={item.hotkey} />}
|
|
241
|
+
text={item.text}
|
|
242
|
+
>
|
|
243
|
+
{item.submenu
|
|
244
|
+
? item.submenu
|
|
245
|
+
.filter(ident)
|
|
246
|
+
.map((def, index) => (
|
|
247
|
+
<DynamicMenuItem key={index} {...{ def, enhancers, context }} />
|
|
248
|
+
))
|
|
249
|
+
: undefined}
|
|
250
|
+
</ItemComponent>
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
// if (item.disabled && item.disabledTooltip) {
|
|
254
|
+
// item.tooltip = def.disabledTooltip
|
|
255
|
+
// }
|
|
256
|
+
if (item.disabled && typeof item.disabled === "string") {
|
|
257
|
+
item.tooltip = item.disabled;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (item.tooltip) {
|
|
261
|
+
out = <Tooltip content={item.tooltip}>{out}</Tooltip>;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return item.hidden ? null : out;
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
// Map the passed item definition(s) to DynamicMenuItem elements
|
|
268
|
+
export const createDynamicMenu = (menuDef, enhancers, context) => {
|
|
269
|
+
if (menuDef instanceof Array) {
|
|
270
|
+
return menuDef.map((def, index) => (
|
|
271
|
+
<DynamicMenuItem key={index} {...{ def, enhancers, context }} />
|
|
272
|
+
));
|
|
273
|
+
} else {
|
|
274
|
+
return <DynamicMenuItem {...{ def: menuDef, enhancers, context }} />;
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
// Create a "bar" menu, keeping the top level array unchanged, and only
|
|
279
|
+
// map their submenus to DynamicMenuItem elements
|
|
280
|
+
export const createDynamicBarMenu = (topMenuDef, enhancers, context) => {
|
|
281
|
+
return topMenuDef.map(topLevelItem => {
|
|
282
|
+
const def = { ...topLevelItem };
|
|
283
|
+
if (def.submenu) {
|
|
284
|
+
def.submenu = def.submenu.map((subdef, index) => (
|
|
285
|
+
<DynamicMenuItem key={index} def={subdef} {...{ enhancers, context }} />
|
|
286
|
+
));
|
|
287
|
+
}
|
|
288
|
+
return def;
|
|
289
|
+
});
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
// Shorthand for command-based menus
|
|
293
|
+
export const createCommandMenu = (menuDef, commands, config, context) => {
|
|
294
|
+
return createDynamicMenu(
|
|
295
|
+
menuDef,
|
|
296
|
+
[commandMenuEnhancer(commands, config)],
|
|
297
|
+
context
|
|
298
|
+
);
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
// Shorthand for command-based bar menus
|
|
302
|
+
export const createCommandBarMenu = (menuDef, commands, config, context) => {
|
|
303
|
+
return createDynamicBarMenu(
|
|
304
|
+
menuDef,
|
|
305
|
+
[commandMenuEnhancer(commands, config)],
|
|
306
|
+
context
|
|
307
|
+
);
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
export function showCommandContextMenu(
|
|
311
|
+
menuDef,
|
|
312
|
+
commands,
|
|
313
|
+
config,
|
|
314
|
+
event,
|
|
315
|
+
onClose,
|
|
316
|
+
context
|
|
317
|
+
) {
|
|
318
|
+
return showContextMenu(
|
|
319
|
+
menuDef,
|
|
320
|
+
[commandMenuEnhancer(commands, config)],
|
|
321
|
+
event,
|
|
322
|
+
onClose,
|
|
323
|
+
context
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* TODO: update documentation. This is now an alias of createDynamicMenu
|
|
329
|
+
*
|
|
330
|
+
* Creates the contents of a Blueprint menu based on a given menu structure.
|
|
331
|
+
*
|
|
332
|
+
* The input can be an array of item objects, where each may contain:
|
|
333
|
+
* text: text to show
|
|
334
|
+
* key: React key to use (optional)
|
|
335
|
+
* divider: indicates it's a divider instead of an item. Use an empty string
|
|
336
|
+
* for a normal divider, or some label text for a labeled one
|
|
337
|
+
* icon: name of icon to show (optional)
|
|
338
|
+
* label: right-aligned label, used mostly for shortcuts (optional)
|
|
339
|
+
* hotkey: right-aligned label formatted with <KeyCombo> (optional)
|
|
340
|
+
* tooltip: tooltip text to use (optional)
|
|
341
|
+
* submenu: nested menu structure describing submenu (i.e. array of item objects),
|
|
342
|
+
* or array of MenuItem elements
|
|
343
|
+
* onClick: click handler
|
|
344
|
+
* navTo: a url to navigate to (assumes react-router)
|
|
345
|
+
* href: a url to link to
|
|
346
|
+
* target: link target
|
|
347
|
+
*
|
|
348
|
+
* Since this function is recursive (to handle nested submenus), and React
|
|
349
|
+
* elements passed as input are returned unchanged, it is possible to freely mix
|
|
350
|
+
* item objects and MenuItem elements. That also makes it safe to call the function
|
|
351
|
+
* with its own output.
|
|
352
|
+
*
|
|
353
|
+
* A customize function may also be provided, and allows customization or
|
|
354
|
+
* replacement of the created MenuItems, allowing for custom props or behavior.
|
|
355
|
+
* That function receives the original created element and the item object, and
|
|
356
|
+
* must return an element.
|
|
357
|
+
*
|
|
358
|
+
* Usage example:
|
|
359
|
+
*
|
|
360
|
+
* const menu = createMenu([
|
|
361
|
+
* { text: 'Item One', icon: 'add', onClick: () => console.info('Clicked 1') },
|
|
362
|
+
* { text: 'Item One', onClick: () => console.info('Clicked 2') },
|
|
363
|
+
* { divider: '' },
|
|
364
|
+
* { text: 'Item Three', icon: 'numerical', onClick: () => console.info('Clicked 3') },
|
|
365
|
+
* { divider: '' },
|
|
366
|
+
* { text: 'Submenus', submenu: [
|
|
367
|
+
* { text: 'Sub One' },
|
|
368
|
+
* { text: 'Sub Two' },
|
|
369
|
+
* ]},
|
|
370
|
+
* ]);
|
|
371
|
+
*
|
|
372
|
+
*/
|
|
373
|
+
export const createMenu = createDynamicMenu;
|
|
374
|
+
|
|
375
|
+
export function showContextMenu(
|
|
376
|
+
menuDef,
|
|
377
|
+
enhancers,
|
|
378
|
+
event,
|
|
379
|
+
onClose,
|
|
380
|
+
context,
|
|
381
|
+
menuComp = Menu
|
|
382
|
+
) {
|
|
383
|
+
menuDef = filterMenuForCorrectness(menuDef);
|
|
384
|
+
if (!menuDef) return;
|
|
385
|
+
|
|
386
|
+
const MenuComponent = menuComp;
|
|
387
|
+
event.persist && event.persist();
|
|
388
|
+
// Render a context menu at the passed event's position
|
|
389
|
+
ContextMenu.show(
|
|
390
|
+
<MenuComponent>
|
|
391
|
+
{createDynamicMenu(menuDef, enhancers, context)}
|
|
392
|
+
</MenuComponent>,
|
|
393
|
+
{ left: event.clientX, top: event.clientY },
|
|
394
|
+
onClose
|
|
395
|
+
);
|
|
396
|
+
event.stopPropagation && event.stopPropagation();
|
|
397
|
+
event.preventDefault && event.preventDefault();
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
function filterMenuForCorrectness(menuDef) {
|
|
401
|
+
return menuDef && menuDef.length && menuDef.filter(ident);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
export function getStringFromReactComponent(comp) {
|
|
405
|
+
if (!comp) return "";
|
|
406
|
+
if (isString(comp) || isNumber(comp)) return comp;
|
|
407
|
+
if (comp.props?.text) {
|
|
408
|
+
return getStringFromReactComponent(comp.props.text);
|
|
409
|
+
}
|
|
410
|
+
const { children } = comp.props || {};
|
|
411
|
+
if (!children) return "";
|
|
412
|
+
if (isArray(children))
|
|
413
|
+
return flatMap(children, getStringFromReactComponent).join("");
|
|
414
|
+
if (isString(children)) return children;
|
|
415
|
+
|
|
416
|
+
if (children.props) {
|
|
417
|
+
return getStringFromReactComponent(children.props);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
export function doesSearchValMatchText(searchVal, justText) {
|
|
421
|
+
return fuzzysearch(
|
|
422
|
+
searchVal ? searchVal.toLowerCase() : "",
|
|
423
|
+
justText ? justText.toLowerCase() : ""
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
export const MenuItemWithTooltip = ({ tooltip, ...rest }) => {
|
|
428
|
+
let out = <MenuItem {...rest}></MenuItem>;
|
|
429
|
+
if (tooltip) {
|
|
430
|
+
out = <Tooltip content={tooltip}>{out}</Tooltip>;
|
|
431
|
+
}
|
|
432
|
+
return out;
|
|
433
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teselagen/ui",
|
|
3
|
-
"version": "0.7.33
|
|
3
|
+
"version": "0.7.33",
|
|
4
4
|
"main": "./src/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
"@dnd-kit/core": "^6.1.0",
|
|
18
18
|
"@dnd-kit/modifiers": "^7.0.0",
|
|
19
19
|
"@dnd-kit/sortable": "^8.0.0",
|
|
20
|
-
"@teselagen/react-table": "6.10.16",
|
|
21
20
|
"classnames": "^2.3.2",
|
|
22
21
|
"color": "^3.2.1",
|
|
23
22
|
"copy-to-clipboard": "^3.3.1",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const PRIMARY_SELECTED_VAL = "main_cell";
|
package/pureNoFunc.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This HOC compares props to create a pure component that will only update
|
|
3
|
+
* when props are not deep equal. It will compare the string values of functions
|
|
4
|
+
*/
|
|
5
|
+
import { shouldUpdate } from "recompose";
|
|
6
|
+
import { isEqualWith, isFunction } from "lodash-es";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* tgreen: This is an awful function which we should come up with a better solution for
|
|
10
|
+
* @param {*} o1
|
|
11
|
+
* @param {*} o2
|
|
12
|
+
*/
|
|
13
|
+
const isEq = (o1, o2) => {
|
|
14
|
+
const isEq = isEqualWith(o1, o2, function (val1, val2) {
|
|
15
|
+
if (isFunction(val1) && isFunction(val2)) {
|
|
16
|
+
return val1 === val2 || val1.toString() === val2.toString();
|
|
17
|
+
}
|
|
18
|
+
// tgreen: we were seeing an issue where the isEq would infinite loop on react children
|
|
19
|
+
// components. We decided to just ignore them (assume they are equal)
|
|
20
|
+
if (val1 && val1.constructor && val1.constructor.name === "FiberNode")
|
|
21
|
+
return true;
|
|
22
|
+
});
|
|
23
|
+
return isEq;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const pure = BaseComponent => {
|
|
27
|
+
const hoc = shouldUpdate((props, nextProps) => !isEq(props, nextProps));
|
|
28
|
+
return hoc(BaseComponent);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default pure;
|