@mackin.com/styleguide 8.0.0-beta.9 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +114 -36
- package/index.js +687 -481
- 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) => {
|
|
160
|
-
var _a;
|
|
161
|
-
const showTimeMs = (_a = props.showTimeMs) !== null && _a !== void 0 ? _a : 250;
|
|
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) => {
|
|
232
|
+
const Button = React__namespace.forwardRef((props, ref) => {
|
|
337
233
|
var _a;
|
|
338
|
-
const
|
|
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) {
|
|
@@ -1461,7 +1604,7 @@ const ConfirmModal = (props) => {
|
|
|
1461
1604
|
}
|
|
1462
1605
|
`}
|
|
1463
1606
|
`;
|
|
1464
|
-
return (React__namespace.createElement(Modal, { id: props.id,
|
|
1607
|
+
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
1608
|
React__namespace.createElement("div", { className: css.css({ padding: '1rem' }) },
|
|
1466
1609
|
React__namespace.createElement(Text, { align: "center" }, props.text),
|
|
1467
1610
|
React__namespace.createElement("div", { className: css.css({ textAlign: 'center' }) },
|
|
@@ -1491,12 +1634,12 @@ const CopyButton = (props) => {
|
|
|
1491
1634
|
React__namespace.createElement(Icon, { id: copied ? 'paste' : 'copy' })));
|
|
1492
1635
|
};
|
|
1493
1636
|
|
|
1494
|
-
const Divider = () => {
|
|
1637
|
+
const Divider = (p) => {
|
|
1495
1638
|
const theme = useThemeSafely();
|
|
1496
|
-
return (React__namespace.createElement("hr", { className: css.cx("divider", css.css({
|
|
1639
|
+
return (React__namespace.createElement("hr", Object.assign({}, p, { className: css.cx("divider", css.css({
|
|
1497
1640
|
margin: theme.controls.dividerMargin,
|
|
1498
1641
|
border: theme.controls.dividerBorder
|
|
1499
|
-
})) }));
|
|
1642
|
+
}), p.className) })));
|
|
1500
1643
|
};
|
|
1501
1644
|
|
|
1502
1645
|
const ErrorModal = (props) => {
|
|
@@ -1511,7 +1654,7 @@ const ErrorModal = (props) => {
|
|
|
1511
1654
|
color: ${theme.colors.omgFont};
|
|
1512
1655
|
}
|
|
1513
1656
|
`;
|
|
1514
|
-
return (React__namespace.createElement(Modal, { id: props.id,
|
|
1657
|
+
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
1658
|
React__namespace.createElement("div", { className: css.css({ padding: '1rem' }) },
|
|
1516
1659
|
React__namespace.createElement(Text, { align: "center" }, message))));
|
|
1517
1660
|
};
|
|
@@ -1639,7 +1782,7 @@ const hoverClass = css.css({
|
|
|
1639
1782
|
backgroundColor: 'rgba(0,0,0,0.25) !important'
|
|
1640
1783
|
});
|
|
1641
1784
|
const FileUploader = (p) => {
|
|
1642
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
1785
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1643
1786
|
const [message, setMessage] = React.useState(undefined);
|
|
1644
1787
|
const [canUpload, setCanUpload] = React.useState(false);
|
|
1645
1788
|
const [uploading, setUploading] = React.useState(false);
|
|
@@ -1655,7 +1798,7 @@ const FileUploader = (p) => {
|
|
|
1655
1798
|
filesDisplay = (_b = p.instructionMessage) !== null && _b !== void 0 ? _b : `Click or drag and drop files.`;
|
|
1656
1799
|
}
|
|
1657
1800
|
else {
|
|
1658
|
-
filesDisplay = `${files.length.toLocaleString()} file${files.length > 1 ? 's' : ''} selected (${
|
|
1801
|
+
filesDisplay = `${files.length.toLocaleString()} file${files.length > 1 ? 's' : ''} selected (${getFileSizeDisplay(totalFileSize)}): ${files.files.map(f => f.name).join(', ')}`;
|
|
1659
1802
|
}
|
|
1660
1803
|
}
|
|
1661
1804
|
const setAllFiles = (inputFiles) => {
|
|
@@ -1677,8 +1820,9 @@ const FileUploader = (p) => {
|
|
|
1677
1820
|
maxBytes: p.maxBytes
|
|
1678
1821
|
});
|
|
1679
1822
|
};
|
|
1823
|
+
const showInfoOnPick = (_c = p.showInfoOnPick) !== null && _c !== void 0 ? _c : true;
|
|
1680
1824
|
let infoMessage;
|
|
1681
|
-
if (p.infoMessage) {
|
|
1825
|
+
if (p.infoMessage && (!files || showInfoOnPick)) {
|
|
1682
1826
|
if (typeof p.infoMessage === 'string') {
|
|
1683
1827
|
infoMessage = React__default['default'].createElement(Text, { noPad: true }, p.infoMessage);
|
|
1684
1828
|
}
|
|
@@ -1695,6 +1839,8 @@ const FileUploader = (p) => {
|
|
|
1695
1839
|
padding: '1rem',
|
|
1696
1840
|
overflow: 'hidden',
|
|
1697
1841
|
backgroundColor: theme.colors.lightBg,
|
|
1842
|
+
}, p.disabled && {
|
|
1843
|
+
opacity: theme.controls.disabledOpacity
|
|
1698
1844
|
}), onDragOver: e => {
|
|
1699
1845
|
var _a, _b;
|
|
1700
1846
|
e.preventDefault();
|
|
@@ -1728,7 +1874,7 @@ const FileUploader = (p) => {
|
|
|
1728
1874
|
setCanUpload(false);
|
|
1729
1875
|
});
|
|
1730
1876
|
} },
|
|
1731
|
-
React__default['default'].createElement("input", { ref: input, className: css.css({
|
|
1877
|
+
React__default['default'].createElement("input", { disabled: p.disabled, ref: input, className: css.css({
|
|
1732
1878
|
position: 'absolute',
|
|
1733
1879
|
top: -50,
|
|
1734
1880
|
left: 0,
|
|
@@ -1737,6 +1883,8 @@ const FileUploader = (p) => {
|
|
|
1737
1883
|
width: '100%',
|
|
1738
1884
|
cursor: 'pointer',
|
|
1739
1885
|
opacity: 0
|
|
1886
|
+
}, p.disabled && {
|
|
1887
|
+
cursor: 'not-allowed'
|
|
1740
1888
|
}), type: "file", multiple: p.multiple, accept: p.accept, onChange: e => {
|
|
1741
1889
|
try {
|
|
1742
1890
|
if (!e.target.files) {
|
|
@@ -1759,65 +1907,68 @@ const FileUploader = (p) => {
|
|
|
1759
1907
|
zIndex: !!(files === null || files === void 0 ? void 0 : files.length) ? 1 : undefined
|
|
1760
1908
|
}) },
|
|
1761
1909
|
!(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
|
|
1910
|
+
React__default['default'].createElement(Text, { align: "center", noPad: true, spacedOut: true, className: css.css({
|
|
1911
|
+
width: '100%'
|
|
1912
|
+
}) },
|
|
1763
1913
|
filesDisplay,
|
|
1764
1914
|
!!(files === null || files === void 0 ? void 0 : files.length) && (React__default['default'].createElement(Button, { onClick: e => {
|
|
1765
1915
|
e.stopPropagation();
|
|
1766
1916
|
onFilesChange(undefined);
|
|
1767
1917
|
}, className: css.css({ marginLeft: '1rem', color: theme.colors.negative }), rightIcon: React__default['default'].createElement(Icon, { id: "clear" }), variant: "inlineLink" }, "Clear"))),
|
|
1768
1918
|
infoMessage,
|
|
1769
|
-
!!(files === null || files === void 0 ? void 0 : files.invalidFiles.length) && (React__default['default'].createElement(InfoPanel, { variant: "error" },
|
|
1919
|
+
!!(files === null || files === void 0 ? void 0 : files.invalidFiles.length) && (React__default['default'].createElement(InfoPanel, { variant: "error", className: css.css({ width: '100%' }) },
|
|
1770
1920
|
"Invalid files: ",
|
|
1771
1921
|
files.invalidFiles.map(f => f.name).join(', '),
|
|
1772
1922
|
".")),
|
|
1773
|
-
(files === null || files === void 0 ? void 0 : files.overMaxBytes) && (React__default['default'].createElement(InfoPanel, { variant: "error" },
|
|
1923
|
+
(files === null || files === void 0 ? void 0 : files.overMaxBytes) && (React__default['default'].createElement(InfoPanel, { variant: "error", className: css.css({ width: '100%' }) },
|
|
1774
1924
|
"Max file size exceeded (",
|
|
1775
|
-
|
|
1925
|
+
getFileSizeDisplay((_d = p.maxBytes) !== null && _d !== void 0 ? _d : 0),
|
|
1776
1926
|
").")))),
|
|
1777
1927
|
canUpload && !(files === null || files === void 0 ? void 0 : files.hasErrors) && (React__default['default'].createElement(Button, { className: css.css({
|
|
1778
|
-
width: (
|
|
1928
|
+
width: (_e = p.buttonWidth) !== null && _e !== void 0 ? _e : '10rem',
|
|
1779
1929
|
zIndex: 1,
|
|
1780
|
-
}), waiting: uploading, type: "submit", variant: (
|
|
1781
|
-
message === 'success' && (React__default['default'].createElement(UploadInfoPanel, { variant: "positive", message: (
|
|
1930
|
+
}), waiting: uploading, type: "submit", variant: (_f = p.buttonVariant) !== null && _f !== void 0 ? _f : 'primary' }, (_g = p.buttonText) !== null && _g !== void 0 ? _g : 'Upload')),
|
|
1931
|
+
message === 'success' && (React__default['default'].createElement(UploadInfoPanel, { variant: "positive", message: (_h = p.successMessage) !== null && _h !== void 0 ? _h : 'Upload successful.', onClear: () => setMessage(undefined) })),
|
|
1782
1932
|
message === 'failure' && (React__default['default'].createElement(UploadInfoPanel, { variant: "error", message: fullFailureMessage, onClear: () => setMessage(undefined) }))));
|
|
1783
1933
|
};
|
|
1784
1934
|
const UploadInfoPanel = (p) => {
|
|
1785
1935
|
return (React__default['default'].createElement(InfoPanel, { variant: p.variant, className: css.css({ zIndex: 1 }) },
|
|
1786
1936
|
p.message,
|
|
1787
|
-
React__default['default'].createElement(Button, {
|
|
1937
|
+
React__default['default'].createElement(Button, { className: css.css({
|
|
1788
1938
|
color: 'inherit',
|
|
1789
|
-
marginTop: '1rem'
|
|
1939
|
+
marginTop: '1rem',
|
|
1940
|
+
width: '100%'
|
|
1790
1941
|
}), onClick: e => {
|
|
1791
1942
|
e.stopPropagation();
|
|
1792
1943
|
p.onClear();
|
|
1793
1944
|
}, rightIcon: React__default['default'].createElement(Icon, { id: "clear" }), variant: "inlineLink" }, "Clear")));
|
|
1794
1945
|
};
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
const
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1946
|
+
// OMG this is dumb. We're sticking with decimals for ease of use.
|
|
1947
|
+
// https://stackoverflow.com/questions/40949135/gigabyte-or-gibibyte-1000-or-1024
|
|
1948
|
+
const getFileSizeDisplay = (size) => {
|
|
1949
|
+
let value = 0;
|
|
1950
|
+
let suffix = '';
|
|
1951
|
+
if (size >= 1000000000) {
|
|
1952
|
+
value = size / 1000000000;
|
|
1953
|
+
suffix = 'GB';
|
|
1954
|
+
}
|
|
1955
|
+
else if (size >= 1000000) {
|
|
1956
|
+
value = size / 1000000;
|
|
1957
|
+
suffix = 'MB';
|
|
1958
|
+
}
|
|
1959
|
+
else if (size >= 1000) {
|
|
1960
|
+
value = size / 1000;
|
|
1961
|
+
suffix = 'KB';
|
|
1803
1962
|
}
|
|
1804
1963
|
else {
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
};
|
|
1808
|
-
|
|
1809
|
-
const getCurrencyDisplay = (value, isCents, denomination = '$') => {
|
|
1810
|
-
let actualValue = value || 0;
|
|
1811
|
-
if (isCents) {
|
|
1812
|
-
actualValue /= 100;
|
|
1964
|
+
value = size;
|
|
1965
|
+
suffix = 'B';
|
|
1813
1966
|
}
|
|
1814
|
-
return
|
|
1815
|
-
};
|
|
1816
|
-
const noop = () => {
|
|
1817
|
-
// lil' noop would be a great rap name. (thanks linter)
|
|
1967
|
+
return value.toLocaleString(undefined, { minimumFractionDigits: 1, maximumFractionDigits: 1 }) + ` ${suffix}`;
|
|
1818
1968
|
};
|
|
1819
1969
|
|
|
1820
1970
|
const Header = (props) => {
|
|
1971
|
+
var _a;
|
|
1821
1972
|
const theme = useThemeSafely();
|
|
1822
1973
|
const bodyStyles = css.css `
|
|
1823
1974
|
padding-top: calc(${theme.layout.headerHeight} + ${theme.layout.headerBodyOffset});
|
|
@@ -1829,7 +1980,9 @@ const Header = (props) => {
|
|
|
1829
1980
|
document.body.classList.remove(bodyStyles);
|
|
1830
1981
|
};
|
|
1831
1982
|
});
|
|
1832
|
-
const toggleMenu = props.toggleMenu
|
|
1983
|
+
const toggleMenu = (_a = props.toggleMenu) !== null && _a !== void 0 ? _a : (() => {
|
|
1984
|
+
/* noop */
|
|
1985
|
+
});
|
|
1833
1986
|
const headerStyles = css.css `
|
|
1834
1987
|
display: flex;
|
|
1835
1988
|
gap: ${theme.controls.gap};
|
|
@@ -1959,7 +2112,7 @@ const Popover = (p) => {
|
|
|
1959
2112
|
};
|
|
1960
2113
|
|
|
1961
2114
|
const InfoTip = (props) => {
|
|
1962
|
-
var _a, _b;
|
|
2115
|
+
var _a, _b, _c;
|
|
1963
2116
|
const [showTip, setShowTip] = React__namespace.useState(false);
|
|
1964
2117
|
const theme = useThemeSafely();
|
|
1965
2118
|
const bgColor = (_a = props.bgColor) !== null && _a !== void 0 ? _a : theme.colors.nav;
|
|
@@ -2021,13 +2174,13 @@ const InfoTip = (props) => {
|
|
|
2021
2174
|
if (props.variant === 'modal') {
|
|
2022
2175
|
return (React__namespace.createElement(React__namespace.Fragment, null,
|
|
2023
2176
|
button,
|
|
2024
|
-
React__namespace.createElement(Modal, { id: props.modalId,
|
|
2177
|
+
React__namespace.createElement(Modal, { id: props.modalId, __debug: props.__modalDebug, show: showTip, heading: props.modalHeader, onClick: closeTip, className: css.css({
|
|
2025
2178
|
whiteSpace: 'normal'
|
|
2026
2179
|
}), closeButton: true },
|
|
2027
2180
|
React__namespace.createElement("div", { className: css.css({ padding: '1rem' }) }, props.content))));
|
|
2028
2181
|
}
|
|
2029
2182
|
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({
|
|
2183
|
+
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
2184
|
padding: '0.5rem',
|
|
2032
2185
|
fontSize: '0.75rem',
|
|
2033
2186
|
maxWidth: '22rem'
|
|
@@ -2107,11 +2260,13 @@ const BaseInput = React__namespace.forwardRef((props, ref) => {
|
|
|
2107
2260
|
right: calc(${theme.controls.padding} * 2);
|
|
2108
2261
|
`}
|
|
2109
2262
|
`;
|
|
2110
|
-
return (React__namespace.createElement("div",
|
|
2263
|
+
return (React__namespace.createElement("div", { className: css.css({
|
|
2264
|
+
width: '100%'
|
|
2265
|
+
}) },
|
|
2111
2266
|
React__namespace.createElement("div", { className: css.cx('input', inputWrapperStyles, wrapperClassName) },
|
|
2112
2267
|
inputElement,
|
|
2113
2268
|
props.rightControl && (React__namespace.createElement("div", { className: rightControlStyles }, props.rightControl))),
|
|
2114
|
-
React__namespace.createElement(InputErrorDisplay, { error: props.error })));
|
|
2269
|
+
React__namespace.createElement(InputErrorDisplay, { error: props.readOnly ? undefined : props.error })));
|
|
2115
2270
|
});
|
|
2116
2271
|
|
|
2117
2272
|
const tryClampRange = (value, min, max) => {
|
|
@@ -2145,19 +2300,19 @@ const getStepDecimalPlaces = (step) => {
|
|
|
2145
2300
|
}
|
|
2146
2301
|
const strStep = typeof step === 'number' ? step.toString() : step;
|
|
2147
2302
|
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
|
-
|
|
2303
|
+
};
|
|
2304
|
+
const tryClampDecimals = (value, step = 0) => {
|
|
2305
|
+
if (value === undefined) {
|
|
2306
|
+
return value;
|
|
2307
|
+
}
|
|
2308
|
+
if (isNaN(value)) {
|
|
2309
|
+
return undefined;
|
|
2310
|
+
}
|
|
2311
|
+
const decimals = getStepDecimalPlaces(step);
|
|
2312
|
+
if (decimals === 0) {
|
|
2313
|
+
return Math.floor(value);
|
|
2314
|
+
}
|
|
2315
|
+
return parseFloat(value.toFixed(decimals));
|
|
2161
2316
|
};
|
|
2162
2317
|
|
|
2163
2318
|
/** Common state handling for displaying validation messages with inputs. */
|
|
@@ -2170,6 +2325,9 @@ const useInputValidationMessage = (ref, props) => {
|
|
|
2170
2325
|
(_a = ref.current) === null || _a === void 0 ? void 0 : _a.setCustomValidity(customError);
|
|
2171
2326
|
setValidationError(customError || getValidationMessage(ref.current, props.patternErrorMessage));
|
|
2172
2327
|
};
|
|
2328
|
+
React.useEffect(() => {
|
|
2329
|
+
updateErrorMessage();
|
|
2330
|
+
}, [props.customError]);
|
|
2173
2331
|
React__default['default'].useEffect(() => {
|
|
2174
2332
|
updateErrorMessage();
|
|
2175
2333
|
}, []);
|
|
@@ -2205,7 +2363,23 @@ const getValidationMessage = (element, patternErrorMessage) => {
|
|
|
2205
2363
|
return `Must be greater than or equal to ${element.min}.`;
|
|
2206
2364
|
}
|
|
2207
2365
|
if (validity.stepMismatch) {
|
|
2208
|
-
|
|
2366
|
+
const decimalPlaces = getStepDecimalPlaces(element.step);
|
|
2367
|
+
if (decimalPlaces > 0) {
|
|
2368
|
+
const place = decimalPlaces === 1 ? 'place' : 'places';
|
|
2369
|
+
return `Limited to ${getStepDecimalPlaces(element.step)} decimal ${place}.`;
|
|
2370
|
+
}
|
|
2371
|
+
else {
|
|
2372
|
+
/*
|
|
2373
|
+
step is buggy!
|
|
2374
|
+
|
|
2375
|
+
at least in Chrome, setting step=5 will cause the browser to mark the field as invalid if the number is not divisible
|
|
2376
|
+
by 5. 55 is ok. 50 is ok. 59 is not ok.
|
|
2377
|
+
|
|
2378
|
+
to make things worse, if you enter an invalid number like 59 with step=5 and then clear the input, Chrome will tell
|
|
2379
|
+
you the number 5 is now invalid and should be 4 or 9.
|
|
2380
|
+
*/
|
|
2381
|
+
return `Must be an integer.`;
|
|
2382
|
+
}
|
|
2209
2383
|
}
|
|
2210
2384
|
}
|
|
2211
2385
|
if (validity.tooShort) {
|
|
@@ -2446,19 +2620,6 @@ const NumberInput = React__namespace.forwardRef((props, ref) => {
|
|
|
2446
2620
|
(_b = props.onBlur) === null || _b === void 0 ? void 0 : _b.call(props, e);
|
|
2447
2621
|
} })));
|
|
2448
2622
|
});
|
|
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
2623
|
const parseNumber = (rawValue) => {
|
|
2463
2624
|
let value;
|
|
2464
2625
|
if (rawValue) {
|
|
@@ -2475,7 +2636,7 @@ const TextInput = React__namespace.forwardRef((props, ref) => {
|
|
|
2475
2636
|
const [localValue, setLocalValue] = React__namespace.useState(props.value);
|
|
2476
2637
|
const inputRef = (ref !== null && ref !== void 0 ? ref : React__namespace.useRef(null));
|
|
2477
2638
|
const [validationError, updateErrorMessage] = useInputValidationMessage(inputRef, props);
|
|
2478
|
-
const nativeProps = __rest(props, ["onValueChange", "customError", "patternErrorMessage"]);
|
|
2639
|
+
const nativeProps = __rest(props, ["emptyString", "onValueChange", "customError", "patternErrorMessage"]);
|
|
2479
2640
|
useIgnoreMount(() => {
|
|
2480
2641
|
var _a;
|
|
2481
2642
|
if ((_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.checkValidity()) {
|
|
@@ -2494,14 +2655,19 @@ const TextInput = React__namespace.forwardRef((props, ref) => {
|
|
|
2494
2655
|
}, [props.value]);
|
|
2495
2656
|
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
2657
|
var _a;
|
|
2497
|
-
setLocalValue(e.target.value || undefined);
|
|
2658
|
+
setLocalValue(props.emptyString ? e.target.value : e.target.value || undefined);
|
|
2498
2659
|
(_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, e);
|
|
2499
2660
|
}, onBlur: e => {
|
|
2500
|
-
var _a;
|
|
2661
|
+
var _a, _b;
|
|
2501
2662
|
if (!e.target.checkValidity()) {
|
|
2502
2663
|
setLocalValue(undefined);
|
|
2503
2664
|
}
|
|
2504
|
-
(_a = props.
|
|
2665
|
+
else if ((_a = props.trim) !== null && _a !== void 0 ? _a : true) {
|
|
2666
|
+
setLocalValue(currentValue => {
|
|
2667
|
+
return currentValue === null || currentValue === void 0 ? void 0 : currentValue.trim();
|
|
2668
|
+
});
|
|
2669
|
+
}
|
|
2670
|
+
(_b = props.onBlur) === null || _b === void 0 ? void 0 : _b.call(props, e);
|
|
2505
2671
|
} })));
|
|
2506
2672
|
});
|
|
2507
2673
|
|
|
@@ -2597,6 +2763,9 @@ const Label = (props) => {
|
|
|
2597
2763
|
From https://fireship.io/snippets/use-media-query-hook/.
|
|
2598
2764
|
Tried using https://www.npmjs.com/package/react-media, but it cause Webpack build issues.
|
|
2599
2765
|
*/
|
|
2766
|
+
/** React wrapper around window resizing and window.matchMedia.
|
|
2767
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia
|
|
2768
|
+
*/
|
|
2600
2769
|
const useMediaQuery = (query) => {
|
|
2601
2770
|
const [matches, setMatches] = React.useState(false);
|
|
2602
2771
|
React.useEffect(() => {
|
|
@@ -2612,11 +2781,13 @@ const useMediaQuery = (query) => {
|
|
|
2612
2781
|
};
|
|
2613
2782
|
|
|
2614
2783
|
const Nav = (props) => {
|
|
2784
|
+
var _a, _b;
|
|
2615
2785
|
const nav = React__namespace.useRef(null);
|
|
2616
2786
|
const theme = useThemeSafely();
|
|
2617
2787
|
const totalNavOffset = `calc(${theme.layout.navWidth} + 20px)`;
|
|
2618
2788
|
const backdrop = React__namespace.useContext(BackdropContext);
|
|
2619
2789
|
const isLargeScreen = useMediaQuery(`(min-width:${theme.breakpoints.desktop})`);
|
|
2790
|
+
const log = useLogger(`Nav ${(_a = props.id) !== null && _a !== void 0 ? _a : '?'}`, (_b = props.__debug) !== null && _b !== void 0 ? _b : false);
|
|
2620
2791
|
const slideRight = css.keyframes `
|
|
2621
2792
|
0% {
|
|
2622
2793
|
transform: translateX(0);
|
|
@@ -2677,9 +2848,11 @@ const Nav = (props) => {
|
|
|
2677
2848
|
props.toggle(false);
|
|
2678
2849
|
}
|
|
2679
2850
|
}, [backdrop.showing]);
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2851
|
+
useBooleanChanged((current, previous) => {
|
|
2852
|
+
var _a;
|
|
2853
|
+
log('show changed', `${previous !== null && previous !== void 0 ? previous : 'undefined'} > ${current}`);
|
|
2854
|
+
backdrop.setShow(current, (_a = props.id) !== null && _a !== void 0 ? _a : 'Nav');
|
|
2855
|
+
}, props.show);
|
|
2683
2856
|
React__namespace.useLayoutEffect(() => {
|
|
2684
2857
|
if (nav && nav.current) {
|
|
2685
2858
|
if (props.show) {
|
|
@@ -2710,6 +2883,7 @@ const Nav = (props) => {
|
|
|
2710
2883
|
return (React__namespace.createElement("nav", { ref: nav, className: css.cx('nav', navStyles, props.className) }, props.children));
|
|
2711
2884
|
};
|
|
2712
2885
|
|
|
2886
|
+
//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
2887
|
const OmniLink = (props) => {
|
|
2714
2888
|
var _a, _b, _c;
|
|
2715
2889
|
const theme = useThemeSafely();
|
|
@@ -2886,7 +3060,7 @@ const OmniLink = (props) => {
|
|
|
2886
3060
|
const Picker = (props) => {
|
|
2887
3061
|
const selectProps = __rest(props
|
|
2888
3062
|
// if we put numbers in, we expect them out
|
|
2889
|
-
, ["value", "options", "
|
|
3063
|
+
, ["value", "options", "onValueChange", "readOnly", "round", "controlAlign"]);
|
|
2890
3064
|
// if we put numbers in, we expect them out
|
|
2891
3065
|
let isNumber = false;
|
|
2892
3066
|
if (props.options && props.options.length) {
|
|
@@ -2956,6 +3130,7 @@ const Picker = (props) => {
|
|
|
2956
3130
|
(_a = selectProps.onMouseDown) === null || _a === void 0 ? void 0 : _a.call(selectProps, e);
|
|
2957
3131
|
}
|
|
2958
3132
|
}, onChange: e => {
|
|
3133
|
+
var _a;
|
|
2959
3134
|
let val = e.target.value;
|
|
2960
3135
|
if (isNumber) {
|
|
2961
3136
|
val = parseInt(val, 10);
|
|
@@ -2963,7 +3138,8 @@ const Picker = (props) => {
|
|
|
2963
3138
|
val = '';
|
|
2964
3139
|
}
|
|
2965
3140
|
}
|
|
2966
|
-
props.
|
|
3141
|
+
props.onValueChange(val);
|
|
3142
|
+
(_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, e);
|
|
2967
3143
|
} }), (props.options || []).map(o => {
|
|
2968
3144
|
var _a;
|
|
2969
3145
|
let val;
|
|
@@ -3050,8 +3226,8 @@ const BoundMemoryPager = (p) => {
|
|
|
3050
3226
|
var _a, _b, _c;
|
|
3051
3227
|
const { pager, showPageText } = p, rest = __rest(p, ["pager", "showPageText"]);
|
|
3052
3228
|
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,
|
|
3229
|
+
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" },
|
|
3230
|
+
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
3231
|
p.onPage(d);
|
|
3056
3232
|
} })));
|
|
3057
3233
|
};
|
|
@@ -3062,8 +3238,8 @@ const BoundStaticPager = (p) => {
|
|
|
3062
3238
|
const showLimit = !!(result.limit && p.limitOptions && p.limitOptions.length > 1 && p.onLimit);
|
|
3063
3239
|
const showSort = !!(p.sort !== undefined && p.sortOptions && p.sortOptions.length > 1 && p.onSort);
|
|
3064
3240
|
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 : [],
|
|
3241
|
+
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" },
|
|
3242
|
+
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
3243
|
var _a;
|
|
3068
3244
|
(_a = p.onSort) === null || _a === void 0 ? void 0 : _a.call(p, v);
|
|
3069
3245
|
} }))) : undefined, page: d => {
|
|
@@ -3071,6 +3247,7 @@ const BoundStaticPager = (p) => {
|
|
|
3071
3247
|
} })));
|
|
3072
3248
|
};
|
|
3073
3249
|
|
|
3250
|
+
/** A page of data with helpers props. */
|
|
3074
3251
|
class PagedResult {
|
|
3075
3252
|
constructor(items = [], total = 0, page = 0, limit = 0) {
|
|
3076
3253
|
this.items = items;
|
|
@@ -3081,10 +3258,6 @@ class PagedResult {
|
|
|
3081
3258
|
static fromDto(dto) {
|
|
3082
3259
|
return new PagedResult(dto.items, dto.total, dto.page, dto.limit);
|
|
3083
3260
|
}
|
|
3084
|
-
// allItems: T[]
|
|
3085
|
-
// get pageItems(): T[] {
|
|
3086
|
-
// return this.allItems.slice(this.minPageItemIndex, this.maxPageItemIndex + 1)
|
|
3087
|
-
// }
|
|
3088
3261
|
/** Helper for items.length */
|
|
3089
3262
|
get length() {
|
|
3090
3263
|
return this.items ? this.items.length : 0;
|
|
@@ -3208,7 +3381,7 @@ class PagedResult {
|
|
|
3208
3381
|
}
|
|
3209
3382
|
}
|
|
3210
3383
|
|
|
3211
|
-
/**
|
|
3384
|
+
/** In-memory pager. */
|
|
3212
3385
|
class ItemPager {
|
|
3213
3386
|
constructor(allItems, options) {
|
|
3214
3387
|
var _a, _b, _c, _d;
|
|
@@ -3458,6 +3631,7 @@ const cleanPct = (value) => {
|
|
|
3458
3631
|
return 0;
|
|
3459
3632
|
};
|
|
3460
3633
|
|
|
3634
|
+
/** Provides stateful notifications around async calls. */
|
|
3461
3635
|
const useWaiting = (func) => {
|
|
3462
3636
|
// Guard against the owner of this hook being unmounted at the time of .finally.
|
|
3463
3637
|
const isCancelled = React.useRef(false);
|
|
@@ -3528,6 +3702,28 @@ const GlobalStyles = () => {
|
|
|
3528
3702
|
return null;
|
|
3529
3703
|
};
|
|
3530
3704
|
|
|
3705
|
+
const getCurrencyDisplay = (value, isCents, denomination = '$') => {
|
|
3706
|
+
let actualValue = value || 0;
|
|
3707
|
+
if (isCents) {
|
|
3708
|
+
actualValue /= 100;
|
|
3709
|
+
}
|
|
3710
|
+
return `${denomination}${actualValue.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
|
|
3711
|
+
};
|
|
3712
|
+
/** Converts an enum to an array of entities with id and name. The enum can be an integer or string enum.*/
|
|
3713
|
+
const enumToEntities = (enumObj) => {
|
|
3714
|
+
const entities = [];
|
|
3715
|
+
for (const key in enumObj) {
|
|
3716
|
+
if (isNaN(parseInt(key, 10))) {
|
|
3717
|
+
entities.push({
|
|
3718
|
+
id: enumObj[key],
|
|
3719
|
+
name: key
|
|
3720
|
+
});
|
|
3721
|
+
}
|
|
3722
|
+
}
|
|
3723
|
+
return entities;
|
|
3724
|
+
};
|
|
3725
|
+
//TB: FUTURE Expose in UI.
|
|
3726
|
+
|
|
3531
3727
|
const Slider = (p) => {
|
|
3532
3728
|
const theme = useThemeSafely();
|
|
3533
3729
|
const currentValue = React.useRef(p.value);
|
|
@@ -3810,11 +4006,8 @@ const defaultRows = 10;
|
|
|
3810
4006
|
const TextArea = React__namespace.forwardRef((props, ref) => {
|
|
3811
4007
|
var _a, _b;
|
|
3812
4008
|
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
4009
|
const inputRef = (ref !== null && ref !== void 0 ? ref : React__namespace.useRef(null));
|
|
4010
|
+
const [validationError, updateErrorMessage] = useInputValidationMessage(inputRef, props);
|
|
3818
4011
|
const nativeProps = __rest(props, ["onValueChange"]);
|
|
3819
4012
|
const theme = useThemeSafely();
|
|
3820
4013
|
React__namespace.useEffect(() => {
|
|
@@ -3881,6 +4074,14 @@ const TextArea = React__namespace.forwardRef((props, ref) => {
|
|
|
3881
4074
|
var _a;
|
|
3882
4075
|
setLocalValue(e.target.value || undefined);
|
|
3883
4076
|
(_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, e);
|
|
4077
|
+
}, onBlur: e => {
|
|
4078
|
+
var _a;
|
|
4079
|
+
if (!props.noTrim) {
|
|
4080
|
+
setLocalValue(currentValue => {
|
|
4081
|
+
return currentValue === null || currentValue === void 0 ? void 0 : currentValue.trim();
|
|
4082
|
+
});
|
|
4083
|
+
}
|
|
4084
|
+
(_a = props.onBlur) === null || _a === void 0 ? void 0 : _a.call(props, e);
|
|
3884
4085
|
} })),
|
|
3885
4086
|
React__namespace.createElement(InputErrorDisplay, { error: validationError })));
|
|
3886
4087
|
});
|
|
@@ -3969,17 +4170,14 @@ const WaitingIndicator = (p) => {
|
|
|
3969
4170
|
const [show, setShow] = React.useState(p.show);
|
|
3970
4171
|
const hideTimer = React.useRef(0);
|
|
3971
4172
|
const lastShowStatus = React.useRef(false);
|
|
3972
|
-
const log = useLogger(`WaitingIndicator ${(_a = p.id) !== null && _a !== void 0 ? _a : '?'}`, (_b = p.
|
|
3973
|
-
if (p.
|
|
4173
|
+
const log = useLogger(`WaitingIndicator ${(_a = p.id) !== null && _a !== void 0 ? _a : '?'}`, (_b = p.__debug) !== null && _b !== void 0 ? _b : false);
|
|
4174
|
+
if (p.__debug) {
|
|
3974
4175
|
React.useEffect(() => {
|
|
3975
4176
|
log('mounted');
|
|
3976
4177
|
return () => {
|
|
3977
4178
|
log('unmounted');
|
|
3978
4179
|
};
|
|
3979
4180
|
}, []);
|
|
3980
|
-
React.useEffect(() => {
|
|
3981
|
-
log('re-rendered');
|
|
3982
|
-
});
|
|
3983
4181
|
}
|
|
3984
4182
|
React.useEffect(() => {
|
|
3985
4183
|
log('show changed', p.show);
|
|
@@ -4020,7 +4218,7 @@ const WaitingIndicator = (p) => {
|
|
|
4020
4218
|
}
|
|
4021
4219
|
}
|
|
4022
4220
|
}, [p.show]);
|
|
4023
|
-
return (React__default['default'].createElement(Modal, { id: p.id,
|
|
4221
|
+
return (React__default['default'].createElement(Modal, { id: p.id, __debug: p.__debug, className: "waitingIndicator", show: show, noBackground: true },
|
|
4024
4222
|
React__default['default'].createElement("div", { className: css.css({
|
|
4025
4223
|
color: 'white',
|
|
4026
4224
|
fontSize: '3rem'
|
|
@@ -4028,6 +4226,7 @@ const WaitingIndicator = (p) => {
|
|
|
4028
4226
|
React__default['default'].createElement(Icon, { id: "waiting", spin: true }))));
|
|
4029
4227
|
};
|
|
4030
4228
|
|
|
4229
|
+
exports.Accordian = Accordian;
|
|
4031
4230
|
exports.Autocomplete = Autocomplete;
|
|
4032
4231
|
exports.Backdrop = Backdrop$1;
|
|
4033
4232
|
exports.Backdrop2 = Backdrop;
|
|
@@ -4088,7 +4287,14 @@ exports.Tr = Tr;
|
|
|
4088
4287
|
exports.WaitingIndicator = WaitingIndicator;
|
|
4089
4288
|
exports.calcDynamicThemeProps = calcDynamicThemeProps;
|
|
4090
4289
|
exports.defaultTheme = defaultTheme;
|
|
4290
|
+
exports.enumToEntities = enumToEntities;
|
|
4091
4291
|
exports.getCurrencyDisplay = getCurrencyDisplay;
|
|
4292
|
+
exports.getFileSizeDisplay = getFileSizeDisplay;
|
|
4293
|
+
exports.useAccordianState = useAccordianState;
|
|
4294
|
+
exports.useBooleanChanged = useBooleanChanged;
|
|
4295
|
+
exports.useIgnoreMount = useIgnoreMount;
|
|
4092
4296
|
exports.useMediaQuery = useMediaQuery;
|
|
4297
|
+
exports.useScrollbarSize = useScrollbarSize;
|
|
4093
4298
|
exports.useThemeSafely = useThemeSafely;
|
|
4299
|
+
exports.useWaiting = useWaiting;
|
|
4094
4300
|
//# sourceMappingURL=index.js.map
|