@mackin.com/styleguide 8.0.0-beta.9 → 8.0.2
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/index.d.ts +114 -36
- package/index.js +694 -483
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
2
|
|
|
3
|
-
var css = require('@emotion/css');
|
|
4
|
-
var lodash = require('lodash');
|
|
5
3
|
var React = require('react');
|
|
6
|
-
var
|
|
4
|
+
var css = require('@emotion/css');
|
|
7
5
|
var proRegularSvgIcons = require('@fortawesome/pro-regular-svg-icons');
|
|
8
6
|
var proSolidSvgIcons = require('@fortawesome/pro-solid-svg-icons');
|
|
9
7
|
var proLightSvgIcons = require('@fortawesome/pro-light-svg-icons');
|
|
10
8
|
var reactFontawesome = require('@fortawesome/react-fontawesome');
|
|
9
|
+
var lodash = require('lodash');
|
|
11
10
|
var dateFns = require('date-fns');
|
|
11
|
+
var nanoid = require('nanoid');
|
|
12
12
|
var reactDom = require('react-dom');
|
|
13
13
|
var reactTinyPopover = require('react-tiny-popover');
|
|
14
14
|
var reactRouterDom = require('react-router-dom');
|
|
@@ -17,29 +17,97 @@ var ReactSlider = require('react-slider');
|
|
|
17
17
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
18
18
|
|
|
19
19
|
function _interopNamespace(e) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
20
|
+
if (e && e.__esModule) return e;
|
|
21
|
+
var n = Object.create(null);
|
|
22
|
+
if (e) {
|
|
23
|
+
Object.keys(e).forEach(function (k) {
|
|
24
|
+
if (k !== 'default') {
|
|
25
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
26
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
get: function () {
|
|
29
|
+
return e[k];
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
n['default'] = e;
|
|
36
|
+
return Object.freeze(n);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
40
39
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
40
|
+
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
41
41
|
var ReactSlider__default = /*#__PURE__*/_interopDefaultLegacy(ReactSlider);
|
|
42
42
|
|
|
43
|
+
/*! *****************************************************************************
|
|
44
|
+
Copyright (c) Microsoft Corporation.
|
|
45
|
+
|
|
46
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
47
|
+
purpose with or without fee is hereby granted.
|
|
48
|
+
|
|
49
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
50
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
51
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
52
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
53
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
54
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
55
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
56
|
+
***************************************************************************** */
|
|
57
|
+
|
|
58
|
+
function __rest(s, e) {
|
|
59
|
+
var t = {};
|
|
60
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
61
|
+
t[p] = s[p];
|
|
62
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
63
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
64
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
65
|
+
t[p[i]] = s[p[i]];
|
|
66
|
+
}
|
|
67
|
+
return t;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const ICONS = {
|
|
71
|
+
add: proSolidSvgIcons.faPlus,
|
|
72
|
+
delete: proSolidSvgIcons.faTrashAlt,
|
|
73
|
+
save: proSolidSvgIcons.faSave,
|
|
74
|
+
activate: proRegularSvgIcons.faCheckCircle,
|
|
75
|
+
deactivate: proRegularSvgIcons.faCircle,
|
|
76
|
+
online: proLightSvgIcons.faWifi,
|
|
77
|
+
offline: proLightSvgIcons.faWifiSlash,
|
|
78
|
+
noIcon: proSolidSvgIcons.faCrow,
|
|
79
|
+
close: proSolidSvgIcons.faTimes,
|
|
80
|
+
waiting: proSolidSvgIcons.faSync,
|
|
81
|
+
refresh: proSolidSvgIcons.faSync,
|
|
82
|
+
menu: proLightSvgIcons.faBars,
|
|
83
|
+
search: proLightSvgIcons.faSearch,
|
|
84
|
+
expand: proRegularSvgIcons.faChevronDown,
|
|
85
|
+
collapse: proRegularSvgIcons.faChevronUp,
|
|
86
|
+
help: proLightSvgIcons.faQuestionCircle,
|
|
87
|
+
debug: proLightSvgIcons.faNarwhal,
|
|
88
|
+
goTo: proLightSvgIcons.faChevronRight,
|
|
89
|
+
goBack: proLightSvgIcons.faChevronLeft,
|
|
90
|
+
download: proLightSvgIcons.faCloudDownload,
|
|
91
|
+
upload: proLightSvgIcons.faCloudUpload,
|
|
92
|
+
selected: proSolidSvgIcons.faCheckSquare,
|
|
93
|
+
unselected: proRegularSvgIcons.faSquare,
|
|
94
|
+
pagerLeft: proLightSvgIcons.faChevronLeft,
|
|
95
|
+
pagerRight: proLightSvgIcons.faChevronRight,
|
|
96
|
+
sortAsc: proRegularSvgIcons.faChevronUp,
|
|
97
|
+
sortDesc: proRegularSvgIcons.faChevronDown,
|
|
98
|
+
pickDate: proLightSvgIcons.faCalendarAlt,
|
|
99
|
+
copy: proLightSvgIcons.faCopy,
|
|
100
|
+
paste: proLightSvgIcons.faPaste,
|
|
101
|
+
clear: proRegularSvgIcons.faTimesCircle,
|
|
102
|
+
hide: proLightSvgIcons.faEyeSlash,
|
|
103
|
+
show: proLightSvgIcons.faEye
|
|
104
|
+
};
|
|
105
|
+
const Icon = (props) => {
|
|
106
|
+
var _a;
|
|
107
|
+
const icon = (_a = ICONS[props.id]) !== null && _a !== void 0 ? _a : ICONS['noIcon'];
|
|
108
|
+
return React__namespace.createElement(reactFontawesome.FontAwesomeIcon, { style: props.style, onClick: props.onClick, spin: props.spin, className: css.cx('icon', props.className), icon: icon });
|
|
109
|
+
};
|
|
110
|
+
|
|
43
111
|
/** Call this on your theme after messing with the props. It will re-build things that depend on sizes and colors. */
|
|
44
112
|
const calcDynamicThemeProps = (theme) => {
|
|
45
113
|
theme.controls.border = `${theme.controls.borderWidth} solid ${theme.colors.border}`;
|
|
@@ -48,6 +116,8 @@ const calcDynamicThemeProps = (theme) => {
|
|
|
48
116
|
theme.controls.focusOutlineRequiredShadow = `0px 0px 4px 2px ${theme.colors.focusOutlineRequired}`;
|
|
49
117
|
theme.controls.dividerBorder = `2px solid ${theme.colors.divider}`;
|
|
50
118
|
theme.controls.inputErrorMinHeight = `calc(${theme.fonts.sizeSmall} * 1.5 + 4px)`;
|
|
119
|
+
theme.mediaQueries.desktop = `@media(min-width:${theme.breakpoints.desktop})`;
|
|
120
|
+
theme.mediaQueries.tablet = `@media(min-width:${theme.breakpoints.tablet})`;
|
|
51
121
|
};
|
|
52
122
|
const defaultTheme = {
|
|
53
123
|
colors: {
|
|
@@ -77,7 +147,7 @@ const defaultTheme = {
|
|
|
77
147
|
divider: 'rgba(0, 0, 0, 0.50)',
|
|
78
148
|
nav: '#7851a9',
|
|
79
149
|
navFont: 'rgba(255, 255, 255, 0.9)',
|
|
80
|
-
focusOutline: '
|
|
150
|
+
focusOutline: 'rgb(0 188 212 / 75%)',
|
|
81
151
|
progressBg: '#007bff63',
|
|
82
152
|
progressFill: '#007bff',
|
|
83
153
|
modalBg: 'white',
|
|
@@ -135,6 +205,10 @@ const defaultTheme = {
|
|
|
135
205
|
breakpoints: {
|
|
136
206
|
desktop: '800px',
|
|
137
207
|
tablet: '768px'
|
|
208
|
+
},
|
|
209
|
+
mediaQueries: {
|
|
210
|
+
desktop: '',
|
|
211
|
+
tablet: ''
|
|
138
212
|
}
|
|
139
213
|
};
|
|
140
214
|
calcDynamicThemeProps(defaultTheme);
|
|
@@ -155,193 +229,9 @@ const useThemeSafely = () => {
|
|
|
155
229
|
return defaultTheme;
|
|
156
230
|
};
|
|
157
231
|
|
|
158
|
-
|
|
159
|
-
const Backdrop$1 = (props) => {
|
|
232
|
+
const Button = React__namespace.forwardRef((props, ref) => {
|
|
160
233
|
var _a;
|
|
161
|
-
const
|
|
162
|
-
const backdropId = React__namespace.useRef('Backdrop' + nanoid.nanoid());
|
|
163
|
-
const theme = useThemeSafely();
|
|
164
|
-
const backdropStyles = css.css `
|
|
165
|
-
opacity: 0;
|
|
166
|
-
position: fixed;
|
|
167
|
-
top: 0;
|
|
168
|
-
left: 0;
|
|
169
|
-
right: 0;
|
|
170
|
-
bottom: 0;
|
|
171
|
-
background-color: ${theme.colors.backdrop};
|
|
172
|
-
transition: opacity ${showTimeMs}ms ease-in-out;
|
|
173
|
-
visibility: hidden;
|
|
174
|
-
user-select: none;
|
|
175
|
-
-webkit-tap-highlight-color: transparent;
|
|
176
|
-
`;
|
|
177
|
-
const showStyles = css.css `
|
|
178
|
-
z-index: ${theme.zIndexes.backdrop} !important;
|
|
179
|
-
opacity: 1.0 !important;
|
|
180
|
-
label:${backdropId.current};
|
|
181
|
-
`;
|
|
182
|
-
const bodyStyles = css.css `
|
|
183
|
-
overflow: hidden !important;
|
|
184
|
-
label:${backdropId.current};
|
|
185
|
-
`;
|
|
186
|
-
const bodyResponsiveStyles = css.css `
|
|
187
|
-
label:${backdropId.current};
|
|
188
|
-
@media(min-width:${theme.breakpoints.desktop}) {
|
|
189
|
-
overflow: auto !important;
|
|
190
|
-
}
|
|
191
|
-
`;
|
|
192
|
-
const bodyReverseResponsiveStyles = css.css `
|
|
193
|
-
${bodyStyles}
|
|
194
|
-
overflow: auto !important;
|
|
195
|
-
@media(min-width:${theme.breakpoints.desktop}) {
|
|
196
|
-
overflow: hidden !important;
|
|
197
|
-
}
|
|
198
|
-
`;
|
|
199
|
-
const styles = css.css `
|
|
200
|
-
${backdropStyles}
|
|
201
|
-
${props.onClick && `
|
|
202
|
-
cursor: pointer;
|
|
203
|
-
`}
|
|
204
|
-
${props.transparent && `
|
|
205
|
-
background-color: transparent;
|
|
206
|
-
transition: none;
|
|
207
|
-
`}
|
|
208
|
-
${props.children && `
|
|
209
|
-
display: flex;
|
|
210
|
-
justify-content:center;
|
|
211
|
-
align-items: center;
|
|
212
|
-
`}
|
|
213
|
-
${props.responsive && `
|
|
214
|
-
@media(min-width:${theme.breakpoints.desktop}) {
|
|
215
|
-
display: none;
|
|
216
|
-
}
|
|
217
|
-
`}
|
|
218
|
-
${props.reverseResponsive && `
|
|
219
|
-
display: none;
|
|
220
|
-
@media(min-width:${theme.breakpoints.desktop}) {
|
|
221
|
-
display: flex;
|
|
222
|
-
}
|
|
223
|
-
`}
|
|
224
|
-
`;
|
|
225
|
-
const backdrop = React__namespace.useRef(null);
|
|
226
|
-
React__namespace.useEffect(() => {
|
|
227
|
-
if (backdrop && backdrop.current) {
|
|
228
|
-
if (props.show && backdrop.current.style.visibility !== 'visible') {
|
|
229
|
-
backdrop.current.style.visibility = 'visible';
|
|
230
|
-
backdrop.current.classList.add(showStyles);
|
|
231
|
-
if (!props.allowScroll) {
|
|
232
|
-
document.body.classList.add(bodyStyles);
|
|
233
|
-
if (props.responsive) {
|
|
234
|
-
document.body.classList.add(bodyResponsiveStyles);
|
|
235
|
-
}
|
|
236
|
-
else if (props.reverseResponsive) {
|
|
237
|
-
document.body.classList.add(bodyReverseResponsiveStyles);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
else if (!props.show && backdrop.current.style.visibility === 'visible') {
|
|
242
|
-
backdrop.current.classList.remove(showStyles);
|
|
243
|
-
if (backdrop && backdrop.current) {
|
|
244
|
-
backdrop.current.style.visibility = 'hidden';
|
|
245
|
-
if (!props.allowScroll) {
|
|
246
|
-
document.body.classList.remove(bodyStyles);
|
|
247
|
-
if (props.responsive) {
|
|
248
|
-
document.body.classList.remove(bodyResponsiveStyles);
|
|
249
|
-
}
|
|
250
|
-
else if (props.reverseResponsive) {
|
|
251
|
-
document.body.classList.remove(bodyReverseResponsiveStyles);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
return () => {
|
|
258
|
-
if (backdrop && backdrop.current && !props.allowScroll) {
|
|
259
|
-
document.body.classList.remove(bodyStyles);
|
|
260
|
-
}
|
|
261
|
-
};
|
|
262
|
-
}, [props.show]);
|
|
263
|
-
return (React__namespace.createElement("div", { onMouseDown: e => {
|
|
264
|
-
var _a;
|
|
265
|
-
e.stopPropagation();
|
|
266
|
-
e.preventDefault();
|
|
267
|
-
(_a = props.onClick) === null || _a === void 0 ? void 0 : _a.call(props);
|
|
268
|
-
}, onClick: e => {
|
|
269
|
-
e.stopPropagation();
|
|
270
|
-
e.preventDefault();
|
|
271
|
-
}, ref: backdrop, className: css.cx('backdrop', styles, props.className) }, props.children));
|
|
272
|
-
};
|
|
273
|
-
|
|
274
|
-
/*! *****************************************************************************
|
|
275
|
-
Copyright (c) Microsoft Corporation.
|
|
276
|
-
|
|
277
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
278
|
-
purpose with or without fee is hereby granted.
|
|
279
|
-
|
|
280
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
281
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
282
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
283
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
284
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
285
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
286
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
287
|
-
***************************************************************************** */
|
|
288
|
-
|
|
289
|
-
function __rest(s, e) {
|
|
290
|
-
var t = {};
|
|
291
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
292
|
-
t[p] = s[p];
|
|
293
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
294
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
295
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
296
|
-
t[p[i]] = s[p[i]];
|
|
297
|
-
}
|
|
298
|
-
return t;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
const ICONS = {
|
|
302
|
-
add: proSolidSvgIcons.faPlus,
|
|
303
|
-
delete: proSolidSvgIcons.faTrashAlt,
|
|
304
|
-
save: proSolidSvgIcons.faSave,
|
|
305
|
-
activate: proRegularSvgIcons.faCheckCircle,
|
|
306
|
-
deactivate: proRegularSvgIcons.faCircle,
|
|
307
|
-
online: proLightSvgIcons.faWifi,
|
|
308
|
-
offline: proLightSvgIcons.faWifiSlash,
|
|
309
|
-
noIcon: proSolidSvgIcons.faCrow,
|
|
310
|
-
close: proSolidSvgIcons.faTimes,
|
|
311
|
-
waiting: proSolidSvgIcons.faSync,
|
|
312
|
-
refresh: proSolidSvgIcons.faSync,
|
|
313
|
-
menu: proLightSvgIcons.faBars,
|
|
314
|
-
search: proLightSvgIcons.faSearch,
|
|
315
|
-
expand: proRegularSvgIcons.faChevronDown,
|
|
316
|
-
collapse: proRegularSvgIcons.faChevronUp,
|
|
317
|
-
help: proLightSvgIcons.faQuestionCircle,
|
|
318
|
-
debug: proLightSvgIcons.faNarwhal,
|
|
319
|
-
goTo: proLightSvgIcons.faChevronRight,
|
|
320
|
-
goBack: proLightSvgIcons.faChevronLeft,
|
|
321
|
-
download: proLightSvgIcons.faCloudDownload,
|
|
322
|
-
upload: proLightSvgIcons.faCloudUpload,
|
|
323
|
-
selected: proSolidSvgIcons.faCheckSquare,
|
|
324
|
-
unselected: proRegularSvgIcons.faSquare,
|
|
325
|
-
pagerLeft: proLightSvgIcons.faChevronLeft,
|
|
326
|
-
pagerRight: proLightSvgIcons.faChevronRight,
|
|
327
|
-
sortAsc: proRegularSvgIcons.faChevronUp,
|
|
328
|
-
sortDesc: proRegularSvgIcons.faChevronDown,
|
|
329
|
-
pickDate: proLightSvgIcons.faCalendarAlt,
|
|
330
|
-
copy: proLightSvgIcons.faCopy,
|
|
331
|
-
paste: proLightSvgIcons.faPaste,
|
|
332
|
-
clear: proRegularSvgIcons.faTimesCircle,
|
|
333
|
-
hide: proLightSvgIcons.faEyeSlash,
|
|
334
|
-
show: proLightSvgIcons.faEye
|
|
335
|
-
};
|
|
336
|
-
const Icon = (props) => {
|
|
337
|
-
var _a;
|
|
338
|
-
const icon = (_a = ICONS[props.id]) !== null && _a !== void 0 ? _a : ICONS['noIcon'];
|
|
339
|
-
return React__namespace.createElement(reactFontawesome.FontAwesomeIcon, { style: props.style, onClick: props.onClick, spin: props.spin, className: css.cx('icon', props.className), icon: icon });
|
|
340
|
-
};
|
|
341
|
-
|
|
342
|
-
const Button = (props) => {
|
|
343
|
-
var _a, _b;
|
|
344
|
-
const nativeProps = __rest(props, ["variant", "textAlign", "block", "round", "rightIcon", "leftIcon", "iconBlock", "small", "readOnly", "waiting", "enforceMinWidth"]);
|
|
234
|
+
const nativeProps = __rest(props, ["variant", "round", "rightIcon", "leftIcon", "iconBlock", "small", "readOnly", "waiting", "enforceMinWidth"]);
|
|
345
235
|
const theme = useThemeSafely();
|
|
346
236
|
const buttonStyles = css.css `
|
|
347
237
|
padding-left: ${theme.controls.padding};
|
|
@@ -358,7 +248,6 @@ const Button = (props) => {
|
|
|
358
248
|
font-weight: bold;
|
|
359
249
|
flex-shrink: 0;
|
|
360
250
|
min-width: ${theme.controls.height};
|
|
361
|
-
text-align: ${(_a = props.textAlign) !== null && _a !== void 0 ? _a : 'center'};
|
|
362
251
|
|
|
363
252
|
&:disabled {
|
|
364
253
|
opacity: ${theme.controls.disabledOpacity};
|
|
@@ -497,9 +386,6 @@ const Button = (props) => {
|
|
|
497
386
|
${props.round && `
|
|
498
387
|
border-radius: ${theme.controls.roundRadius};
|
|
499
388
|
`}
|
|
500
|
-
${props.block && `
|
|
501
|
-
width: 100%;
|
|
502
|
-
`}
|
|
503
389
|
${props.iconBlock && `
|
|
504
390
|
display: flex;
|
|
505
391
|
justify-content: space-between;
|
|
@@ -507,10 +393,94 @@ const Button = (props) => {
|
|
|
507
393
|
`}
|
|
508
394
|
`;
|
|
509
395
|
const disabled = props.disabled || props.waiting;
|
|
510
|
-
return (React__namespace.createElement("button", Object.assign({}, nativeProps, { disabled: disabled, className: css.cx('button', styles, props.className), type: (
|
|
396
|
+
return (React__namespace.createElement("button", Object.assign({}, nativeProps, { ref: ref, disabled: disabled, className: css.cx('button', styles, props.className), type: (_a = props.type) !== null && _a !== void 0 ? _a : 'button' }),
|
|
511
397
|
props.leftIcon && React__namespace.createElement("span", { className: css.css({ marginRight: '0.5rem' }) }, props.leftIcon),
|
|
512
398
|
props.waiting ? React__namespace.createElement(Icon, { id: "waiting", spin: true }) : props.children,
|
|
513
399
|
props.rightIcon && React__namespace.createElement("span", { className: css.css({ marginLeft: '0.5rem' }) }, props.rightIcon)));
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
const accordianExpandTimeMs = 250;
|
|
403
|
+
const accordianMaxHeight = 1020;
|
|
404
|
+
const accordianTimingFunction = 'ease-in-out';
|
|
405
|
+
// we need to apply the seperately so stuff doesn't hang over during expand/collapse.
|
|
406
|
+
// if we remove this and just keep overflow:hidden, autocompletes will get cut off in the subpanels.
|
|
407
|
+
const visibleStyle = css.css({
|
|
408
|
+
overflow: 'visible !important'
|
|
409
|
+
});
|
|
410
|
+
const Accordian = (props) => {
|
|
411
|
+
var _a, _b, _c, _d;
|
|
412
|
+
const [open, setOpen] = React__namespace.useState(false);
|
|
413
|
+
const theme = useThemeSafely();
|
|
414
|
+
const content = React__namespace.useRef(null);
|
|
415
|
+
const contentStyles = css.css({
|
|
416
|
+
overflow: 'hidden',
|
|
417
|
+
maxHeight: 0,
|
|
418
|
+
transition: `max-height ${(_a = props.expandTimeMs) !== null && _a !== void 0 ? _a : accordianExpandTimeMs}ms ${(_b = props.transitionTimingFunction) !== null && _b !== void 0 ? _b : accordianTimingFunction}`
|
|
419
|
+
});
|
|
420
|
+
const expandedContentStyles = css.css({
|
|
421
|
+
maxHeight: (_c = props.maxHeight) !== null && _c !== void 0 ? _c : accordianMaxHeight
|
|
422
|
+
});
|
|
423
|
+
const expandedContentWrapperStyles = !props.noPad ? css.css({
|
|
424
|
+
padding: '0 1rem 1rem 1rem'
|
|
425
|
+
}) : undefined;
|
|
426
|
+
React__namespace.useEffect(() => {
|
|
427
|
+
const currentContent = content.current;
|
|
428
|
+
if (currentContent) {
|
|
429
|
+
if (open) {
|
|
430
|
+
currentContent.classList.add(expandedContentStyles);
|
|
431
|
+
window.setTimeout(() => {
|
|
432
|
+
currentContent.classList.add(visibleStyle);
|
|
433
|
+
}, accordianExpandTimeMs);
|
|
434
|
+
}
|
|
435
|
+
else {
|
|
436
|
+
currentContent.classList.remove(visibleStyle, expandedContentStyles);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}, [open]);
|
|
440
|
+
React__namespace.useEffect(() => {
|
|
441
|
+
var _a;
|
|
442
|
+
if (props.open === undefined) {
|
|
443
|
+
// technically, we only need to use this effect if props.open was initialized with a boolean.
|
|
444
|
+
// you can't have conditional effects so here we go...
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
setOpen((_a = props.open) !== null && _a !== void 0 ? _a : false);
|
|
448
|
+
}, [props.open]);
|
|
449
|
+
return (React__namespace.createElement("div", { className: "accordian" },
|
|
450
|
+
React__namespace.createElement(Button, { readOnly: props.disabled, variant: props.variant, className: css.cx(css.css({
|
|
451
|
+
display: 'flex',
|
|
452
|
+
alignItems: 'center',
|
|
453
|
+
justifyContent: 'space-between',
|
|
454
|
+
height: 'auto',
|
|
455
|
+
minHeight: theme.controls.height,
|
|
456
|
+
width: ((_d = props.block) !== null && _d !== void 0 ? _d : true) ? '100%' : 'auto'
|
|
457
|
+
}, props.className)), onClick: e => {
|
|
458
|
+
e.stopPropagation();
|
|
459
|
+
if (props.onChange) {
|
|
460
|
+
props.onChange(!open);
|
|
461
|
+
}
|
|
462
|
+
else {
|
|
463
|
+
setOpen(!open);
|
|
464
|
+
}
|
|
465
|
+
}, rightIcon: !props.disabled ? React__namespace.createElement(Icon, { id: open ? 'collapse' : 'expand' }) : undefined },
|
|
466
|
+
React__namespace.createElement("span", null, props.header)),
|
|
467
|
+
React__namespace.createElement("div", { ref: content, className: css.cx('accordian__body', contentStyles) },
|
|
468
|
+
React__namespace.createElement("div", { className: expandedContentWrapperStyles }, props.children))));
|
|
469
|
+
};
|
|
470
|
+
const useAccordianState = (count, openIndex) => {
|
|
471
|
+
const [panels, setShowPanel] = React__namespace.useState(new Array(count).fill(false).map((b, i) => {
|
|
472
|
+
return i === openIndex;
|
|
473
|
+
}));
|
|
474
|
+
return [
|
|
475
|
+
panels,
|
|
476
|
+
(index, open) => {
|
|
477
|
+
setShowPanel(previousState => {
|
|
478
|
+
const newState = previousState.slice().fill(false);
|
|
479
|
+
newState[index] = open;
|
|
480
|
+
return newState;
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
];
|
|
514
484
|
};
|
|
515
485
|
|
|
516
486
|
const DEFAULT_DEBOUNCE_MS = 250;
|
|
@@ -854,25 +824,12 @@ const Text = (props) => {
|
|
|
854
824
|
}, props.children);
|
|
855
825
|
};
|
|
856
826
|
|
|
857
|
-
const DEFAULT_MAX_SHOWN_VALUES = 7;
|
|
858
|
-
const getAutocompleteValueText = (v) => {
|
|
859
|
-
if (!v) {
|
|
860
|
-
return '';
|
|
861
|
-
}
|
|
862
|
-
if (typeof v === 'string') {
|
|
863
|
-
return v;
|
|
864
|
-
}
|
|
865
|
-
return v.name;
|
|
866
|
-
};
|
|
867
|
-
const getAutocompleteValueId = (v) => {
|
|
868
|
-
if (typeof v === 'string') {
|
|
869
|
-
return v;
|
|
870
|
-
}
|
|
871
|
-
return v.id;
|
|
872
|
-
};
|
|
873
827
|
//TB: FUTURE will need to use the new input
|
|
828
|
+
const defaultMaxShownValues = 7;
|
|
829
|
+
const buttonMarkerClass = 'ListItem__button';
|
|
874
830
|
const Autocomplete = (p) => {
|
|
875
831
|
var _a;
|
|
832
|
+
const theme = useThemeSafely();
|
|
876
833
|
const element = React__namespace.useRef(null);
|
|
877
834
|
const input = React__namespace.useRef(null);
|
|
878
835
|
const list = React__namespace.useRef(null);
|
|
@@ -880,7 +837,7 @@ const Autocomplete = (p) => {
|
|
|
880
837
|
const showValues = React__namespace.useMemo(() => values.length > 0, [values]);
|
|
881
838
|
const shownValues = React__namespace.useMemo(() => {
|
|
882
839
|
var _a;
|
|
883
|
-
return values.slice(0, (_a = p.maxShownValues) !== null && _a !== void 0 ? _a :
|
|
840
|
+
return values.slice(0, (_a = p.maxShownValues) !== null && _a !== void 0 ? _a : defaultMaxShownValues);
|
|
884
841
|
}, [values]);
|
|
885
842
|
const onChangeForOptions = React__namespace.useRef(lodash.debounce((value) => {
|
|
886
843
|
if (!p.minChars || value.length >= p.minChars) {
|
|
@@ -894,182 +851,330 @@ const Autocomplete = (p) => {
|
|
|
894
851
|
else {
|
|
895
852
|
setValues([]);
|
|
896
853
|
}
|
|
897
|
-
}, (_a = p.getOptionsDebounceMs) !== null && _a !== void 0 ? _a : 0, { leading:
|
|
898
|
-
const
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
854
|
+
}, (_a = p.getOptionsDebounceMs) !== null && _a !== void 0 ? _a : 0, { leading: false, trailing: true }));
|
|
855
|
+
const getNextTabElement = (fromIndex, direction) => {
|
|
856
|
+
var _a, _b, _c;
|
|
857
|
+
if (fromIndex === -1) {
|
|
858
|
+
let buttonIndex = 0;
|
|
859
|
+
if (direction === -1) {
|
|
860
|
+
buttonIndex = shownValues.length - 1;
|
|
861
|
+
}
|
|
862
|
+
return (_a = list.current) === null || _a === void 0 ? void 0 : _a.querySelector(`.${buttonMarkerClass}${buttonIndex}`);
|
|
863
|
+
}
|
|
864
|
+
else {
|
|
865
|
+
const nextIndex = fromIndex + direction;
|
|
866
|
+
if (nextIndex >= shownValues.length || nextIndex < 0) {
|
|
867
|
+
return (_b = input.current) !== null && _b !== void 0 ? _b : undefined;
|
|
868
|
+
}
|
|
869
|
+
else {
|
|
870
|
+
return (_c = list.current) === null || _c === void 0 ? void 0 : _c.querySelector(`.${buttonMarkerClass}${nextIndex}`);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
};
|
|
874
|
+
React__namespace.useEffect(() => {
|
|
875
|
+
const clearItems = () => {
|
|
876
|
+
if (values.length > 0) {
|
|
877
|
+
setValues([]);
|
|
878
|
+
}
|
|
879
|
+
};
|
|
880
|
+
document.addEventListener('click', clearItems);
|
|
881
|
+
return () => {
|
|
882
|
+
document.removeEventListener('click', clearItems);
|
|
883
|
+
};
|
|
884
|
+
}, [values]);
|
|
904
885
|
let listBorderRadius = '';
|
|
905
886
|
if (p.round || theme.controls.borderRadius) {
|
|
906
887
|
listBorderRadius = theme.controls.borderRadius || '0.5rem';
|
|
907
888
|
}
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
},
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
889
|
+
return (React__namespace.createElement("div", { onClick: e => {
|
|
890
|
+
e.stopPropagation();
|
|
891
|
+
}, onKeyDown: e => {
|
|
892
|
+
var _a;
|
|
893
|
+
if (e.key === 'Escape') {
|
|
894
|
+
setValues([]);
|
|
895
|
+
(_a = input.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
896
|
+
}
|
|
897
|
+
}, ref: element, className: css.cx(css.css({
|
|
898
|
+
position: 'relative',
|
|
899
|
+
width: '100%',
|
|
900
|
+
label: 'Autocomplete'
|
|
901
|
+
}), 'autocomplete') },
|
|
902
|
+
React__namespace.createElement(TabLocker, { disabled: !showValues, style: { position: 'relative' } },
|
|
903
|
+
React__namespace.createElement(Input, { inputAriaAttributes: p.inputAriaAttributes, ref: input, debounceMs: 0, type: "text", value: getAutocompleteValueText(p.value), round: p.round, rightControl: p.rightControl, placeholder: p.placeholder, id: p.id, disabled: p.disabled, className: p.className, inputClassName: p.inputClassName, maxLength: p.maxLength, required: p.required, onChange: v => {
|
|
904
|
+
const value = v;
|
|
905
|
+
p.onChange(value);
|
|
906
|
+
onChangeForOptions.current(value);
|
|
907
|
+
}, onKeyDown: e => {
|
|
908
|
+
var _a, _b, _c;
|
|
909
|
+
if (showValues) {
|
|
910
|
+
if (e.key === 'ArrowDown') {
|
|
911
|
+
e.preventDefault();
|
|
912
|
+
e.stopPropagation();
|
|
913
|
+
(_a = getNextTabElement(-1, 1)) === null || _a === void 0 ? void 0 : _a.focus();
|
|
914
|
+
}
|
|
915
|
+
else if (e.key === 'ArrowUp') {
|
|
916
|
+
e.preventDefault();
|
|
917
|
+
e.stopPropagation();
|
|
918
|
+
(_b = getNextTabElement(-1, -1)) === null || _b === void 0 ? void 0 : _b.focus();
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
(_c = p.onKeyDown) === null || _c === void 0 ? void 0 : _c.call(p, e);
|
|
922
|
+
}, onKeyPress: e => { var _a; return (_a = p.onKeyPress) === null || _a === void 0 ? void 0 : _a.call(p, e); } }),
|
|
923
|
+
showValues && (React__namespace.createElement(List, { ref: list, className: css.css({
|
|
924
|
+
position: 'absolute',
|
|
925
|
+
width: '100%',
|
|
926
|
+
border: theme.controls.border,
|
|
927
|
+
borderRadius: listBorderRadius,
|
|
928
|
+
boxShadow: theme.controls.boxShadow,
|
|
929
|
+
backgroundColor: theme.colors.bg,
|
|
930
|
+
marginTop: `-4px !important`,
|
|
931
|
+
zIndex: theme.zIndexes.backdrop,
|
|
932
|
+
'li:first-child button': {
|
|
933
|
+
borderTopRightRadius: listBorderRadius,
|
|
934
|
+
borderTopLeftRadius: listBorderRadius,
|
|
935
|
+
},
|
|
936
|
+
'li:last-child button': {
|
|
937
|
+
borderBottomRightRadius: listBorderRadius,
|
|
938
|
+
borderBottomLeftRadius: listBorderRadius,
|
|
939
|
+
}
|
|
940
|
+
}) },
|
|
941
|
+
shownValues.map((value, listItemIndex) => {
|
|
942
|
+
return (React__namespace.createElement(ListItem, { key: getAutocompleteValueId(value), variant: "full" },
|
|
943
|
+
React__namespace.createElement(Button, { onKeyDown: e => {
|
|
944
|
+
var _a, _b;
|
|
945
|
+
if (e.key === 'ArrowDown') {
|
|
946
|
+
e.stopPropagation();
|
|
947
|
+
e.preventDefault();
|
|
948
|
+
(_a = getNextTabElement(listItemIndex, 1)) === null || _a === void 0 ? void 0 : _a.focus();
|
|
949
|
+
}
|
|
950
|
+
else if (e.key === 'ArrowUp') {
|
|
951
|
+
e.stopPropagation();
|
|
952
|
+
e.preventDefault();
|
|
953
|
+
(_b = getNextTabElement(listItemIndex, -1)) === null || _b === void 0 ? void 0 : _b.focus();
|
|
954
|
+
}
|
|
955
|
+
}, className: css.cx(buttonMarkerClass + listItemIndex, css.css({
|
|
956
|
+
borderRadius: 0,
|
|
957
|
+
})), onClick: () => {
|
|
958
|
+
p.onPick(value);
|
|
959
|
+
setValues([]);
|
|
960
|
+
setTimeout(() => {
|
|
961
|
+
var _a;
|
|
962
|
+
// we need to wait until the component is re-rendered.
|
|
963
|
+
// outside changes to Inputs will be ignored if the component has focus.
|
|
964
|
+
(_a = input.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
965
|
+
}, 0);
|
|
966
|
+
} },
|
|
967
|
+
React__namespace.createElement(Text, { tag: "div", ellipsis: true, align: "left" }, getAutocompleteValueText(value)))));
|
|
968
|
+
}),
|
|
969
|
+
shownValues.length < values.length && (React__namespace.createElement(ListItem, null,
|
|
970
|
+
React__namespace.createElement(Text, { tag: "div", italics: true, align: "center" },
|
|
971
|
+
"Showing ",
|
|
972
|
+
shownValues.length.toLocaleString(),
|
|
973
|
+
" of ",
|
|
974
|
+
values.length.toLocaleString(),
|
|
975
|
+
" results."))))))));
|
|
976
|
+
};
|
|
977
|
+
const getAutocompleteValueText = (v) => {
|
|
978
|
+
if (!v) {
|
|
979
|
+
return '';
|
|
980
|
+
}
|
|
981
|
+
if (typeof v === 'string') {
|
|
982
|
+
return v;
|
|
983
|
+
}
|
|
984
|
+
return v.name;
|
|
985
|
+
};
|
|
986
|
+
const getAutocompleteValueId = (v) => {
|
|
987
|
+
if (typeof v === 'string') {
|
|
988
|
+
return v;
|
|
989
|
+
}
|
|
990
|
+
return v.id;
|
|
991
|
+
};
|
|
992
|
+
|
|
993
|
+
/** @deprecated Use Backdrop2 going forward. */
|
|
994
|
+
const Backdrop$1 = (props) => {
|
|
995
|
+
var _a;
|
|
996
|
+
const showTimeMs = (_a = props.showTimeMs) !== null && _a !== void 0 ? _a : 250;
|
|
997
|
+
const backdropId = React__namespace.useRef('Backdrop' + nanoid.nanoid());
|
|
998
|
+
const theme = useThemeSafely();
|
|
999
|
+
const backdropStyles = css.css `
|
|
1000
|
+
opacity: 0;
|
|
1001
|
+
position: fixed;
|
|
1002
|
+
top: 0;
|
|
1003
|
+
left: 0;
|
|
1004
|
+
right: 0;
|
|
1005
|
+
bottom: 0;
|
|
1006
|
+
background-color: ${theme.colors.backdrop};
|
|
1007
|
+
transition: opacity ${showTimeMs}ms ease-in-out;
|
|
1008
|
+
visibility: hidden;
|
|
1009
|
+
user-select: none;
|
|
1010
|
+
-webkit-tap-highlight-color: transparent;
|
|
1011
|
+
`;
|
|
1012
|
+
const showStyles = css.css `
|
|
1013
|
+
z-index: ${theme.zIndexes.backdrop} !important;
|
|
1014
|
+
opacity: 1.0 !important;
|
|
1015
|
+
label:${backdropId.current};
|
|
1016
|
+
`;
|
|
1017
|
+
const bodyStyles = css.css `
|
|
1018
|
+
overflow: hidden !important;
|
|
1019
|
+
label:${backdropId.current};
|
|
1020
|
+
`;
|
|
1021
|
+
const bodyResponsiveStyles = css.css `
|
|
1022
|
+
label:${backdropId.current};
|
|
1023
|
+
@media(min-width:${theme.breakpoints.desktop}) {
|
|
1024
|
+
overflow: auto !important;
|
|
1025
|
+
}
|
|
1026
|
+
`;
|
|
1027
|
+
const bodyReverseResponsiveStyles = css.css `
|
|
1028
|
+
${bodyStyles}
|
|
1029
|
+
overflow: auto !important;
|
|
1030
|
+
@media(min-width:${theme.breakpoints.desktop}) {
|
|
1031
|
+
overflow: hidden !important;
|
|
1032
|
+
}
|
|
1033
|
+
`;
|
|
1034
|
+
const styles = css.css `
|
|
1035
|
+
${backdropStyles}
|
|
1036
|
+
${props.onClick && `
|
|
1037
|
+
cursor: pointer;
|
|
1038
|
+
`}
|
|
1039
|
+
${props.transparent && `
|
|
1040
|
+
background-color: transparent;
|
|
1041
|
+
transition: none;
|
|
1042
|
+
`}
|
|
1043
|
+
${props.children && `
|
|
1044
|
+
display: flex;
|
|
1045
|
+
justify-content:center;
|
|
1046
|
+
align-items: center;
|
|
1047
|
+
`}
|
|
1048
|
+
${props.responsive && `
|
|
1049
|
+
@media(min-width:${theme.breakpoints.desktop}) {
|
|
1050
|
+
display: none;
|
|
1051
|
+
}
|
|
1052
|
+
`}
|
|
1053
|
+
${props.reverseResponsive && `
|
|
1054
|
+
display: none;
|
|
1055
|
+
@media(min-width:${theme.breakpoints.desktop}) {
|
|
1056
|
+
display: flex;
|
|
1057
|
+
}
|
|
930
1058
|
`}
|
|
931
1059
|
`;
|
|
932
|
-
const
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
if (nextIndex >= shownValues.length || nextIndex < 0) {
|
|
948
|
-
return (_b = input.current) !== null && _b !== void 0 ? _b : undefined;
|
|
949
|
-
}
|
|
950
|
-
else {
|
|
951
|
-
return (_c = list.current) === null || _c === void 0 ? void 0 : _c.querySelector(`.${buttonMarkerClass}${nextIndex}`);
|
|
1060
|
+
const backdrop = React__namespace.useRef(null);
|
|
1061
|
+
React__namespace.useEffect(() => {
|
|
1062
|
+
if (backdrop && backdrop.current) {
|
|
1063
|
+
if (props.show && backdrop.current.style.visibility !== 'visible') {
|
|
1064
|
+
backdrop.current.style.visibility = 'visible';
|
|
1065
|
+
backdrop.current.classList.add(showStyles);
|
|
1066
|
+
if (!props.allowScroll) {
|
|
1067
|
+
document.body.classList.add(bodyStyles);
|
|
1068
|
+
if (props.responsive) {
|
|
1069
|
+
document.body.classList.add(bodyResponsiveStyles);
|
|
1070
|
+
}
|
|
1071
|
+
else if (props.reverseResponsive) {
|
|
1072
|
+
document.body.classList.add(bodyReverseResponsiveStyles);
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
952
1075
|
}
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
onChangeForOptions.current(value);
|
|
962
|
-
}, onKeyDown: e => {
|
|
963
|
-
var _a, _b;
|
|
964
|
-
if (showValues) {
|
|
965
|
-
if (e.key === 'ArrowDown') {
|
|
966
|
-
e.preventDefault();
|
|
967
|
-
e.stopPropagation();
|
|
968
|
-
(_a = getNextTabElement(-1, 1)) === null || _a === void 0 ? void 0 : _a.focus();
|
|
1076
|
+
else if (!props.show && backdrop.current.style.visibility === 'visible') {
|
|
1077
|
+
backdrop.current.classList.remove(showStyles);
|
|
1078
|
+
if (backdrop && backdrop.current) {
|
|
1079
|
+
backdrop.current.style.visibility = 'hidden';
|
|
1080
|
+
if (!props.allowScroll) {
|
|
1081
|
+
document.body.classList.remove(bodyStyles);
|
|
1082
|
+
if (props.responsive) {
|
|
1083
|
+
document.body.classList.remove(bodyResponsiveStyles);
|
|
969
1084
|
}
|
|
970
|
-
else if (
|
|
971
|
-
|
|
972
|
-
e.stopPropagation();
|
|
973
|
-
(_b = getNextTabElement(-1, -1)) === null || _b === void 0 ? void 0 : _b.focus();
|
|
1085
|
+
else if (props.reverseResponsive) {
|
|
1086
|
+
document.body.classList.remove(bodyReverseResponsiveStyles);
|
|
974
1087
|
}
|
|
975
1088
|
}
|
|
976
|
-
}
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
shownValues.length.toLocaleString(),
|
|
1008
|
-
" of ",
|
|
1009
|
-
values.length.toLocaleString(),
|
|
1010
|
-
" results."))))))));
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
return () => {
|
|
1093
|
+
if (backdrop && backdrop.current && !props.allowScroll) {
|
|
1094
|
+
document.body.classList.remove(bodyStyles);
|
|
1095
|
+
}
|
|
1096
|
+
};
|
|
1097
|
+
}, [props.show]);
|
|
1098
|
+
return (React__namespace.createElement("div", { onMouseDown: e => {
|
|
1099
|
+
var _a;
|
|
1100
|
+
e.stopPropagation();
|
|
1101
|
+
e.preventDefault();
|
|
1102
|
+
(_a = props.onClick) === null || _a === void 0 ? void 0 : _a.call(props);
|
|
1103
|
+
}, onClick: e => {
|
|
1104
|
+
e.stopPropagation();
|
|
1105
|
+
e.preventDefault();
|
|
1106
|
+
}, ref: backdrop, className: css.cx('backdrop', styles, props.className) }, props.children));
|
|
1107
|
+
};
|
|
1108
|
+
|
|
1109
|
+
/** useEffect but ignores the first call on component mount. */
|
|
1110
|
+
const useIgnoreMount = (effect, deps) => {
|
|
1111
|
+
const mounted = React__default['default'].useRef(false);
|
|
1112
|
+
React__default['default'].useEffect(() => {
|
|
1113
|
+
if (!mounted.current) {
|
|
1114
|
+
mounted.current = true;
|
|
1115
|
+
}
|
|
1116
|
+
else {
|
|
1117
|
+
effect();
|
|
1118
|
+
}
|
|
1119
|
+
}, deps);
|
|
1011
1120
|
};
|
|
1012
1121
|
|
|
1013
1122
|
const useLogger = (componentName, enabled) => {
|
|
1014
1123
|
return (...messages) => {
|
|
1015
1124
|
if (enabled) {
|
|
1016
1125
|
// tslint:disable-next-line
|
|
1017
|
-
console.log(componentName
|
|
1126
|
+
console.log(`[${componentName}]`, ...messages);
|
|
1018
1127
|
}
|
|
1019
1128
|
};
|
|
1020
1129
|
};
|
|
1021
1130
|
|
|
1131
|
+
const portalId = 'backdrop';
|
|
1022
1132
|
const BackdropContext = React__default['default'].createContext({
|
|
1023
1133
|
showing: false,
|
|
1024
1134
|
showCount: 0,
|
|
1025
|
-
portalId:
|
|
1026
|
-
setShow: s => {
|
|
1135
|
+
portalId: portalId,
|
|
1136
|
+
setShow: (s, f) => {
|
|
1027
1137
|
/* empty */
|
|
1028
1138
|
}
|
|
1029
1139
|
});
|
|
1030
1140
|
const BackdropContextProvider = (p) => {
|
|
1031
1141
|
var _a;
|
|
1032
1142
|
const [showCount, setShowCount] = React.useState(0);
|
|
1033
|
-
const log = useLogger('BackdropContextProvider', (_a = p.
|
|
1034
|
-
if (p.
|
|
1143
|
+
const log = useLogger('BackdropContextProvider', (_a = p.__debug) !== null && _a !== void 0 ? _a : false);
|
|
1144
|
+
if (p.__debug) {
|
|
1035
1145
|
React.useEffect(() => {
|
|
1036
1146
|
log('mounted');
|
|
1037
1147
|
return () => {
|
|
1038
1148
|
log('un-mounted');
|
|
1039
1149
|
};
|
|
1040
1150
|
}, []);
|
|
1041
|
-
|
|
1042
|
-
log('re-rendered');
|
|
1043
|
-
});
|
|
1044
|
-
React.useEffect(() => {
|
|
1151
|
+
useIgnoreMount(() => {
|
|
1045
1152
|
log('showCount changed', showCount);
|
|
1046
1153
|
}, [showCount]);
|
|
1047
1154
|
}
|
|
1048
1155
|
return (React__default['default'].createElement(BackdropContext.Provider, { value: {
|
|
1049
|
-
portalId:
|
|
1156
|
+
portalId: portalId,
|
|
1050
1157
|
showing: showCount > 0,
|
|
1051
1158
|
showCount: showCount,
|
|
1052
|
-
setShow: (show) => {
|
|
1159
|
+
setShow: (show, from) => {
|
|
1053
1160
|
if (show) {
|
|
1054
1161
|
setShowCount(s => {
|
|
1055
1162
|
const count = s + 1;
|
|
1056
|
-
log(
|
|
1057
|
-
log('showCount was', showCount);
|
|
1163
|
+
log(`setShow from ${from} ${s} -> ${count}`);
|
|
1058
1164
|
return count;
|
|
1059
1165
|
});
|
|
1060
1166
|
}
|
|
1061
1167
|
else {
|
|
1062
1168
|
setShowCount(s => {
|
|
1063
1169
|
const count = Math.max(0, s - 1);
|
|
1064
|
-
log(
|
|
1065
|
-
log('showCount was', showCount);
|
|
1170
|
+
log(`setShow from ${from} ${s} -> ${count}`);
|
|
1066
1171
|
return count;
|
|
1067
1172
|
});
|
|
1068
1173
|
}
|
|
1069
1174
|
}
|
|
1070
1175
|
} },
|
|
1071
1176
|
p.children,
|
|
1072
|
-
p.
|
|
1177
|
+
p.__debug && (React__default['default'].createElement("p", { className: css.css({
|
|
1073
1178
|
position: 'fixed',
|
|
1074
1179
|
top: 0, right: 0,
|
|
1075
1180
|
backgroundColor: '#ff00004f',
|
|
@@ -1086,23 +1191,20 @@ const BackdropOverlay = (p) => {
|
|
|
1086
1191
|
const context = React.useContext(BackdropContext);
|
|
1087
1192
|
const theme = useThemeSafely();
|
|
1088
1193
|
const showTimeMs = (_a = p.showTimeMs) !== null && _a !== void 0 ? _a : 250;
|
|
1089
|
-
const log = useLogger('BackdropOverlay', (_b = p.
|
|
1090
|
-
if (p.
|
|
1194
|
+
const log = useLogger('BackdropOverlay', (_b = p.__debug) !== null && _b !== void 0 ? _b : false);
|
|
1195
|
+
if (p.__debug) {
|
|
1091
1196
|
React.useEffect(() => {
|
|
1092
1197
|
log('mounted');
|
|
1093
1198
|
return () => {
|
|
1094
1199
|
log('unmounted');
|
|
1095
1200
|
};
|
|
1096
1201
|
}, []);
|
|
1097
|
-
|
|
1098
|
-
log('re-rendered');
|
|
1099
|
-
});
|
|
1100
|
-
React.useEffect(() => {
|
|
1202
|
+
useIgnoreMount(() => {
|
|
1101
1203
|
log('context.showing changed', context.showing);
|
|
1102
1204
|
}, [context.showing]);
|
|
1103
1205
|
}
|
|
1104
1206
|
return (React__default['default'].createElement("div", { onClick: () => {
|
|
1105
|
-
context === null || context === void 0 ? void 0 : context.setShow(false);
|
|
1207
|
+
context === null || context === void 0 ? void 0 : context.setShow(false, 'BackdropOverlay');
|
|
1106
1208
|
log('onClick', 'setShow', false);
|
|
1107
1209
|
}, id: context === null || context === void 0 ? void 0 : context.portalId, className: css.css({
|
|
1108
1210
|
cursor: 'pointer',
|
|
@@ -1118,12 +1220,12 @@ const BackdropOverlay = (p) => {
|
|
|
1118
1220
|
}) }));
|
|
1119
1221
|
};
|
|
1120
1222
|
const Backdrop = (p) => {
|
|
1121
|
-
return (React__default['default'].createElement(BackdropContextProvider, {
|
|
1223
|
+
return (React__default['default'].createElement(BackdropContextProvider, { __debug: p.__debug },
|
|
1122
1224
|
React__default['default'].createElement("div", { className: css.css({
|
|
1123
1225
|
height: '100%'
|
|
1124
1226
|
}) },
|
|
1125
1227
|
p.children,
|
|
1126
|
-
React__default['default'].createElement(BackdropOverlay, { showTimeMs: p.showTimeMs,
|
|
1228
|
+
React__default['default'].createElement(BackdropOverlay, { showTimeMs: p.showTimeMs, __debug: p.__debug }))));
|
|
1127
1229
|
};
|
|
1128
1230
|
|
|
1129
1231
|
const Calendar = (p) => {
|
|
@@ -1295,11 +1397,41 @@ const Checkbox = (props) => {
|
|
|
1295
1397
|
props.children)));
|
|
1296
1398
|
};
|
|
1297
1399
|
|
|
1400
|
+
/** useEffect but it will only fire when the actual truthiness of the value changes.
|
|
1401
|
+
* Use for comparing previous states to next states without all the bullshit around useEffect and component mounting.
|
|
1402
|
+
*/
|
|
1403
|
+
const useBooleanChanged = (effect, dep) => {
|
|
1404
|
+
/*
|
|
1405
|
+
Why?
|
|
1406
|
+
useEffect with a dependency array will fire once on mount even though the dependency list doesn't change.
|
|
1407
|
+
Components like Modal need to communicate when their show status changes.
|
|
1408
|
+
useIgnoreMount is not enough because it only ignores the first render and is therefore a kludge.
|
|
1409
|
+
This is what we want regardless of mount status:
|
|
1410
|
+
true > false = Change
|
|
1411
|
+
false > true = Change
|
|
1412
|
+
true > true = No Change
|
|
1413
|
+
false > false = No Change
|
|
1414
|
+
undefined > false = No Change
|
|
1415
|
+
undefined > true = Change
|
|
1416
|
+
*/
|
|
1417
|
+
const lastValue = React.useRef(undefined);
|
|
1418
|
+
React.useEffect(() => {
|
|
1419
|
+
//console.log('[useBooleanChanged] useEffect called with', dep, 'was', lastValue.current ?? 'undefined')
|
|
1420
|
+
if (!!lastValue.current !== !!dep) {
|
|
1421
|
+
const previous = lastValue.current;
|
|
1422
|
+
lastValue.current = dep;
|
|
1423
|
+
effect(!!lastValue.current, !!previous);
|
|
1424
|
+
//console.log('[useBooleanChanged] change called')
|
|
1425
|
+
}
|
|
1426
|
+
}, [dep]);
|
|
1427
|
+
};
|
|
1428
|
+
|
|
1298
1429
|
// Taken from: https://github.com/react-bootstrap/dom-helpers/blob/master/src/scrollbarSize.ts
|
|
1299
1430
|
const canUseDom = !!(typeof window !== 'undefined' &&
|
|
1300
1431
|
window.document &&
|
|
1301
1432
|
window.document.createElement);
|
|
1302
1433
|
let size;
|
|
1434
|
+
/** Tells you actual width of the scroll bar. This can vary by browser. */
|
|
1303
1435
|
const useScrollbarSize = (recalc) => {
|
|
1304
1436
|
if ((!size && size !== 0) || recalc) {
|
|
1305
1437
|
if (canUseDom) {
|
|
@@ -1317,7 +1449,6 @@ const useScrollbarSize = (recalc) => {
|
|
|
1317
1449
|
return size;
|
|
1318
1450
|
};
|
|
1319
1451
|
|
|
1320
|
-
let htmlBodyStyles;
|
|
1321
1452
|
const Modal = (p) => {
|
|
1322
1453
|
var _a, _b, _c, _d;
|
|
1323
1454
|
const backdrop = React.useContext(BackdropContext);
|
|
@@ -1325,42 +1456,54 @@ const Modal = (p) => {
|
|
|
1325
1456
|
const theme = useThemeSafely();
|
|
1326
1457
|
const hasHeader = p.closeButton || p.heading;
|
|
1327
1458
|
const contentRef = React__default['default'].useRef(null);
|
|
1328
|
-
const log = useLogger(
|
|
1459
|
+
const log = useLogger((_a = p.id) !== null && _a !== void 0 ? _a : 'Modal', (_b = p.__debug) !== null && _b !== void 0 ? _b : false);
|
|
1460
|
+
const showing = React.useRef(p.show);
|
|
1461
|
+
const bodyStyles = React.useRef('');
|
|
1462
|
+
const tryRemoveBodyStyles = () => {
|
|
1463
|
+
if (bodyStyles.current) {
|
|
1464
|
+
log('removing singleton', bodyStyles.current);
|
|
1465
|
+
document.body.classList.remove(bodyStyles.current);
|
|
1466
|
+
}
|
|
1467
|
+
};
|
|
1329
1468
|
React.useEffect(() => {
|
|
1330
1469
|
log('mounted');
|
|
1331
1470
|
return () => {
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
log('backdrop.
|
|
1337
|
-
|
|
1471
|
+
var _a;
|
|
1472
|
+
if (showing.current) {
|
|
1473
|
+
log(`un-mount in progress and this modal is showing. decrement the backdrop and try to remove singleton body styles.`);
|
|
1474
|
+
backdrop.setShow(false, (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal');
|
|
1475
|
+
log('backdrop.setShow', false);
|
|
1476
|
+
tryRemoveBodyStyles();
|
|
1477
|
+
}
|
|
1478
|
+
else {
|
|
1479
|
+
log(`un-mount in progress but this modal is not showing. do nothing with the backdrop.`);
|
|
1338
1480
|
}
|
|
1339
1481
|
log('un-mounted');
|
|
1340
1482
|
};
|
|
1341
1483
|
}, []);
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1484
|
+
useBooleanChanged((show, previousShow) => {
|
|
1485
|
+
var _a, _b, _c;
|
|
1486
|
+
log('show changed', `${previousShow !== null && previousShow !== void 0 ? previousShow : 'undefined'} > ${show}`);
|
|
1487
|
+
backdrop.setShow(show, (_a = p.id) !== null && _a !== void 0 ? _a : 'Modal');
|
|
1488
|
+
showing.current = show;
|
|
1489
|
+
log('backdrop.setShow', show);
|
|
1490
|
+
if (!bodyStyles.current) {
|
|
1491
|
+
bodyStyles.current = css.css({
|
|
1492
|
+
label: 'ModalBodyOverrides_' + ((_c = (_b = p.id) === null || _b === void 0 ? void 0 : _b.replace(/\s+/, '')) !== null && _c !== void 0 ? _c : nanoid.nanoid()),
|
|
1349
1493
|
overflow: 'hidden',
|
|
1350
1494
|
paddingRight: `${useScrollbarSize()}px`
|
|
1351
1495
|
});
|
|
1496
|
+
log('creating singleton bodyStyles', bodyStyles.current);
|
|
1352
1497
|
}
|
|
1353
|
-
if (
|
|
1354
|
-
log('adding
|
|
1355
|
-
document.body.classList.add(
|
|
1498
|
+
if (show) {
|
|
1499
|
+
log('this modal is showing. adding singleton bodyStyles', bodyStyles.current);
|
|
1500
|
+
document.body.classList.add(bodyStyles.current);
|
|
1356
1501
|
}
|
|
1357
1502
|
else {
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
document.body.classList.remove(htmlBodyStyles);
|
|
1361
|
-
}
|
|
1503
|
+
log('this modal is hiding. try removing singleton bodyStyles');
|
|
1504
|
+
tryRemoveBodyStyles();
|
|
1362
1505
|
}
|
|
1363
|
-
},
|
|
1506
|
+
}, p.show);
|
|
1364
1507
|
React__default['default'].useLayoutEffect(() => {
|
|
1365
1508
|
var _a;
|
|
1366
1509
|
if (p.show === true) {
|
|
@@ -1431,7 +1574,12 @@ const Modal = (p) => {
|
|
|
1431
1574
|
e.stopPropagation();
|
|
1432
1575
|
}, onMouseUp: e => {
|
|
1433
1576
|
mouseDownElement.current = undefined;
|
|
1434
|
-
|
|
1577
|
+
/*
|
|
1578
|
+
MouseDown and MouseUp stopPropagation was added to fix bugs while clicking within the modal.
|
|
1579
|
+
At least in the case of MouseUp, this breaks sliders and the handle grab logic appears to live on window.
|
|
1580
|
+
Turning this off now. Should not cause any issues for MouseUp unlike MouseDown.
|
|
1581
|
+
*/
|
|
1582
|
+
// e.stopPropagation()
|
|
1435
1583
|
}, className: css.cx('modalBody', modalBodyStyles, p.className) },
|
|
1436
1584
|
React__default['default'].createElement(TabLocker, null,
|
|
1437
1585
|
hasHeader && (React__default['default'].createElement("header", { className: css.cx('modalHeader', modalHeaderStyles) },
|
|
@@ -1461,7 +1609,7 @@ const ConfirmModal = (props) => {
|
|
|
1461
1609
|
}
|
|
1462
1610
|
`}
|
|
1463
1611
|
`;
|
|
1464
|
-
return (React__namespace.createElement(Modal, { id: props.id,
|
|
1612
|
+
return (React__namespace.createElement(Modal, { id: props.id, __debug: props.__debug, className: css.cx('confirmModal', modalStyle, props.className), heading: props.header, closeButton: true, show: props.show, onClick: props.onCancel },
|
|
1465
1613
|
React__namespace.createElement("div", { className: css.css({ padding: '1rem' }) },
|
|
1466
1614
|
React__namespace.createElement(Text, { align: "center" }, props.text),
|
|
1467
1615
|
React__namespace.createElement("div", { className: css.css({ textAlign: 'center' }) },
|
|
@@ -1491,12 +1639,12 @@ const CopyButton = (props) => {
|
|
|
1491
1639
|
React__namespace.createElement(Icon, { id: copied ? 'paste' : 'copy' })));
|
|
1492
1640
|
};
|
|
1493
1641
|
|
|
1494
|
-
const Divider = () => {
|
|
1642
|
+
const Divider = (p) => {
|
|
1495
1643
|
const theme = useThemeSafely();
|
|
1496
|
-
return (React__namespace.createElement("hr", { className: css.cx("divider", css.css({
|
|
1644
|
+
return (React__namespace.createElement("hr", Object.assign({}, p, { className: css.cx("divider", css.css({
|
|
1497
1645
|
margin: theme.controls.dividerMargin,
|
|
1498
1646
|
border: theme.controls.dividerBorder
|
|
1499
|
-
})) }));
|
|
1647
|
+
}), p.className) })));
|
|
1500
1648
|
};
|
|
1501
1649
|
|
|
1502
1650
|
const ErrorModal = (props) => {
|
|
@@ -1511,7 +1659,7 @@ const ErrorModal = (props) => {
|
|
|
1511
1659
|
color: ${theme.colors.omgFont};
|
|
1512
1660
|
}
|
|
1513
1661
|
`;
|
|
1514
|
-
return (React__namespace.createElement(Modal, { id: props.id,
|
|
1662
|
+
return (React__namespace.createElement(Modal, { id: props.id, __debug: props.__debug, className: css.cx('errorModal', modalStyles), heading: "Error", closeButton: true, show: props.show, onClick: props.close },
|
|
1515
1663
|
React__namespace.createElement("div", { className: css.css({ padding: '1rem' }) },
|
|
1516
1664
|
React__namespace.createElement(Text, { align: "center" }, message))));
|
|
1517
1665
|
};
|
|
@@ -1639,7 +1787,7 @@ const hoverClass = css.css({
|
|
|
1639
1787
|
backgroundColor: 'rgba(0,0,0,0.25) !important'
|
|
1640
1788
|
});
|
|
1641
1789
|
const FileUploader = (p) => {
|
|
1642
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
1790
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1643
1791
|
const [message, setMessage] = React.useState(undefined);
|
|
1644
1792
|
const [canUpload, setCanUpload] = React.useState(false);
|
|
1645
1793
|
const [uploading, setUploading] = React.useState(false);
|
|
@@ -1655,7 +1803,7 @@ const FileUploader = (p) => {
|
|
|
1655
1803
|
filesDisplay = (_b = p.instructionMessage) !== null && _b !== void 0 ? _b : `Click or drag and drop files.`;
|
|
1656
1804
|
}
|
|
1657
1805
|
else {
|
|
1658
|
-
filesDisplay = `${files.length.toLocaleString()} file${files.length > 1 ? 's' : ''} selected (${
|
|
1806
|
+
filesDisplay = `${files.length.toLocaleString()} file${files.length > 1 ? 's' : ''} selected (${getFileSizeDisplay(totalFileSize)}): ${files.files.map(f => f.name).join(', ')}`;
|
|
1659
1807
|
}
|
|
1660
1808
|
}
|
|
1661
1809
|
const setAllFiles = (inputFiles) => {
|
|
@@ -1677,8 +1825,9 @@ const FileUploader = (p) => {
|
|
|
1677
1825
|
maxBytes: p.maxBytes
|
|
1678
1826
|
});
|
|
1679
1827
|
};
|
|
1828
|
+
const showInfoOnPick = (_c = p.showInfoOnPick) !== null && _c !== void 0 ? _c : true;
|
|
1680
1829
|
let infoMessage;
|
|
1681
|
-
if (p.infoMessage) {
|
|
1830
|
+
if (p.infoMessage && (!files || showInfoOnPick)) {
|
|
1682
1831
|
if (typeof p.infoMessage === 'string') {
|
|
1683
1832
|
infoMessage = React__default['default'].createElement(Text, { noPad: true }, p.infoMessage);
|
|
1684
1833
|
}
|
|
@@ -1695,6 +1844,8 @@ const FileUploader = (p) => {
|
|
|
1695
1844
|
padding: '1rem',
|
|
1696
1845
|
overflow: 'hidden',
|
|
1697
1846
|
backgroundColor: theme.colors.lightBg,
|
|
1847
|
+
}, p.disabled && {
|
|
1848
|
+
opacity: theme.controls.disabledOpacity
|
|
1698
1849
|
}), onDragOver: e => {
|
|
1699
1850
|
var _a, _b;
|
|
1700
1851
|
e.preventDefault();
|
|
@@ -1728,7 +1879,7 @@ const FileUploader = (p) => {
|
|
|
1728
1879
|
setCanUpload(false);
|
|
1729
1880
|
});
|
|
1730
1881
|
} },
|
|
1731
|
-
React__default['default'].createElement("input", { ref: input, className: css.css({
|
|
1882
|
+
React__default['default'].createElement("input", { disabled: p.disabled, ref: input, className: css.css({
|
|
1732
1883
|
position: 'absolute',
|
|
1733
1884
|
top: -50,
|
|
1734
1885
|
left: 0,
|
|
@@ -1737,6 +1888,8 @@ const FileUploader = (p) => {
|
|
|
1737
1888
|
width: '100%',
|
|
1738
1889
|
cursor: 'pointer',
|
|
1739
1890
|
opacity: 0
|
|
1891
|
+
}, p.disabled && {
|
|
1892
|
+
cursor: 'not-allowed'
|
|
1740
1893
|
}), type: "file", multiple: p.multiple, accept: p.accept, onChange: e => {
|
|
1741
1894
|
try {
|
|
1742
1895
|
if (!e.target.files) {
|
|
@@ -1759,65 +1912,68 @@ const FileUploader = (p) => {
|
|
|
1759
1912
|
zIndex: !!(files === null || files === void 0 ? void 0 : files.length) ? 1 : undefined
|
|
1760
1913
|
}) },
|
|
1761
1914
|
!(files === null || files === void 0 ? void 0 : files.length) && React__default['default'].createElement(Icon, { style: { fontSize: '2rem' }, id: "upload" }),
|
|
1762
|
-
React__default['default'].createElement(Text, { align: "center", noPad: true, spacedOut: true
|
|
1915
|
+
React__default['default'].createElement(Text, { align: "center", noPad: true, spacedOut: true, className: css.css({
|
|
1916
|
+
width: '100%'
|
|
1917
|
+
}) },
|
|
1763
1918
|
filesDisplay,
|
|
1764
1919
|
!!(files === null || files === void 0 ? void 0 : files.length) && (React__default['default'].createElement(Button, { onClick: e => {
|
|
1765
1920
|
e.stopPropagation();
|
|
1766
1921
|
onFilesChange(undefined);
|
|
1767
1922
|
}, className: css.css({ marginLeft: '1rem', color: theme.colors.negative }), rightIcon: React__default['default'].createElement(Icon, { id: "clear" }), variant: "inlineLink" }, "Clear"))),
|
|
1768
1923
|
infoMessage,
|
|
1769
|
-
!!(files === null || files === void 0 ? void 0 : files.invalidFiles.length) && (React__default['default'].createElement(InfoPanel, { variant: "error" },
|
|
1924
|
+
!!(files === null || files === void 0 ? void 0 : files.invalidFiles.length) && (React__default['default'].createElement(InfoPanel, { variant: "error", className: css.css({ width: '100%' }) },
|
|
1770
1925
|
"Invalid files: ",
|
|
1771
1926
|
files.invalidFiles.map(f => f.name).join(', '),
|
|
1772
1927
|
".")),
|
|
1773
|
-
(files === null || files === void 0 ? void 0 : files.overMaxBytes) && (React__default['default'].createElement(InfoPanel, { variant: "error" },
|
|
1928
|
+
(files === null || files === void 0 ? void 0 : files.overMaxBytes) && (React__default['default'].createElement(InfoPanel, { variant: "error", className: css.css({ width: '100%' }) },
|
|
1774
1929
|
"Max file size exceeded (",
|
|
1775
|
-
|
|
1930
|
+
getFileSizeDisplay((_d = p.maxBytes) !== null && _d !== void 0 ? _d : 0),
|
|
1776
1931
|
").")))),
|
|
1777
1932
|
canUpload && !(files === null || files === void 0 ? void 0 : files.hasErrors) && (React__default['default'].createElement(Button, { className: css.css({
|
|
1778
|
-
width: (
|
|
1933
|
+
width: (_e = p.buttonWidth) !== null && _e !== void 0 ? _e : '10rem',
|
|
1779
1934
|
zIndex: 1,
|
|
1780
|
-
}), waiting: uploading, type: "submit", variant: (
|
|
1781
|
-
message === 'success' && (React__default['default'].createElement(UploadInfoPanel, { variant: "positive", message: (
|
|
1935
|
+
}), waiting: uploading, type: "submit", variant: (_f = p.buttonVariant) !== null && _f !== void 0 ? _f : 'primary' }, (_g = p.buttonText) !== null && _g !== void 0 ? _g : 'Upload')),
|
|
1936
|
+
message === 'success' && (React__default['default'].createElement(UploadInfoPanel, { variant: "positive", message: (_h = p.successMessage) !== null && _h !== void 0 ? _h : 'Upload successful.', onClear: () => setMessage(undefined) })),
|
|
1782
1937
|
message === 'failure' && (React__default['default'].createElement(UploadInfoPanel, { variant: "error", message: fullFailureMessage, onClear: () => setMessage(undefined) }))));
|
|
1783
1938
|
};
|
|
1784
1939
|
const UploadInfoPanel = (p) => {
|
|
1785
1940
|
return (React__default['default'].createElement(InfoPanel, { variant: p.variant, className: css.css({ zIndex: 1 }) },
|
|
1786
1941
|
p.message,
|
|
1787
|
-
React__default['default'].createElement(Button, {
|
|
1942
|
+
React__default['default'].createElement(Button, { className: css.css({
|
|
1788
1943
|
color: 'inherit',
|
|
1789
|
-
marginTop: '1rem'
|
|
1944
|
+
marginTop: '1rem',
|
|
1945
|
+
width: '100%'
|
|
1790
1946
|
}), onClick: e => {
|
|
1791
1947
|
e.stopPropagation();
|
|
1792
1948
|
p.onClear();
|
|
1793
1949
|
}, rightIcon: React__default['default'].createElement(Icon, { id: "clear" }), variant: "inlineLink" }, "Clear")));
|
|
1794
1950
|
};
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
const
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1951
|
+
// OMG this is dumb. We're sticking with decimals for ease of use.
|
|
1952
|
+
// https://stackoverflow.com/questions/40949135/gigabyte-or-gibibyte-1000-or-1024
|
|
1953
|
+
const getFileSizeDisplay = (size) => {
|
|
1954
|
+
let value = 0;
|
|
1955
|
+
let suffix = '';
|
|
1956
|
+
if (size >= 1000000000) {
|
|
1957
|
+
value = size / 1000000000;
|
|
1958
|
+
suffix = 'GB';
|
|
1959
|
+
}
|
|
1960
|
+
else if (size >= 1000000) {
|
|
1961
|
+
value = size / 1000000;
|
|
1962
|
+
suffix = 'MB';
|
|
1963
|
+
}
|
|
1964
|
+
else if (size >= 1000) {
|
|
1965
|
+
value = size / 1000;
|
|
1966
|
+
suffix = 'KB';
|
|
1803
1967
|
}
|
|
1804
1968
|
else {
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
};
|
|
1808
|
-
|
|
1809
|
-
const getCurrencyDisplay = (value, isCents, denomination = '$') => {
|
|
1810
|
-
let actualValue = value || 0;
|
|
1811
|
-
if (isCents) {
|
|
1812
|
-
actualValue /= 100;
|
|
1969
|
+
value = size;
|
|
1970
|
+
suffix = 'B';
|
|
1813
1971
|
}
|
|
1814
|
-
return
|
|
1815
|
-
};
|
|
1816
|
-
const noop = () => {
|
|
1817
|
-
// lil' noop would be a great rap name. (thanks linter)
|
|
1972
|
+
return value.toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 }) + ` ${suffix}`;
|
|
1818
1973
|
};
|
|
1819
1974
|
|
|
1820
1975
|
const Header = (props) => {
|
|
1976
|
+
var _a;
|
|
1821
1977
|
const theme = useThemeSafely();
|
|
1822
1978
|
const bodyStyles = css.css `
|
|
1823
1979
|
padding-top: calc(${theme.layout.headerHeight} + ${theme.layout.headerBodyOffset});
|
|
@@ -1829,7 +1985,9 @@ const Header = (props) => {
|
|
|
1829
1985
|
document.body.classList.remove(bodyStyles);
|
|
1830
1986
|
};
|
|
1831
1987
|
});
|
|
1832
|
-
const toggleMenu = props.toggleMenu
|
|
1988
|
+
const toggleMenu = (_a = props.toggleMenu) !== null && _a !== void 0 ? _a : (() => {
|
|
1989
|
+
/* noop */
|
|
1990
|
+
});
|
|
1833
1991
|
const headerStyles = css.css `
|
|
1834
1992
|
display: flex;
|
|
1835
1993
|
gap: ${theme.controls.gap};
|
|
@@ -1959,7 +2117,7 @@ const Popover = (p) => {
|
|
|
1959
2117
|
};
|
|
1960
2118
|
|
|
1961
2119
|
const InfoTip = (props) => {
|
|
1962
|
-
var _a, _b;
|
|
2120
|
+
var _a, _b, _c;
|
|
1963
2121
|
const [showTip, setShowTip] = React__namespace.useState(false);
|
|
1964
2122
|
const theme = useThemeSafely();
|
|
1965
2123
|
const bgColor = (_a = props.bgColor) !== null && _a !== void 0 ? _a : theme.colors.nav;
|
|
@@ -2021,13 +2179,13 @@ const InfoTip = (props) => {
|
|
|
2021
2179
|
if (props.variant === 'modal') {
|
|
2022
2180
|
return (React__namespace.createElement(React__namespace.Fragment, null,
|
|
2023
2181
|
button,
|
|
2024
|
-
React__namespace.createElement(Modal, { id: props.modalId,
|
|
2182
|
+
React__namespace.createElement(Modal, { id: props.modalId, __debug: props.__modalDebug, show: showTip, heading: props.modalHeader, onClick: closeTip, className: css.css({
|
|
2025
2183
|
whiteSpace: 'normal'
|
|
2026
2184
|
}), closeButton: true },
|
|
2027
2185
|
React__namespace.createElement("div", { className: css.css({ padding: '1rem' }) }, props.content))));
|
|
2028
2186
|
}
|
|
2029
2187
|
else {
|
|
2030
|
-
return (React__namespace.createElement(Popover, { reposition: false, isOpen: showTip, onClickOutside: closeTip, arrorColor: bgColor, border: '', backgroundColor: bgColor, parent: button, content: (React__namespace.createElement("div", { className: css.css({
|
|
2188
|
+
return (React__namespace.createElement(Popover, { positions: props.positions, reposition: (_c = props.reposition) !== null && _c !== void 0 ? _c : false, isOpen: showTip, onClickOutside: closeTip, arrorColor: bgColor, border: '', backgroundColor: bgColor, parent: button, content: (React__namespace.createElement("div", { className: css.css({
|
|
2031
2189
|
padding: '0.5rem',
|
|
2032
2190
|
fontSize: '0.75rem',
|
|
2033
2191
|
maxWidth: '22rem'
|
|
@@ -2107,11 +2265,13 @@ const BaseInput = React__namespace.forwardRef((props, ref) => {
|
|
|
2107
2265
|
right: calc(${theme.controls.padding} * 2);
|
|
2108
2266
|
`}
|
|
2109
2267
|
`;
|
|
2110
|
-
return (React__namespace.createElement("div",
|
|
2268
|
+
return (React__namespace.createElement("div", { className: css.css({
|
|
2269
|
+
width: '100%'
|
|
2270
|
+
}) },
|
|
2111
2271
|
React__namespace.createElement("div", { className: css.cx('input', inputWrapperStyles, wrapperClassName) },
|
|
2112
2272
|
inputElement,
|
|
2113
2273
|
props.rightControl && (React__namespace.createElement("div", { className: rightControlStyles }, props.rightControl))),
|
|
2114
|
-
React__namespace.createElement(InputErrorDisplay, { error: props.error })));
|
|
2274
|
+
React__namespace.createElement(InputErrorDisplay, { error: props.readOnly ? undefined : props.error })));
|
|
2115
2275
|
});
|
|
2116
2276
|
|
|
2117
2277
|
const tryClampRange = (value, min, max) => {
|
|
@@ -2145,19 +2305,19 @@ const getStepDecimalPlaces = (step) => {
|
|
|
2145
2305
|
}
|
|
2146
2306
|
const strStep = typeof step === 'number' ? step.toString() : step;
|
|
2147
2307
|
return (_b = (_a = strStep.split('.')[1]) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
|
|
2148
|
-
};
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2308
|
+
};
|
|
2309
|
+
const tryClampDecimals = (value, step = 0) => {
|
|
2310
|
+
if (value === undefined) {
|
|
2311
|
+
return value;
|
|
2312
|
+
}
|
|
2313
|
+
if (isNaN(value)) {
|
|
2314
|
+
return undefined;
|
|
2315
|
+
}
|
|
2316
|
+
const decimals = getStepDecimalPlaces(step);
|
|
2317
|
+
if (decimals === 0) {
|
|
2318
|
+
return Math.floor(value);
|
|
2319
|
+
}
|
|
2320
|
+
return parseFloat(value.toFixed(decimals));
|
|
2161
2321
|
};
|
|
2162
2322
|
|
|
2163
2323
|
/** Common state handling for displaying validation messages with inputs. */
|
|
@@ -2170,6 +2330,9 @@ const useInputValidationMessage = (ref, props) => {
|
|
|
2170
2330
|
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.setCustomValidity(customError);
|
|
2171
2331
|
setValidationError(customError || getValidationMessage(ref.current, props.patternErrorMessage));
|
|
2172
2332
|
};
|
|
2333
|
+
React.useEffect(() => {
|
|
2334
|
+
updateErrorMessage();
|
|
2335
|
+
}, [props.customError]);
|
|
2173
2336
|
React__default['default'].useEffect(() => {
|
|
2174
2337
|
updateErrorMessage();
|
|
2175
2338
|
}, []);
|
|
@@ -2205,7 +2368,23 @@ const getValidationMessage = (element, patternErrorMessage) => {
|
|
|
2205
2368
|
return `Must be greater than or equal to ${element.min}.`;
|
|
2206
2369
|
}
|
|
2207
2370
|
if (validity.stepMismatch) {
|
|
2208
|
-
|
|
2371
|
+
const decimalPlaces = getStepDecimalPlaces(element.step);
|
|
2372
|
+
if (decimalPlaces > 0) {
|
|
2373
|
+
const place = decimalPlaces === 1 ? 'place' : 'places';
|
|
2374
|
+
return `Limited to ${getStepDecimalPlaces(element.step)} decimal ${place}.`;
|
|
2375
|
+
}
|
|
2376
|
+
else {
|
|
2377
|
+
/*
|
|
2378
|
+
step is buggy!
|
|
2379
|
+
|
|
2380
|
+
at least in Chrome, setting step=5 will cause the browser to mark the field as invalid if the number is not divisible
|
|
2381
|
+
by 5. 55 is ok. 50 is ok. 59 is not ok.
|
|
2382
|
+
|
|
2383
|
+
to make things worse, if you enter an invalid number like 59 with step=5 and then clear the input, Chrome will tell
|
|
2384
|
+
you the number 5 is now invalid and should be 4 or 9.
|
|
2385
|
+
*/
|
|
2386
|
+
return `Must be an integer.`;
|
|
2387
|
+
}
|
|
2209
2388
|
}
|
|
2210
2389
|
}
|
|
2211
2390
|
if (validity.tooShort) {
|
|
@@ -2446,19 +2625,6 @@ const NumberInput = React__namespace.forwardRef((props, ref) => {
|
|
|
2446
2625
|
(_b = props.onBlur) === null || _b === void 0 ? void 0 : _b.call(props, e);
|
|
2447
2626
|
} })));
|
|
2448
2627
|
});
|
|
2449
|
-
const tryClampDecimals = (value, step = 0) => {
|
|
2450
|
-
if (value === undefined) {
|
|
2451
|
-
return value;
|
|
2452
|
-
}
|
|
2453
|
-
if (isNaN(value)) {
|
|
2454
|
-
return undefined;
|
|
2455
|
-
}
|
|
2456
|
-
const decimals = getStepDecimalPlaces(step);
|
|
2457
|
-
if (decimals === 0) {
|
|
2458
|
-
return Math.floor(value);
|
|
2459
|
-
}
|
|
2460
|
-
return parseFloat(value.toFixed(decimals));
|
|
2461
|
-
};
|
|
2462
2628
|
const parseNumber = (rawValue) => {
|
|
2463
2629
|
let value;
|
|
2464
2630
|
if (rawValue) {
|
|
@@ -2475,7 +2641,7 @@ const TextInput = React__namespace.forwardRef((props, ref) => {
|
|
|
2475
2641
|
const [localValue, setLocalValue] = React__namespace.useState(props.value);
|
|
2476
2642
|
const inputRef = (ref !== null && ref !== void 0 ? ref : React__namespace.useRef(null));
|
|
2477
2643
|
const [validationError, updateErrorMessage] = useInputValidationMessage(inputRef, props);
|
|
2478
|
-
const nativeProps = __rest(props, ["onValueChange", "customError", "patternErrorMessage"]);
|
|
2644
|
+
const nativeProps = __rest(props, ["emptyString", "onValueChange", "customError", "patternErrorMessage"]);
|
|
2479
2645
|
useIgnoreMount(() => {
|
|
2480
2646
|
var _a;
|
|
2481
2647
|
if ((_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.checkValidity()) {
|
|
@@ -2494,14 +2660,19 @@ const TextInput = React__namespace.forwardRef((props, ref) => {
|
|
|
2494
2660
|
}, [props.value]);
|
|
2495
2661
|
return (React__namespace.createElement(BaseInput, Object.assign({}, nativeProps, { error: validationError, type: (_a = props.type) !== null && _a !== void 0 ? _a : 'text', ref: inputRef, value: localValue !== null && localValue !== void 0 ? localValue : '', onChange: e => {
|
|
2496
2662
|
var _a;
|
|
2497
|
-
setLocalValue(e.target.value || undefined);
|
|
2663
|
+
setLocalValue(props.emptyString ? e.target.value : e.target.value || undefined);
|
|
2498
2664
|
(_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, e);
|
|
2499
2665
|
}, onBlur: e => {
|
|
2500
|
-
var _a;
|
|
2666
|
+
var _a, _b;
|
|
2501
2667
|
if (!e.target.checkValidity()) {
|
|
2502
2668
|
setLocalValue(undefined);
|
|
2503
2669
|
}
|
|
2504
|
-
(_a = props.
|
|
2670
|
+
else if ((_a = props.trim) !== null && _a !== void 0 ? _a : true) {
|
|
2671
|
+
setLocalValue(currentValue => {
|
|
2672
|
+
return currentValue === null || currentValue === void 0 ? void 0 : currentValue.trim();
|
|
2673
|
+
});
|
|
2674
|
+
}
|
|
2675
|
+
(_b = props.onBlur) === null || _b === void 0 ? void 0 : _b.call(props, e);
|
|
2505
2676
|
} })));
|
|
2506
2677
|
});
|
|
2507
2678
|
|
|
@@ -2597,6 +2768,9 @@ const Label = (props) => {
|
|
|
2597
2768
|
From https://fireship.io/snippets/use-media-query-hook/.
|
|
2598
2769
|
Tried using https://www.npmjs.com/package/react-media, but it cause Webpack build issues.
|
|
2599
2770
|
*/
|
|
2771
|
+
/** React wrapper around window resizing and window.matchMedia.
|
|
2772
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia
|
|
2773
|
+
*/
|
|
2600
2774
|
const useMediaQuery = (query) => {
|
|
2601
2775
|
const [matches, setMatches] = React.useState(false);
|
|
2602
2776
|
React.useEffect(() => {
|
|
@@ -2612,11 +2786,13 @@ const useMediaQuery = (query) => {
|
|
|
2612
2786
|
};
|
|
2613
2787
|
|
|
2614
2788
|
const Nav = (props) => {
|
|
2789
|
+
var _a, _b;
|
|
2615
2790
|
const nav = React__namespace.useRef(null);
|
|
2616
2791
|
const theme = useThemeSafely();
|
|
2617
2792
|
const totalNavOffset = `calc(${theme.layout.navWidth} + 20px)`;
|
|
2618
2793
|
const backdrop = React__namespace.useContext(BackdropContext);
|
|
2619
2794
|
const isLargeScreen = useMediaQuery(`(min-width:${theme.breakpoints.desktop})`);
|
|
2795
|
+
const log = useLogger(`Nav ${(_a = props.id) !== null && _a !== void 0 ? _a : '?'}`, (_b = props.__debug) !== null && _b !== void 0 ? _b : false);
|
|
2620
2796
|
const slideRight = css.keyframes `
|
|
2621
2797
|
0% {
|
|
2622
2798
|
transform: translateX(0);
|
|
@@ -2677,9 +2853,11 @@ const Nav = (props) => {
|
|
|
2677
2853
|
props.toggle(false);
|
|
2678
2854
|
}
|
|
2679
2855
|
}, [backdrop.showing]);
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2856
|
+
useBooleanChanged((current, previous) => {
|
|
2857
|
+
var _a;
|
|
2858
|
+
log('show changed', `${previous !== null && previous !== void 0 ? previous : 'undefined'} > ${current}`);
|
|
2859
|
+
backdrop.setShow(current, (_a = props.id) !== null && _a !== void 0 ? _a : 'Nav');
|
|
2860
|
+
}, props.show);
|
|
2683
2861
|
React__namespace.useLayoutEffect(() => {
|
|
2684
2862
|
if (nav && nav.current) {
|
|
2685
2863
|
if (props.show) {
|
|
@@ -2710,6 +2888,7 @@ const Nav = (props) => {
|
|
|
2710
2888
|
return (React__namespace.createElement("nav", { ref: nav, className: css.cx('nav', navStyles, props.className) }, props.children));
|
|
2711
2889
|
};
|
|
2712
2890
|
|
|
2891
|
+
//TB: FUTURE make just a basic styled link so you don't have to go with React Router if you don't want to.
|
|
2713
2892
|
const OmniLink = (props) => {
|
|
2714
2893
|
var _a, _b, _c;
|
|
2715
2894
|
const theme = useThemeSafely();
|
|
@@ -2886,7 +3065,7 @@ const OmniLink = (props) => {
|
|
|
2886
3065
|
const Picker = (props) => {
|
|
2887
3066
|
const selectProps = __rest(props
|
|
2888
3067
|
// if we put numbers in, we expect them out
|
|
2889
|
-
, ["value", "options", "
|
|
3068
|
+
, ["value", "options", "onValueChange", "readOnly", "round", "controlAlign"]);
|
|
2890
3069
|
// if we put numbers in, we expect them out
|
|
2891
3070
|
let isNumber = false;
|
|
2892
3071
|
if (props.options && props.options.length) {
|
|
@@ -2956,6 +3135,7 @@ const Picker = (props) => {
|
|
|
2956
3135
|
(_a = selectProps.onMouseDown) === null || _a === void 0 ? void 0 : _a.call(selectProps, e);
|
|
2957
3136
|
}
|
|
2958
3137
|
}, onChange: e => {
|
|
3138
|
+
var _a;
|
|
2959
3139
|
let val = e.target.value;
|
|
2960
3140
|
if (isNumber) {
|
|
2961
3141
|
val = parseInt(val, 10);
|
|
@@ -2963,7 +3143,8 @@ const Picker = (props) => {
|
|
|
2963
3143
|
val = '';
|
|
2964
3144
|
}
|
|
2965
3145
|
}
|
|
2966
|
-
props.
|
|
3146
|
+
props.onValueChange(val);
|
|
3147
|
+
(_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, e);
|
|
2967
3148
|
} }), (props.options || []).map(o => {
|
|
2968
3149
|
var _a;
|
|
2969
3150
|
let val;
|
|
@@ -3050,8 +3231,8 @@ const BoundMemoryPager = (p) => {
|
|
|
3050
3231
|
var _a, _b, _c;
|
|
3051
3232
|
const { pager, showPageText } = p, rest = __rest(p, ["pager", "showPageText"]);
|
|
3052
3233
|
return (React__namespace.createElement(Pager, Object.assign({}, rest, { pageIndex: p.showPageText ? pager.page : undefined, totalPages: p.showPageText ? pager.totalPages : undefined, canGoNext: pager.hasNext, canGoPrevious: pager.hasPrevious, minItem: pager.minItemIndex + 1, maxItem: pager.maxItemIndex + 1, totalItems: pager.totalItems, leftControls: pager.limitOptions.length > 1 && p.onLimit ? (React__namespace.createElement(Label, { text: (_a = p.limitText) !== null && _a !== void 0 ? _a : 'Limit', orientation: "horizontal" },
|
|
3053
|
-
React__namespace.createElement(Picker, { value: pager.limit, options: pager.limitOptions,
|
|
3054
|
-
React__namespace.createElement(Picker, { value: (_c = pager.sort) !== null && _c !== void 0 ? _c : '', options: pager.sortOptions,
|
|
3234
|
+
React__namespace.createElement(Picker, { value: pager.limit, options: pager.limitOptions, onValueChange: v => { var _a; return (_a = p.onLimit) === null || _a === void 0 ? void 0 : _a.call(p, v); } }))) : undefined, rightControls: pager.sortOptions.length > 1 && p.onSort ? (React__namespace.createElement(Label, { text: (_b = p.sortText) !== null && _b !== void 0 ? _b : 'Sort', orientation: "horizontalReverse" },
|
|
3235
|
+
React__namespace.createElement(Picker, { value: (_c = pager.sort) !== null && _c !== void 0 ? _c : '', options: pager.sortOptions, onValueChange: v => { var _a; return (_a = p.onSort) === null || _a === void 0 ? void 0 : _a.call(p, v); } }))) : undefined, page: d => {
|
|
3055
3236
|
p.onPage(d);
|
|
3056
3237
|
} })));
|
|
3057
3238
|
};
|
|
@@ -3062,8 +3243,8 @@ const BoundStaticPager = (p) => {
|
|
|
3062
3243
|
const showLimit = !!(result.limit && p.limitOptions && p.limitOptions.length > 1 && p.onLimit);
|
|
3063
3244
|
const showSort = !!(p.sort !== undefined && p.sortOptions && p.sortOptions.length > 1 && p.onSort);
|
|
3064
3245
|
return (React__namespace.createElement(Pager, Object.assign({}, rest, { pageIndex: p.showPageText ? result.page : undefined, totalPages: p.showPageText ? result.totalPages : undefined, canGoNext: result.hasNext, canGoPrevious: result.hasPrevious, minItem: result.minPageItemIndex + 1, maxItem: result.maxPageItemIndex + 1, totalItems: result.total, leftControls: showLimit ? (React__namespace.createElement(Label, { text: (_a = p.limitText) !== null && _a !== void 0 ? _a : 'Limit', orientation: "horizontal" },
|
|
3065
|
-
React__namespace.createElement(Picker, { value: (_b = result.limit) !== null && _b !== void 0 ? _b : 1, options: (_c = p.limitOptions) !== null && _c !== void 0 ? _c : [1],
|
|
3066
|
-
React__namespace.createElement(Picker, { value: (_e = p.sort) !== null && _e !== void 0 ? _e : '', options: (_f = p.sortOptions) !== null && _f !== void 0 ? _f : [],
|
|
3246
|
+
React__namespace.createElement(Picker, { value: (_b = result.limit) !== null && _b !== void 0 ? _b : 1, options: (_c = p.limitOptions) !== null && _c !== void 0 ? _c : [1], onValueChange: v => { var _a; return (_a = p.onLimit) === null || _a === void 0 ? void 0 : _a.call(p, v); } }))) : undefined, rightControls: showSort ? (React__namespace.createElement(Label, { text: (_d = p.sortText) !== null && _d !== void 0 ? _d : 'Sort', orientation: "horizontalReverse" },
|
|
3247
|
+
React__namespace.createElement(Picker, { value: (_e = p.sort) !== null && _e !== void 0 ? _e : '', options: (_f = p.sortOptions) !== null && _f !== void 0 ? _f : [], onValueChange: v => {
|
|
3067
3248
|
var _a;
|
|
3068
3249
|
(_a = p.onSort) === null || _a === void 0 ? void 0 : _a.call(p, v);
|
|
3069
3250
|
} }))) : undefined, page: d => {
|
|
@@ -3071,6 +3252,7 @@ const BoundStaticPager = (p) => {
|
|
|
3071
3252
|
} })));
|
|
3072
3253
|
};
|
|
3073
3254
|
|
|
3255
|
+
/** A page of data with helpers props. */
|
|
3074
3256
|
class PagedResult {
|
|
3075
3257
|
constructor(items = [], total = 0, page = 0, limit = 0) {
|
|
3076
3258
|
this.items = items;
|
|
@@ -3081,10 +3263,6 @@ class PagedResult {
|
|
|
3081
3263
|
static fromDto(dto) {
|
|
3082
3264
|
return new PagedResult(dto.items, dto.total, dto.page, dto.limit);
|
|
3083
3265
|
}
|
|
3084
|
-
// allItems: T[]
|
|
3085
|
-
// get pageItems(): T[] {
|
|
3086
|
-
// return this.allItems.slice(this.minPageItemIndex, this.maxPageItemIndex + 1)
|
|
3087
|
-
// }
|
|
3088
3266
|
/** Helper for items.length */
|
|
3089
3267
|
get length() {
|
|
3090
3268
|
return this.items ? this.items.length : 0;
|
|
@@ -3208,7 +3386,7 @@ class PagedResult {
|
|
|
3208
3386
|
}
|
|
3209
3387
|
}
|
|
3210
3388
|
|
|
3211
|
-
/**
|
|
3389
|
+
/** In-memory pager. */
|
|
3212
3390
|
class ItemPager {
|
|
3213
3391
|
constructor(allItems, options) {
|
|
3214
3392
|
var _a, _b, _c, _d;
|
|
@@ -3458,6 +3636,7 @@ const cleanPct = (value) => {
|
|
|
3458
3636
|
return 0;
|
|
3459
3637
|
};
|
|
3460
3638
|
|
|
3639
|
+
/** Provides stateful notifications around async calls. */
|
|
3461
3640
|
const useWaiting = (func) => {
|
|
3462
3641
|
// Guard against the owner of this hook being unmounted at the time of .finally.
|
|
3463
3642
|
const isCancelled = React.useRef(false);
|
|
@@ -3528,6 +3707,28 @@ const GlobalStyles = () => {
|
|
|
3528
3707
|
return null;
|
|
3529
3708
|
};
|
|
3530
3709
|
|
|
3710
|
+
const getCurrencyDisplay = (value, isCents, denomination = '$') => {
|
|
3711
|
+
let actualValue = value || 0;
|
|
3712
|
+
if (isCents) {
|
|
3713
|
+
actualValue /= 100;
|
|
3714
|
+
}
|
|
3715
|
+
return `${denomination}${actualValue.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
|
|
3716
|
+
};
|
|
3717
|
+
/** Converts an enum to an array of entities with id and name. The enum can be an integer or string enum.*/
|
|
3718
|
+
const enumToEntities = (enumObj) => {
|
|
3719
|
+
const entities = [];
|
|
3720
|
+
for (const key in enumObj) {
|
|
3721
|
+
if (isNaN(parseInt(key, 10))) {
|
|
3722
|
+
entities.push({
|
|
3723
|
+
id: enumObj[key],
|
|
3724
|
+
name: key
|
|
3725
|
+
});
|
|
3726
|
+
}
|
|
3727
|
+
}
|
|
3728
|
+
return entities;
|
|
3729
|
+
};
|
|
3730
|
+
//TB: FUTURE Expose in UI.
|
|
3731
|
+
|
|
3531
3732
|
const Slider = (p) => {
|
|
3532
3733
|
const theme = useThemeSafely();
|
|
3533
3734
|
const currentValue = React.useRef(p.value);
|
|
@@ -3810,12 +4011,9 @@ const defaultRows = 10;
|
|
|
3810
4011
|
const TextArea = React__namespace.forwardRef((props, ref) => {
|
|
3811
4012
|
var _a, _b;
|
|
3812
4013
|
const [localValue, setLocalValue] = React__namespace.useState(props.value);
|
|
3813
|
-
const [validationError, setValidationError] = React__namespace.useState('');
|
|
3814
|
-
const updateErrorMessage = React__namespace.useCallback(() => {
|
|
3815
|
-
setValidationError(getValidationMessage(inputRef.current));
|
|
3816
|
-
}, []);
|
|
3817
4014
|
const inputRef = (ref !== null && ref !== void 0 ? ref : React__namespace.useRef(null));
|
|
3818
|
-
const
|
|
4015
|
+
const [validationError, updateErrorMessage] = useInputValidationMessage(inputRef, props);
|
|
4016
|
+
const nativeProps = __rest(props, ["onValueChange", "customError"]);
|
|
3819
4017
|
const theme = useThemeSafely();
|
|
3820
4018
|
React__namespace.useEffect(() => {
|
|
3821
4019
|
updateErrorMessage();
|
|
@@ -3881,6 +4079,14 @@ const TextArea = React__namespace.forwardRef((props, ref) => {
|
|
|
3881
4079
|
var _a;
|
|
3882
4080
|
setLocalValue(e.target.value || undefined);
|
|
3883
4081
|
(_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, e);
|
|
4082
|
+
}, onBlur: e => {
|
|
4083
|
+
var _a;
|
|
4084
|
+
if (!props.noTrim) {
|
|
4085
|
+
setLocalValue(currentValue => {
|
|
4086
|
+
return currentValue === null || currentValue === void 0 ? void 0 : currentValue.trim();
|
|
4087
|
+
});
|
|
4088
|
+
}
|
|
4089
|
+
(_a = props.onBlur) === null || _a === void 0 ? void 0 : _a.call(props, e);
|
|
3884
4090
|
} })),
|
|
3885
4091
|
React__namespace.createElement(InputErrorDisplay, { error: validationError })));
|
|
3886
4092
|
});
|
|
@@ -3969,17 +4175,14 @@ const WaitingIndicator = (p) => {
|
|
|
3969
4175
|
const [show, setShow] = React.useState(p.show);
|
|
3970
4176
|
const hideTimer = React.useRef(0);
|
|
3971
4177
|
const lastShowStatus = React.useRef(false);
|
|
3972
|
-
const log = useLogger(`WaitingIndicator ${(_a = p.id) !== null && _a !== void 0 ? _a : '?'}`, (_b = p.
|
|
3973
|
-
if (p.
|
|
4178
|
+
const log = useLogger(`WaitingIndicator ${(_a = p.id) !== null && _a !== void 0 ? _a : '?'}`, (_b = p.__debug) !== null && _b !== void 0 ? _b : false);
|
|
4179
|
+
if (p.__debug) {
|
|
3974
4180
|
React.useEffect(() => {
|
|
3975
4181
|
log('mounted');
|
|
3976
4182
|
return () => {
|
|
3977
4183
|
log('unmounted');
|
|
3978
4184
|
};
|
|
3979
4185
|
}, []);
|
|
3980
|
-
React.useEffect(() => {
|
|
3981
|
-
log('re-rendered');
|
|
3982
|
-
});
|
|
3983
4186
|
}
|
|
3984
4187
|
React.useEffect(() => {
|
|
3985
4188
|
log('show changed', p.show);
|
|
@@ -4020,7 +4223,7 @@ const WaitingIndicator = (p) => {
|
|
|
4020
4223
|
}
|
|
4021
4224
|
}
|
|
4022
4225
|
}, [p.show]);
|
|
4023
|
-
return (React__default['default'].createElement(Modal, { id: p.id,
|
|
4226
|
+
return (React__default['default'].createElement(Modal, { id: p.id, __debug: p.__debug, className: "waitingIndicator", show: show, noBackground: true },
|
|
4024
4227
|
React__default['default'].createElement("div", { className: css.css({
|
|
4025
4228
|
color: 'white',
|
|
4026
4229
|
fontSize: '3rem'
|
|
@@ -4028,6 +4231,7 @@ const WaitingIndicator = (p) => {
|
|
|
4028
4231
|
React__default['default'].createElement(Icon, { id: "waiting", spin: true }))));
|
|
4029
4232
|
};
|
|
4030
4233
|
|
|
4234
|
+
exports.Accordian = Accordian;
|
|
4031
4235
|
exports.Autocomplete = Autocomplete;
|
|
4032
4236
|
exports.Backdrop = Backdrop$1;
|
|
4033
4237
|
exports.Backdrop2 = Backdrop;
|
|
@@ -4088,7 +4292,14 @@ exports.Tr = Tr;
|
|
|
4088
4292
|
exports.WaitingIndicator = WaitingIndicator;
|
|
4089
4293
|
exports.calcDynamicThemeProps = calcDynamicThemeProps;
|
|
4090
4294
|
exports.defaultTheme = defaultTheme;
|
|
4295
|
+
exports.enumToEntities = enumToEntities;
|
|
4091
4296
|
exports.getCurrencyDisplay = getCurrencyDisplay;
|
|
4297
|
+
exports.getFileSizeDisplay = getFileSizeDisplay;
|
|
4298
|
+
exports.useAccordianState = useAccordianState;
|
|
4299
|
+
exports.useBooleanChanged = useBooleanChanged;
|
|
4300
|
+
exports.useIgnoreMount = useIgnoreMount;
|
|
4092
4301
|
exports.useMediaQuery = useMediaQuery;
|
|
4302
|
+
exports.useScrollbarSize = useScrollbarSize;
|
|
4093
4303
|
exports.useThemeSafely = useThemeSafely;
|
|
4304
|
+
exports.useWaiting = useWaiting;
|
|
4094
4305
|
//# sourceMappingURL=index.js.map
|