@mackin.com/styleguide 7.9.1 → 8.0.0-beta.11

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.
Files changed (3) hide show
  1. package/index.d.ts +69 -75
  2. package/index.js +851 -528
  3. package/package.json +4 -4
package/index.js CHANGED
@@ -1,13 +1,13 @@
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 nanoid = require('nanoid');
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');
10
+ var nanoid = require('nanoid');
11
11
  var dateFns = require('date-fns');
12
12
  var reactDom = require('react-dom');
13
13
  var reactTinyPopover = require('react-tiny-popover');
@@ -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
- 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);
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}`;
@@ -47,6 +115,7 @@ const calcDynamicThemeProps = (theme) => {
47
115
  theme.controls.focusOutlineShadow = `0px 0px 4px 2px ${theme.colors.focusOutline}`;
48
116
  theme.controls.focusOutlineRequiredShadow = `0px 0px 4px 2px ${theme.colors.focusOutlineRequired}`;
49
117
  theme.controls.dividerBorder = `2px solid ${theme.colors.divider}`;
118
+ theme.controls.inputErrorMinHeight = `calc(${theme.fonts.sizeSmall} * 1.5 + 4px)`;
50
119
  };
51
120
  const defaultTheme = {
52
121
  colors: {
@@ -110,14 +179,13 @@ const defaultTheme = {
110
179
  focusOutlineShadow: '',
111
180
  focusOutlineRequiredShadow: '',
112
181
  roundRadius: '3rem',
113
- /** @deprecated Use theme.controls.borderRadius (global) or style the components individually. */
114
- roundedRadius: '0.5rem',
115
182
  disabledOpacity: '0.5',
116
183
  formButtonMinWidth: '7rem',
117
184
  gap: '1rem',
118
185
  dividerMargin: '1rem',
119
186
  dividerBorder: '',
120
- headerBoxShadow: '0px 2px 12px 6px rgba(0, 0, 0, 0.2)'
187
+ headerBoxShadow: '0px 2px 12px 6px rgba(0, 0, 0, 0.2)',
188
+ inputErrorMinHeight: ''
121
189
  },
122
190
  zIndexes: {
123
191
  header: 50,
@@ -155,193 +223,9 @@ const useThemeSafely = () => {
155
223
  return defaultTheme;
156
224
  };
157
225
 
158
- /** @deprecated Use Backdrop2 going forward. */
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) => {
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
226
  const Button = (props) => {
343
227
  var _a, _b;
344
- const nativeProps = __rest(props, ["variant", "textAlign", "block", "round", "rounded", "rightIcon", "leftIcon", "iconBlock", "small", "readonly", "waiting", "enforceMinWidth"]);
228
+ const nativeProps = __rest(props, ["variant", "textAlign", "block", "round", "rightIcon", "leftIcon", "iconBlock", "small", "readOnly", "waiting", "enforceMinWidth"]);
345
229
  const theme = useThemeSafely();
346
230
  const buttonStyles = css.css `
347
231
  padding-left: ${theme.controls.padding};
@@ -470,50 +354,243 @@ const Button = (props) => {
470
354
  background-color: ${theme.colors.positive};
471
355
  color: ${theme.colors.positiveFont};
472
356
  `}
473
- ${props.variant === 'negative' && `
474
- background-color: ${theme.colors.negative};
475
- color: ${theme.colors.negativeFont};
357
+ ${props.variant === 'negative' && `
358
+ background-color: ${theme.colors.negative};
359
+ color: ${theme.colors.negativeFont};
360
+ `}
361
+ ${props.enforceMinWidth && `
362
+ min-width: ${theme.controls.formButtonMinWidth};
363
+ `}
364
+ ${props.readOnly && `
365
+ cursor: default;
366
+ box-shadow: none;
367
+ pointer-events:none;
368
+
369
+ &:hover {
370
+ filter:none;
371
+ }
372
+
373
+ &:focus {
374
+ box-shadow: none;
375
+ }
376
+ `}
377
+ ${props.small && `
378
+ font-size: 0.8rem;
379
+ height:${theme.controls.heightSmall};
380
+ `}
381
+ ${props.round && `
382
+ border-radius: ${theme.controls.roundRadius};
383
+ `}
384
+ ${props.block && `
385
+ width: 100%;
386
+ `}
387
+ ${props.iconBlock && `
388
+ display: flex;
389
+ justify-content: space-between;
390
+ align-items: center;
391
+ `}
392
+ `;
393
+ const disabled = props.disabled || props.waiting;
394
+ return (React__namespace.createElement("button", Object.assign({}, nativeProps, { disabled: disabled, className: css.cx('button', styles, props.className), type: (_b = props.type) !== null && _b !== void 0 ? _b : 'button' }),
395
+ props.leftIcon && React__namespace.createElement("span", { className: css.css({ marginRight: '0.5rem' }) }, props.leftIcon),
396
+ props.waiting ? React__namespace.createElement(Icon, { id: "waiting", spin: true }) : props.children,
397
+ props.rightIcon && React__namespace.createElement("span", { className: css.css({ marginLeft: '0.5rem' }) }, props.rightIcon)));
398
+ };
399
+
400
+ const accordianExpandTimeMs = 250;
401
+ const accordianMaxHeight = 1020;
402
+ const accordianTimingFunction = 'ease-in-out';
403
+ // we need to apply the seperately so stuff doesn't hang over during expand/collapse.
404
+ // if we remove this and just keep overflow:hidden, autocompletes will get cut off in the subpanels.
405
+ const visibleStyle = css.css({
406
+ overflow: 'visible'
407
+ });
408
+ const Accordian = (props) => {
409
+ var _a, _b, _c, _d;
410
+ const [open, setOpen] = React__namespace.useState(false);
411
+ const theme = useThemeSafely();
412
+ const content = React__namespace.useRef(null);
413
+ const contentStyles = css.css({
414
+ overflow: 'hidden',
415
+ maxHeight: 0,
416
+ transition: `max-height ${(_a = props.expandTimeMs) !== null && _a !== void 0 ? _a : accordianExpandTimeMs}ms ${(_b = props.transitionTimingFunction) !== null && _b !== void 0 ? _b : accordianTimingFunction}`
417
+ });
418
+ const expandedContentStyles = css.css({
419
+ maxHeight: (_c = props.maxHeight) !== null && _c !== void 0 ? _c : accordianMaxHeight
420
+ });
421
+ const expandedContentWrapperStyles = !props.noPad ? css.css({
422
+ padding: '0 1rem 1rem 1rem'
423
+ }) : undefined;
424
+ React__namespace.useEffect(() => {
425
+ const currentContent = content.current;
426
+ if (currentContent) {
427
+ if (open) {
428
+ currentContent.classList.add(expandedContentStyles);
429
+ window.setTimeout(() => {
430
+ currentContent.classList.add(visibleStyle);
431
+ }, accordianExpandTimeMs);
432
+ }
433
+ else {
434
+ currentContent.classList.remove(visibleStyle, expandedContentStyles);
435
+ }
436
+ }
437
+ }, [open]);
438
+ if (props.open !== undefined) {
439
+ React__namespace.useEffect(() => {
440
+ var _a;
441
+ setOpen((_a = props.open) !== null && _a !== void 0 ? _a : false);
442
+ }, [props.open]);
443
+ }
444
+ return (React__namespace.createElement("div", { className: "accordian" },
445
+ React__namespace.createElement(Button, { readOnly: props.disabled, block: (_d = props.block) !== null && _d !== void 0 ? _d : true, variant: props.variant, className: css.cx(css.css({
446
+ display: 'flex',
447
+ alignItems: 'center',
448
+ justifyContent: 'space-between',
449
+ height: 'auto',
450
+ minHeight: theme.controls.height
451
+ }, props.className)), onClick: e => {
452
+ e.stopPropagation();
453
+ if (props.onChange) {
454
+ props.onChange(!open);
455
+ }
456
+ else {
457
+ setOpen(!open);
458
+ }
459
+ }, rightIcon: !props.disabled ? React__namespace.createElement(Icon, { id: open ? 'collapse' : 'expand' }) : undefined },
460
+ React__namespace.createElement("span", null, props.header)),
461
+ React__namespace.createElement("div", { ref: content, className: css.cx('accordian__body', contentStyles) },
462
+ React__namespace.createElement("div", { className: expandedContentWrapperStyles }, props.children))));
463
+ };
464
+ const useAccordianState = (count, openIndex) => {
465
+ const [panels, setShowPanel] = React__namespace.useState(new Array(count).fill(false).map((b, i) => {
466
+ return i === openIndex;
467
+ }));
468
+ return [
469
+ panels,
470
+ (index, open) => {
471
+ setShowPanel(previousState => {
472
+ const newState = previousState.slice().fill(false);
473
+ newState[index] = open;
474
+ return newState;
475
+ });
476
+ }
477
+ ];
478
+ };
479
+
480
+ /** @deprecated Use Backdrop2 going forward. */
481
+ const Backdrop$1 = (props) => {
482
+ var _a;
483
+ const showTimeMs = (_a = props.showTimeMs) !== null && _a !== void 0 ? _a : 250;
484
+ const backdropId = React__namespace.useRef('Backdrop' + nanoid.nanoid());
485
+ const theme = useThemeSafely();
486
+ const backdropStyles = css.css `
487
+ opacity: 0;
488
+ position: fixed;
489
+ top: 0;
490
+ left: 0;
491
+ right: 0;
492
+ bottom: 0;
493
+ background-color: ${theme.colors.backdrop};
494
+ transition: opacity ${showTimeMs}ms ease-in-out;
495
+ visibility: hidden;
496
+ user-select: none;
497
+ -webkit-tap-highlight-color: transparent;
498
+ `;
499
+ const showStyles = css.css `
500
+ z-index: ${theme.zIndexes.backdrop} !important;
501
+ opacity: 1.0 !important;
502
+ label:${backdropId.current};
503
+ `;
504
+ const bodyStyles = css.css `
505
+ overflow: hidden !important;
506
+ label:${backdropId.current};
507
+ `;
508
+ const bodyResponsiveStyles = css.css `
509
+ label:${backdropId.current};
510
+ @media(min-width:${theme.breakpoints.desktop}) {
511
+ overflow: auto !important;
512
+ }
513
+ `;
514
+ const bodyReverseResponsiveStyles = css.css `
515
+ ${bodyStyles}
516
+ overflow: auto !important;
517
+ @media(min-width:${theme.breakpoints.desktop}) {
518
+ overflow: hidden !important;
519
+ }
520
+ `;
521
+ const styles = css.css `
522
+ ${backdropStyles}
523
+ ${props.onClick && `
524
+ cursor: pointer;
525
+ `}
526
+ ${props.transparent && `
527
+ background-color: transparent;
528
+ transition: none;
476
529
  `}
477
- ${props.enforceMinWidth && `
478
- min-width: ${theme.controls.formButtonMinWidth};
530
+ ${props.children && `
531
+ display: flex;
532
+ justify-content:center;
533
+ align-items: center;
479
534
  `}
480
- ${props.readonly && `
481
- cursor: default;
482
- box-shadow: none;
483
- pointer-events:none;
484
-
485
- &:hover {
486
- filter:none;
487
- }
488
-
489
- &:focus {
490
- box-shadow: none;
535
+ ${props.responsive && `
536
+ @media(min-width:${theme.breakpoints.desktop}) {
537
+ display: none;
491
538
  }
492
539
  `}
493
- ${props.small && `
494
- font-size: 0.8rem;
495
- height:${theme.controls.heightSmall};
496
- `}
497
- ${props.round && `
498
- border-radius: ${theme.controls.roundRadius};
499
- `}
500
- ${props.rounded && `
501
- border-radius: ${theme.controls.roundedRadius};
502
- `}
503
- ${props.block && `
504
- width: 100%;
505
- `}
506
- ${props.iconBlock && `
507
- display: flex;
508
- justify-content: space-between;
509
- align-items: center;
540
+ ${props.reverseResponsive && `
541
+ display: none;
542
+ @media(min-width:${theme.breakpoints.desktop}) {
543
+ display: flex;
544
+ }
510
545
  `}
511
546
  `;
512
- const disabled = props.disabled || props.waiting;
513
- return (React__namespace.createElement("button", Object.assign({}, nativeProps, { disabled: disabled, className: css.cx('button', styles, props.className), type: (_b = props.type) !== null && _b !== void 0 ? _b : 'button' }),
514
- props.leftIcon && React__namespace.createElement("span", { className: css.css({ marginRight: '0.5rem' }) }, props.leftIcon),
515
- props.waiting ? React__namespace.createElement(Icon, { id: "waiting", spin: true }) : props.children,
516
- props.rightIcon && React__namespace.createElement("span", { className: css.css({ marginLeft: '0.5rem' }) }, props.rightIcon)));
547
+ const backdrop = React__namespace.useRef(null);
548
+ React__namespace.useEffect(() => {
549
+ if (backdrop && backdrop.current) {
550
+ if (props.show && backdrop.current.style.visibility !== 'visible') {
551
+ backdrop.current.style.visibility = 'visible';
552
+ backdrop.current.classList.add(showStyles);
553
+ if (!props.allowScroll) {
554
+ document.body.classList.add(bodyStyles);
555
+ if (props.responsive) {
556
+ document.body.classList.add(bodyResponsiveStyles);
557
+ }
558
+ else if (props.reverseResponsive) {
559
+ document.body.classList.add(bodyReverseResponsiveStyles);
560
+ }
561
+ }
562
+ }
563
+ else if (!props.show && backdrop.current.style.visibility === 'visible') {
564
+ backdrop.current.classList.remove(showStyles);
565
+ if (backdrop && backdrop.current) {
566
+ backdrop.current.style.visibility = 'hidden';
567
+ if (!props.allowScroll) {
568
+ document.body.classList.remove(bodyStyles);
569
+ if (props.responsive) {
570
+ document.body.classList.remove(bodyResponsiveStyles);
571
+ }
572
+ else if (props.reverseResponsive) {
573
+ document.body.classList.remove(bodyReverseResponsiveStyles);
574
+ }
575
+ }
576
+ }
577
+ }
578
+ }
579
+ return () => {
580
+ if (backdrop && backdrop.current && !props.allowScroll) {
581
+ document.body.classList.remove(bodyStyles);
582
+ }
583
+ };
584
+ }, [props.show]);
585
+ return (React__namespace.createElement("div", { onMouseDown: e => {
586
+ var _a;
587
+ e.stopPropagation();
588
+ e.preventDefault();
589
+ (_a = props.onClick) === null || _a === void 0 ? void 0 : _a.call(props);
590
+ }, onClick: e => {
591
+ e.stopPropagation();
592
+ e.preventDefault();
593
+ }, ref: backdrop, className: css.cx('backdrop', styles, props.className) }, props.children));
517
594
  };
518
595
 
519
596
  const DEFAULT_DEBOUNCE_MS = 250;
@@ -589,8 +666,6 @@ const Input = React__namespace.forwardRef((props, ref) => {
589
666
  borderRadius: theme.controls.roundRadius,
590
667
  paddingLeft: `calc(${theme.controls.padding} * 2)`,
591
668
  paddingRight: `calc(${theme.controls.padding} * 2)`
592
- }, props.rounded && {
593
- borderRadius: theme.controls.roundedRadius
594
669
  }, props.readOnly && {
595
670
  backgroundColor: 'transparent',
596
671
  cursor: 'default',
@@ -875,7 +950,7 @@ const getAutocompleteValueId = (v) => {
875
950
  }
876
951
  return v.id;
877
952
  };
878
- //TB: will need to use the new input
953
+ //TB: FUTURE will need to use the new input
879
954
  const Autocomplete = (p) => {
880
955
  var _a;
881
956
  const element = React__namespace.useRef(null);
@@ -907,7 +982,7 @@ const Autocomplete = (p) => {
907
982
  width: 100%;
908
983
  `;
909
984
  let listBorderRadius = '';
910
- if (p.round || p.rounded || theme.controls.borderRadius) {
985
+ if (p.round || theme.controls.borderRadius) {
911
986
  listBorderRadius = theme.controls.borderRadius || '0.5rem';
912
987
  }
913
988
  const listClass = css.css({
@@ -960,7 +1035,7 @@ const Autocomplete = (p) => {
960
1035
  return (React__namespace.createElement("div", { ref: element, className: css.cx(baseClass, 'autocomplete') },
961
1036
  React__namespace.createElement(Backdrop$1, { onClick: () => setValues([]), show: showValues, allowScroll: true, transparent: true }),
962
1037
  React__namespace.createElement(TabLocker, { disabled: !showValues, style: { position: 'relative' } },
963
- React__namespace.createElement(Input, { inputAriaAttributes: p.inputAriaAttributes, ref: input, debounceMs: 0, type: "text", value: getAutocompleteValueText(p.value), round: p.round, rounded: p.rounded, rightControl: p.rightControl, placeholder: p.placeholder, id: p.id, disabled: p.disabled, className: p.className, inputClassName: css.cx(inputClass, p.inputClassName), maxLength: p.maxLength, required: p.required, onChange: v => {
1038
+ 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: css.cx(inputClass, p.inputClassName), maxLength: p.maxLength, required: p.required, onChange: v => {
964
1039
  const value = v;
965
1040
  p.onChange(value);
966
1041
  onChangeForOptions.current(value);
@@ -1224,7 +1299,7 @@ const Calendar = (p) => {
1224
1299
  };
1225
1300
 
1226
1301
  const Checkbox = (props) => {
1227
- const inputProps = __rest(props, ["checked", "onChange", "label", "checkedIcon", "uncheckedIcon", "checkedThemeColor", "checkedColor", "readonly"]);
1302
+ const inputProps = __rest(props, ["checked", "onChange", "label", "checkedIcon", "uncheckedIcon", "checkedThemeColor", "checkedColor", "readOnly"]);
1228
1303
  const selected = props.checkedIcon || 'selected';
1229
1304
  const unselected = props.uncheckedIcon || 'unselected';
1230
1305
  const theme = useThemeSafely();
@@ -1239,7 +1314,7 @@ const Checkbox = (props) => {
1239
1314
  }
1240
1315
  const checkboxStyles = css.css `
1241
1316
  display: inline-block;
1242
- ${!props.disabled && !props.readonly && `
1317
+ ${!props.disabled && !props.readOnly && `
1243
1318
  &:hover {
1244
1319
  filter: ${theme.controls.hoverBrightness};
1245
1320
  }
@@ -1253,7 +1328,7 @@ const Checkbox = (props) => {
1253
1328
  ${props.disabled && `
1254
1329
  cursor: not-allowed;
1255
1330
  `}
1256
- ${props.readonly && `
1331
+ ${props.readOnly && `
1257
1332
  cursor: default;
1258
1333
  `}
1259
1334
  `;
@@ -1265,7 +1340,7 @@ const Checkbox = (props) => {
1265
1340
  width: 0;
1266
1341
  opacity: 0;
1267
1342
 
1268
- ${!props.readonly && `
1343
+ ${!props.readOnly && `
1269
1344
  &:focus + .checkboxIcon {
1270
1345
  box-shadow: ${theme.controls.focusOutlineShadow};
1271
1346
  }
@@ -1279,7 +1354,7 @@ const Checkbox = (props) => {
1279
1354
  background-color: ${theme.colors.disabled};
1280
1355
  cursor: not-allowed;
1281
1356
  `}
1282
- ${props.readonly && `
1357
+ ${props.readOnly && `
1283
1358
  cursor: default;
1284
1359
  `}
1285
1360
  ${props.checked && `
@@ -1288,8 +1363,8 @@ const Checkbox = (props) => {
1288
1363
  `;
1289
1364
  return (React__namespace.createElement("span", { className: css.cx('checkbox', checkboxStyles, props.className) },
1290
1365
  React__namespace.createElement("label", { className: labelStyles },
1291
- React__namespace.createElement("input", Object.assign({}, inputProps, { tabIndex: props.readonly ? -1 : undefined, className: nativeCheckboxStyles, type: "checkbox", onChange: e => {
1292
- if (props.readonly) {
1366
+ React__namespace.createElement("input", Object.assign({}, inputProps, { tabIndex: props.readOnly ? -1 : undefined, className: nativeCheckboxStyles, type: "checkbox", onChange: e => {
1367
+ if (props.readOnly) {
1293
1368
  e.preventDefault();
1294
1369
  return;
1295
1370
  }
@@ -1496,93 +1571,6 @@ const CopyButton = (props) => {
1496
1571
  React__namespace.createElement(Icon, { id: copied ? 'paste' : 'copy' })));
1497
1572
  };
1498
1573
 
1499
- const Popover = (p) => {
1500
- var _a, _b;
1501
- const theme = useThemeSafely();
1502
- const resposition = (_a = p.reposition) !== null && _a !== void 0 ? _a : true;
1503
- return (React__namespace.createElement(reactTinyPopover.Popover, { containerClassName: css.css({
1504
- zIndex: theme.zIndexes.tooltip
1505
- }), reposition: resposition, isOpen: p.isOpen, positions: (_b = p.positions) !== null && _b !== void 0 ? _b : ['right', 'top', 'left', 'bottom'], onClickOutside: p.onClickOutside, content: ({ position, childRect, popoverRect }) => {
1506
- var _a, _b, _c, _d;
1507
- return (React__namespace.createElement(reactTinyPopover.ArrowContainer, { position: position, childRect: childRect, popoverRect: popoverRect, arrowColor: (_a = p.arrorColor) !== null && _a !== void 0 ? _a : theme.colors.border, arrowSize: 10 },
1508
- React__namespace.createElement(TabLocker, null,
1509
- React__namespace.createElement("div", { className: css.css({
1510
- border: (_b = p.border) !== null && _b !== void 0 ? _b : theme.controls.border,
1511
- borderRadius: (_c = p.border) !== null && _c !== void 0 ? _c : theme.controls.borderRadius,
1512
- boxShadow: theme.controls.boxShadow,
1513
- backgroundColor: (_d = p.backgroundColor) !== null && _d !== void 0 ? _d : theme.colors.bg,
1514
- }) }, p.content))));
1515
- } },
1516
- React__namespace.createElement("span", null, p.parent)));
1517
- };
1518
-
1519
- const getCalendarDate = (date, min, max) => {
1520
- let calendarDate = date ? new Date(date) : new Date();
1521
- // if there is a min/max we don't want the calendar to open to the current date if it's out of range
1522
- if (min && dateFns.isBefore(calendarDate, min)) {
1523
- calendarDate = new Date(min);
1524
- }
1525
- else if (max && dateFns.isAfter(calendarDate, max)) {
1526
- calendarDate = new Date(max);
1527
- }
1528
- return calendarDate;
1529
- };
1530
- const DatePicker = (p) => {
1531
- const [showCalendar, setShowCalendar] = React__namespace.useState(false);
1532
- const [calendarDate, setCalendarDate] = React__namespace.useState(getCalendarDate(p.value, p.min, p.max));
1533
- // controls the one-time focus set on show
1534
- const needsFocus = React__namespace.useRef(false);
1535
- const popover = React__namespace.useRef(null);
1536
- React__namespace.useEffect(() => {
1537
- var _a;
1538
- setCalendarDate(getCalendarDate((_a = p.value) !== null && _a !== void 0 ? _a : 0, p.min, p.max));
1539
- }, [p.value]);
1540
- React__namespace.useLayoutEffect(() => {
1541
- var _a, _b;
1542
- if (needsFocus.current) {
1543
- (_b = (_a = popover.current) === null || _a === void 0 ? void 0 : _a.querySelector('button')) === null || _b === void 0 ? void 0 : _b.focus();
1544
- needsFocus.current = false;
1545
- }
1546
- });
1547
- //TB: replace with new inputs
1548
- return (React__namespace.createElement(Popover, { reposition: p.reposition, isOpen: showCalendar, onClickOutside: () => {
1549
- needsFocus.current = false;
1550
- setShowCalendar(false);
1551
- }, parent: (React__namespace.createElement(Input, Object.assign({ onFocus: () => {
1552
- needsFocus.current = false;
1553
- setShowCalendar(false);
1554
- }, placeholder: 'MM/DD/YYYY' }, p, { type: "date", rightControl: !p.readOnly ? (React__namespace.createElement(Button, { variant: "icon", readonly: p.readOnly, disabled: p.disabled, small: true, style: {
1555
- fontSize: '1rem'
1556
- }, onClick: () => {
1557
- needsFocus.current = !showCalendar;
1558
- setShowCalendar(!showCalendar);
1559
- } },
1560
- React__namespace.createElement(Icon, { id: "pickDate" }))) : undefined, onChange: v => {
1561
- p.onChange(v);
1562
- } }))), content: (React__namespace.createElement("div", { ref: popover, className: css.css({
1563
- paddingLeft: '1rem',
1564
- paddingRight: '1rem',
1565
- paddingBottom: '1rem'
1566
- }) },
1567
- React__namespace.createElement(Calendar, { onClick: date => {
1568
- p.onChange(date.valueOf());
1569
- needsFocus.current = false;
1570
- setShowCalendar(false);
1571
- }, customTitle: React__namespace.createElement("div", { className: css.css({
1572
- display: 'flex',
1573
- justifyContent: 'space-between',
1574
- alignItems: 'center'
1575
- }) },
1576
- React__namespace.createElement(Button, { disabled: !!p.min && dateFns.isBefore(dateFns.endOfMonth(dateFns.addMonths(calendarDate, -1)), p.min), small: true, variant: "icon", onClick: () => setCalendarDate(dateFns.addMonths(calendarDate, -1)) },
1577
- React__namespace.createElement(Icon, { id: "pagerLeft" })),
1578
- React__namespace.createElement(Text, { align: "center" },
1579
- dateFns.format(calendarDate, 'LLLL'),
1580
- " ",
1581
- calendarDate.getFullYear()),
1582
- React__namespace.createElement(Button, { disabled: !!p.max && dateFns.isAfter(dateFns.startOfMonth(dateFns.addMonths(calendarDate, 1)), p.max), small: true, variant: "icon", onClick: () => setCalendarDate(dateFns.addMonths(calendarDate, 1)) },
1583
- React__namespace.createElement(Icon, { id: "pagerRight" }))), month: calendarDate.getMonth() + 1, year: calendarDate.getFullYear(), showCurrent: true, smallHeader: true, selectedValue: p.value, cellSize: '2rem', min: p.min, max: p.max }))) }));
1584
- };
1585
-
1586
1574
  const Divider = () => {
1587
1575
  const theme = useThemeSafely();
1588
1576
  return (React__namespace.createElement("hr", { className: css.cx("divider", css.css({
@@ -1898,13 +1886,6 @@ const getSizeString = (size) => {
1898
1886
  }
1899
1887
  };
1900
1888
 
1901
- /** @deprecated This will not work correctly with emotion/css. Use 'cx' for adding multiple class names together. */
1902
- const mergeClassNames = (...classes) => {
1903
- if (!classes) {
1904
- return undefined;
1905
- }
1906
- return classes.filter(c => c).map(c => c).join(' ');
1907
- };
1908
1889
  const getCurrencyDisplay = (value, isCents, denomination = '$') => {
1909
1890
  let actualValue = value || 0;
1910
1891
  if (isCents) {
@@ -2037,6 +2018,26 @@ const Image = (props) => {
2037
2018
  }), props.className), src: props.src }));
2038
2019
  };
2039
2020
 
2021
+ const Popover = (p) => {
2022
+ var _a, _b;
2023
+ const theme = useThemeSafely();
2024
+ const resposition = (_a = p.reposition) !== null && _a !== void 0 ? _a : true;
2025
+ return (React__namespace.createElement(reactTinyPopover.Popover, { containerClassName: css.css({
2026
+ zIndex: theme.zIndexes.tooltip
2027
+ }), reposition: resposition, isOpen: p.isOpen, positions: (_b = p.positions) !== null && _b !== void 0 ? _b : ['right', 'top', 'left', 'bottom'], onClickOutside: p.onClickOutside, content: ({ position, childRect, popoverRect }) => {
2028
+ var _a, _b, _c, _d;
2029
+ return (React__namespace.createElement(reactTinyPopover.ArrowContainer, { position: position, childRect: childRect, popoverRect: popoverRect, arrowColor: (_a = p.arrorColor) !== null && _a !== void 0 ? _a : theme.colors.border, arrowSize: 10 },
2030
+ React__namespace.createElement(TabLocker, null,
2031
+ React__namespace.createElement("div", { className: css.css({
2032
+ border: (_b = p.border) !== null && _b !== void 0 ? _b : theme.controls.border,
2033
+ borderRadius: (_c = p.border) !== null && _c !== void 0 ? _c : theme.controls.borderRadius,
2034
+ boxShadow: theme.controls.boxShadow,
2035
+ backgroundColor: (_d = p.backgroundColor) !== null && _d !== void 0 ? _d : theme.colors.bg,
2036
+ }) }, p.content))));
2037
+ } },
2038
+ React__namespace.createElement("span", null, p.parent)));
2039
+ };
2040
+
2040
2041
  const InfoTip = (props) => {
2041
2042
  var _a, _b;
2042
2043
  const [showTip, setShowTip] = React__namespace.useState(false);
@@ -2114,6 +2115,15 @@ const InfoTip = (props) => {
2114
2115
  }
2115
2116
  };
2116
2117
 
2118
+ const InputErrorDisplay = (props) => {
2119
+ const theme = useThemeSafely();
2120
+ return (React__namespace.createElement(Text, { className: css.css({
2121
+ minHeight: theme.controls.inputErrorMinHeight,
2122
+ lineHeight: theme.controls.inputErrorMinHeight,
2123
+ color: theme.colors.negative
2124
+ }), smaller: true, noPad: true }, props.error));
2125
+ };
2126
+
2117
2127
  const defaultMaxLength$1 = 100;
2118
2128
  const BaseInput = React__namespace.forwardRef((props, ref) => {
2119
2129
  var _a;
@@ -2177,178 +2187,417 @@ const BaseInput = React__namespace.forwardRef((props, ref) => {
2177
2187
  right: calc(${theme.controls.padding} * 2);
2178
2188
  `}
2179
2189
  `;
2180
- return (React__namespace.createElement("div", { className: css.cx('input', inputWrapperStyles, wrapperClassName) },
2181
- inputElement,
2182
- props.rightControl && React__namespace.createElement("div", { className: rightControlStyles }, props.rightControl)));
2190
+ return (React__namespace.createElement("div", null,
2191
+ React__namespace.createElement("div", { className: css.cx('input', inputWrapperStyles, wrapperClassName) },
2192
+ inputElement,
2193
+ props.rightControl && (React__namespace.createElement("div", { className: rightControlStyles }, props.rightControl))),
2194
+ React__namespace.createElement(InputErrorDisplay, { error: props.error })));
2183
2195
  });
2184
2196
 
2197
+ const tryClampRange = (value, min, max) => {
2198
+ if (value === undefined) {
2199
+ return value;
2200
+ }
2201
+ if (isNaN(value)) {
2202
+ return undefined;
2203
+ }
2204
+ if (min !== undefined && value < min) {
2205
+ return min;
2206
+ }
2207
+ if (max !== undefined && value > max) {
2208
+ return max;
2209
+ }
2210
+ return value;
2211
+ };
2212
+ const isOutOfRange = (value, min, max) => {
2213
+ if (min !== undefined && value < min) {
2214
+ return true;
2215
+ }
2216
+ if (max !== undefined && value > max) {
2217
+ return true;
2218
+ }
2219
+ return false;
2220
+ };
2221
+ const getStepDecimalPlaces = (step) => {
2222
+ var _a, _b;
2223
+ if (!step) {
2224
+ return 0;
2225
+ }
2226
+ const strStep = typeof step === 'number' ? step.toString() : step;
2227
+ return (_b = (_a = strStep.split('.')[1]) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
2228
+ };
2229
+ const tryClampDecimals = (value, step = 0) => {
2230
+ if (value === undefined) {
2231
+ return value;
2232
+ }
2233
+ if (isNaN(value)) {
2234
+ return undefined;
2235
+ }
2236
+ const decimals = getStepDecimalPlaces(step);
2237
+ if (decimals === 0) {
2238
+ return Math.floor(value);
2239
+ }
2240
+ return parseFloat(value.toFixed(decimals));
2241
+ };
2242
+
2243
+ /** useEffect but ignores the first call on component mount. */
2244
+ const useIgnoreMount = (effect, deps) => {
2245
+ const mounted = React__default['default'].useRef(false);
2246
+ React__default['default'].useEffect(() => {
2247
+ if (!mounted.current) {
2248
+ mounted.current = true;
2249
+ }
2250
+ else {
2251
+ effect();
2252
+ }
2253
+ }, deps);
2254
+ };
2255
+
2256
+ /** Common state handling for displaying validation messages with inputs. */
2257
+ const useInputValidationMessage = (ref, props) => {
2258
+ const [validationError, setValidationError] = React__default['default'].useState('');
2259
+ const updateErrorMessage = (customErrorOverride) => {
2260
+ var _a;
2261
+ const customError = customErrorOverride || props.customError || '';
2262
+ // set it OR clear it. either way, update it.
2263
+ (_a = ref.current) === null || _a === void 0 ? void 0 : _a.setCustomValidity(customError);
2264
+ setValidationError(customError || getValidationMessage(ref.current, props.patternErrorMessage));
2265
+ };
2266
+ React__default['default'].useEffect(() => {
2267
+ updateErrorMessage();
2268
+ }, []);
2269
+ return [validationError, updateErrorMessage];
2270
+ };
2271
+ const getValidationMessage = (element, patternErrorMessage) => {
2272
+ var _a;
2273
+ if (!element) {
2274
+ return '';
2275
+ }
2276
+ const validity = element.validity;
2277
+ if (validity.valid) {
2278
+ return '';
2279
+ }
2280
+ if (validity.customError) {
2281
+ return element.validationMessage;
2282
+ }
2283
+ if (validity.typeMismatch) {
2284
+ switch (element.type) {
2285
+ case 'url':
2286
+ return `Invalid URL.`;
2287
+ case 'email':
2288
+ return `Invalid email.`;
2289
+ default:
2290
+ return element.validationMessage;
2291
+ }
2292
+ }
2293
+ if (element instanceof HTMLInputElement) {
2294
+ if (validity.rangeOverflow) {
2295
+ return `Must be less than or equal to ${element.max}.`;
2296
+ }
2297
+ if (validity.rangeUnderflow) {
2298
+ return `Must be greater than or equal to ${element.min}.`;
2299
+ }
2300
+ if (validity.stepMismatch) {
2301
+ const decimalPlaces = getStepDecimalPlaces(element.step);
2302
+ if (decimalPlaces > 0) {
2303
+ const place = decimalPlaces === 1 ? 'place' : 'places';
2304
+ return `Limited to ${getStepDecimalPlaces(element.step)} decimal ${place}.`;
2305
+ }
2306
+ else {
2307
+ /*
2308
+ step is buggy!
2309
+
2310
+ at least in Chrome, setting step=5 will cause the browser to mark the field as invalid if the number is not divisible
2311
+ by 5. 55 is ok. 50 is ok. 59 is not ok.
2312
+
2313
+ to make things worse, if you enter an invalid number like 59 with step=5 and then clear the input, Chrome will tell
2314
+ you the number 5 is now invalid and should be 4 or 9.
2315
+ */
2316
+ return `Must be an integer.`;
2317
+ }
2318
+ }
2319
+ }
2320
+ if (validity.tooShort) {
2321
+ return `Must be at least ${((_a = element.minLength) !== null && _a !== void 0 ? _a : 0).toLocaleString()} characters in length.`;
2322
+ }
2323
+ if (validity.valueMissing) {
2324
+ return 'Required.';
2325
+ }
2326
+ if (validity.patternMismatch && patternErrorMessage) {
2327
+ return patternErrorMessage;
2328
+ }
2329
+ // unhandled. let the browser decide.
2330
+ return element.validationMessage;
2331
+ };
2332
+
2185
2333
  const dateRegex = /(\d{1,2})(?:\/|-)(\d{1,2})(?:\/|-)(\d{4})/;
2186
2334
  const datePattern = dateRegex.source;
2187
- const outOfRangeValidityMessage = 'Out of range';
2188
- const isOutOfRange = (value, min = Number.MIN_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER) => {
2189
- if (typeof value === 'number') {
2190
- return value < min || value > max;
2335
+ const invalidDateMessage = 'Invalid date.';
2336
+ const DateInput = React__namespace.forwardRef((props, ref) => {
2337
+ var _a;
2338
+ const [dateValue, setDateValue] = React__namespace.useState(props.value);
2339
+ const [textValue, setTextValue] = React__namespace.useState(parseDateString(props.value));
2340
+ const updateValues = React__namespace.useCallback((value) => {
2341
+ let newDateValue;
2342
+ let newTextValue;
2343
+ if (typeof value === 'number') {
2344
+ newDateValue = value;
2345
+ newTextValue = parseDateString(value);
2346
+ }
2347
+ else if (typeof value === 'string') {
2348
+ newDateValue = parseDateNumber(value);
2349
+ newTextValue = value;
2350
+ }
2351
+ setDateValue(newDateValue);
2352
+ setTextValue(newTextValue);
2353
+ }, []);
2354
+ const inputRef = (ref !== null && ref !== void 0 ? ref : React__namespace.useRef(null));
2355
+ const [validationError, updateErrorMessage] = useInputValidationMessage(inputRef, { customError: props.customError, patternErrorMessage: invalidDateMessage });
2356
+ const updateDateErrorMessages = React__namespace.useCallback(() => {
2357
+ let dateError = '';
2358
+ if (dateValue === undefined) {
2359
+ if (!!textValue) {
2360
+ // the text pattern is a valid date format, but the numbers are wrong. example: 05/35/2000.
2361
+ dateError = invalidDateMessage;
2362
+ }
2363
+ }
2364
+ else if (isOutOfRange(dateValue, props.min, props.max)) {
2365
+ // out of range
2366
+ if (props.min !== undefined && props.max !== undefined) {
2367
+ dateError = `Must be be between ${parseDateString(props.min)} and ${parseDateString(props.max)}.`;
2368
+ }
2369
+ else if (props.min !== undefined) {
2370
+ dateError = `Must be greater than or equal to ${parseDateString(props.min)}.`;
2371
+ }
2372
+ else {
2373
+ dateError = `Must be less than or equal to ${parseDateString(props.max)}.`;
2374
+ }
2375
+ }
2376
+ updateErrorMessage(dateError);
2377
+ }, [dateValue, textValue]);
2378
+ const [showCalendar, setShowCalendar] = React__namespace.useState(false);
2379
+ const [calendarDate, setCalendarDate] = React__namespace.useState(getCalendarDate(props.value, props.min, props.max));
2380
+ // controls the one-time focus set on show
2381
+ const needsFocus = React__namespace.useRef(false);
2382
+ const toggleCalendar = React__namespace.useCallback((show) => {
2383
+ var _a;
2384
+ if (show === showCalendar) {
2385
+ return;
2386
+ }
2387
+ needsFocus.current = show;
2388
+ setShowCalendar(show);
2389
+ if (show) {
2390
+ setCalendarDate(getCalendarDate(dateValue, props.min, props.max));
2391
+ }
2392
+ else {
2393
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
2394
+ }
2395
+ }, [dateValue, showCalendar]);
2396
+ const popover = React__namespace.useRef(null);
2397
+ const nativeProps = __rest(props, ["customError", "reposition", "onValueChange"]);
2398
+ useIgnoreMount(() => {
2399
+ var _a;
2400
+ if ((_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.checkValidity()) {
2401
+ props.onValueChange(dateValue);
2402
+ }
2403
+ else {
2404
+ props.onValueChange(undefined);
2405
+ }
2406
+ updateDateErrorMessages();
2407
+ }, [dateValue]);
2408
+ useIgnoreMount(() => {
2409
+ updateDateErrorMessages();
2410
+ }, [textValue]);
2411
+ useIgnoreMount(() => {
2412
+ var _a;
2413
+ if (document.activeElement !== inputRef.current) {
2414
+ updateValues(props.value);
2415
+ setCalendarDate(getCalendarDate((_a = props.value) !== null && _a !== void 0 ? _a : 0, props.min, props.max));
2416
+ }
2417
+ updateDateErrorMessages();
2418
+ }, [props.value]);
2419
+ React__namespace.useLayoutEffect(() => {
2420
+ var _a, _b;
2421
+ if (needsFocus.current) {
2422
+ (_b = (_a = popover.current) === null || _a === void 0 ? void 0 : _a.querySelector('button')) === null || _b === void 0 ? void 0 : _b.focus();
2423
+ needsFocus.current = false;
2424
+ }
2425
+ });
2426
+ const input = (React__namespace.createElement(BaseInput, Object.assign({}, nativeProps, { error: validationError, type: "text", ref: inputRef, value: textValue !== null && textValue !== void 0 ? textValue : '', maxLength: 10, placeholder: (_a = props.placeholder) !== null && _a !== void 0 ? _a : 'MM/DD/YYYY', pattern: datePattern, rightControl: (!props.readOnly && !props.disabled) ? (React__namespace.createElement(Button, { variant: "icon", readOnly: props.readOnly, disabled: props.disabled, small: true, style: {
2427
+ fontSize: '1rem'
2428
+ }, onClick: () => {
2429
+ toggleCalendar(!showCalendar);
2430
+ } },
2431
+ React__namespace.createElement(Icon, { id: "pickDate" }))) : undefined, onChange: e => {
2432
+ var _a;
2433
+ updateValues(e.target.value || undefined);
2434
+ (_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, e);
2435
+ }, onFocus: e => {
2436
+ var _a;
2437
+ toggleCalendar(false);
2438
+ (_a = props.onFocus) === null || _a === void 0 ? void 0 : _a.call(props, e);
2439
+ }, onBlur: e => {
2440
+ var _a, _b;
2441
+ if (!((_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.checkValidity())) {
2442
+ if (dateValue !== undefined) {
2443
+ if (isOutOfRange(dateValue, props.min, props.max)) {
2444
+ // try and fix the range
2445
+ updateValues(tryClampRange(dateValue, props.min, props.max));
2446
+ }
2447
+ }
2448
+ else {
2449
+ // just wipe it all
2450
+ updateValues(undefined);
2451
+ }
2452
+ }
2453
+ (_b = props.onBlur) === null || _b === void 0 ? void 0 : _b.call(props, e);
2454
+ } })));
2455
+ return (React__namespace.createElement(Popover, { reposition: props.reposition, isOpen: showCalendar, onClickOutside: () => {
2456
+ toggleCalendar(false);
2457
+ }, parent: input, content: (React__namespace.createElement("div", { ref: popover, className: css.css({
2458
+ paddingLeft: '1rem',
2459
+ paddingRight: '1rem',
2460
+ paddingBottom: '1rem'
2461
+ }) },
2462
+ React__namespace.createElement(Calendar, { onClick: date => {
2463
+ updateValues(date.valueOf());
2464
+ toggleCalendar(false);
2465
+ }, customTitle: React__namespace.createElement("div", { className: css.css({
2466
+ display: 'flex',
2467
+ justifyContent: 'space-between',
2468
+ alignItems: 'center'
2469
+ }) },
2470
+ React__namespace.createElement(Button, { disabled: !!props.min && dateFns.isBefore(dateFns.endOfMonth(dateFns.addMonths(calendarDate, -1)), props.min), small: true, variant: "icon", onClick: () => setCalendarDate(dateFns.addMonths(calendarDate, -1)) },
2471
+ React__namespace.createElement(Icon, { id: "pagerLeft" })),
2472
+ React__namespace.createElement(Text, { align: "center" },
2473
+ dateFns.format(calendarDate, 'LLLL'),
2474
+ " ",
2475
+ calendarDate.getFullYear()),
2476
+ React__namespace.createElement(Button, { disabled: !!props.max && dateFns.isAfter(dateFns.startOfMonth(dateFns.addMonths(calendarDate, 1)), props.max), small: true, variant: "icon", onClick: () => setCalendarDate(dateFns.addMonths(calendarDate, 1)) },
2477
+ React__namespace.createElement(Icon, { id: "pagerRight" }))), month: calendarDate.getMonth() + 1, year: calendarDate.getFullYear(), showCurrent: true, smallHeader: true, selectedValue: dateValue, cellSize: '2rem', min: props.min, max: props.max }))) }));
2478
+ });
2479
+ const parseDateNumber = (rawValue) => {
2480
+ if (!rawValue) {
2481
+ return undefined;
2191
2482
  }
2192
- return false;
2193
- };
2194
- const parseDateMs = (rawValue, min = Number.MIN_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER) => {
2195
- let value;
2196
- let outOfRange = false;
2483
+ let dateMs;
2197
2484
  const dateParts = dateRegex.exec(rawValue);
2198
2485
  if (dateParts) {
2199
- const month = parseInt(dateParts[1], 10);
2486
+ const month = parseInt(dateParts[1], 10) - 1;
2200
2487
  const day = parseInt(dateParts[2], 10);
2201
2488
  const year = parseInt(dateParts[3], 10);
2202
2489
  if (dateFns.isExists(year, month, day)) {
2203
- value = new Date(year, month - 1, day).valueOf();
2204
- outOfRange = isOutOfRange(value, min, max);
2205
- if (outOfRange) {
2206
- value = Math.max(Math.min(value, max), min);
2207
- }
2490
+ dateMs = new Date(year, month, day).valueOf();
2208
2491
  }
2209
2492
  }
2210
- return {
2211
- value,
2212
- outOfRange
2213
- };
2493
+ return dateMs;
2214
2494
  };
2215
- const formatOuterValue = (value) => {
2216
- if (typeof value === 'number') {
2217
- return dateFns.format(value, 'MM/dd/yyyy');
2495
+ const parseDateString = (dateMs) => {
2496
+ if (typeof dateMs === 'number') {
2497
+ return dateFns.format(dateMs, 'MM/dd/yyyy');
2218
2498
  }
2219
- return '';
2499
+ return undefined;
2220
2500
  };
2221
- const DateInput = React__namespace.forwardRef((props, ref) => {
2222
- const [localValue, setLocalValue] = React__namespace.useState('');
2223
- const hasFocus = React__namespace.useRef(false);
2501
+ const getCalendarDate = (date, min, max) => {
2502
+ let calendarDate = date ? new Date(date) : new Date();
2503
+ // if there is a min/max we don't want the calendar to open to the current date if it's out of range
2504
+ if (min && dateFns.isBefore(calendarDate, min)) {
2505
+ calendarDate = new Date(min);
2506
+ }
2507
+ else if (max && dateFns.isAfter(calendarDate, max)) {
2508
+ calendarDate = new Date(max);
2509
+ }
2510
+ return calendarDate;
2511
+ };
2512
+
2513
+ const NumberInput = React__namespace.forwardRef((props, ref) => {
2514
+ const [localValue, setLocalValue] = React__namespace.useState(props.value);
2224
2515
  const inputRef = (ref !== null && ref !== void 0 ? ref : React__namespace.useRef(null));
2225
- const { value, onChange } = props, otherProps = __rest(props, ["value", "onChange"]);
2226
- React__namespace.useEffect(() => {
2516
+ const [validationError, updateErrorMessage] = useInputValidationMessage(inputRef, props);
2517
+ const nativeProps = __rest(props, ["customError", "onValueChange"]);
2518
+ useIgnoreMount(() => {
2227
2519
  var _a;
2228
- // prevent the outer value from influencing the inner value while you're typing.
2229
- if (!hasFocus.current) {
2230
- // sync the outer value to the local value if it changed.
2231
- setLocalValue(formatOuterValue(value));
2232
- (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.setCustomValidity((isOutOfRange(value, props.min, props.max) ? outOfRangeValidityMessage : ''));
2233
- }
2234
- }, [value]);
2235
- return (React__namespace.createElement(BaseInput, Object.assign({}, otherProps, { pattern: datePattern, maxLength: 10, ref: inputRef, type: "text", value: localValue, onChange: e => {
2236
- setLocalValue(e.target.value);
2237
- const { value: v, outOfRange } = parseDateMs(e.target.value, props.min, props.max);
2238
- // need to force invalid due to our using a 'text' input rather than a 'number' or 'date'.
2239
- e.target.setCustomValidity(outOfRange ? outOfRangeValidityMessage : '');
2240
- onChange(v, e);
2241
- }, onFocus: e => {
2520
+ if ((_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.checkValidity()) {
2521
+ props.onValueChange(localValue);
2522
+ }
2523
+ else {
2524
+ props.onValueChange(undefined);
2525
+ }
2526
+ updateErrorMessage();
2527
+ }, [localValue]);
2528
+ useIgnoreMount(() => {
2529
+ if (document.activeElement !== inputRef.current) {
2530
+ setLocalValue(props.value);
2531
+ }
2532
+ updateErrorMessage();
2533
+ }, [props.value]);
2534
+ return (React__namespace.createElement(BaseInput, Object.assign({}, nativeProps, { error: validationError, type: "number", ref: inputRef, value: localValue !== null && localValue !== void 0 ? localValue : '', maxLength: 20, onChange: e => {
2242
2535
  var _a;
2243
- hasFocus.current = true;
2244
- (_a = props.onFocus) === null || _a === void 0 ? void 0 : _a.call(props, e);
2536
+ const newLocalValue = parseNumber(e.target.value);
2537
+ setLocalValue(newLocalValue);
2538
+ (_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, e);
2245
2539
  }, onBlur: e => {
2246
- var _a;
2247
- hasFocus.current = false;
2248
- (_a = props.onFocus) === null || _a === void 0 ? void 0 : _a.call(props, e);
2249
- // min/max constraints won't be reflected in the local input value. fix that now.
2250
- // handling min/max while typing would be difficult and frustrating to the user.
2251
- setLocalValue(formatOuterValue(value));
2252
- e.target.setCustomValidity(isOutOfRange(value, props.min, props.max) ? outOfRangeValidityMessage : '');
2540
+ var _a, _b;
2541
+ let adjustedValue = localValue;
2542
+ if (e.target.validity.customError) {
2543
+ // if we're invalid due to a custom error, just wipe everything
2544
+ adjustedValue = undefined;
2545
+ }
2546
+ else {
2547
+ // try and fix the value
2548
+ adjustedValue = tryClampRange(adjustedValue, props.min, props.max);
2549
+ adjustedValue = tryClampDecimals(adjustedValue, props.step);
2550
+ }
2551
+ setLocalValue(adjustedValue);
2552
+ // makes our displayed value always matches the adjusted value
2553
+ // examples of failures are 'e', '-', and 5.0 in an integer (step=0) field.
2554
+ e.target.value = (_a = adjustedValue === null || adjustedValue === void 0 ? void 0 : adjustedValue.toString()) !== null && _a !== void 0 ? _a : '';
2555
+ (_b = props.onBlur) === null || _b === void 0 ? void 0 : _b.call(props, e);
2253
2556
  } })));
2254
- });
2255
-
2256
- const parseNumber = (rawValue, step = 0, min = Number.MIN_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER, applyMinMax) => {
2257
- var _a;
2258
- const decimals = step === 0 ? 0 : (_a = step.toString().split('.')[1]) === null || _a === void 0 ? void 0 : _a.length;
2557
+ });
2558
+ const parseNumber = (rawValue) => {
2259
2559
  let value;
2260
2560
  if (rawValue) {
2261
2561
  value = parseFloat(rawValue);
2262
2562
  if (isNaN(value)) {
2263
- value = undefined;
2264
- }
2265
- else {
2266
- if (decimals === 0) {
2267
- value = Math.floor(value);
2268
- }
2269
- else {
2270
- value = parseFloat(value.toFixed(decimals));
2271
- }
2272
- if (applyMinMax) {
2273
- value = Math.max(Math.min(value, max), min);
2274
- }
2563
+ return undefined;
2275
2564
  }
2276
2565
  }
2277
- return [value, value === null || value === void 0 ? void 0 : value.toString()];
2278
- };
2279
- const NumberInput = React__namespace.forwardRef((props, ref) => {
2280
- var _a, _b;
2281
- const { value, onChange, constrainOnInput } = props, otherProps = __rest(props, ["value", "onChange", "constrainOnInput"]);
2282
- const applyInputConstraints = (_a = props.constrainOnInput) !== null && _a !== void 0 ? _a : true;
2283
- return (React__namespace.createElement(BaseInput, Object.assign({}, otherProps, { ref: ref, maxLength: (_b = props.maxLength) !== null && _b !== void 0 ? _b : 50, type: "number", value: value !== null && value !== void 0 ? value : '', onChange: e => {
2284
- const [v, displayValue] = parseNumber(e.target.value, props.step, props.min, props.max, applyInputConstraints);
2285
- // make sure the displayed value always matches our parsed value.
2286
- e.target.value = displayValue !== null && displayValue !== void 0 ? displayValue : '';
2287
- onChange(v, e);
2288
- }, onBlur: e => {
2289
- if (applyInputConstraints) {
2290
- // catch all for things we missed.
2291
- // onChange would have been called with undefined, but something strange might remain.
2292
- if (!e.target.checkValidity()) {
2293
- e.target.value = '';
2294
- }
2295
- }
2296
- } })));
2297
- });
2298
-
2299
- const defaultMaxLength = 200;
2300
- const defaultRows = 10;
2301
- const TextArea = React__namespace.forwardRef((props, ref) => {
2302
- var _a, _b;
2303
- const { className, value, onChange } = props, otherProps = __rest(props, ["className", "value", "onChange"]);
2304
- const theme = useThemeSafely();
2305
- const styles = css.css({
2306
- maxWidth: '100%',
2307
- minHeight: theme.controls.height,
2308
- fontFamily: theme.fonts.family,
2309
- fontSize: theme.fonts.size,
2310
- width: '100%',
2311
- border: theme.controls.border,
2312
- borderRadius: theme.controls.borderRadius,
2313
- color: theme.colors.font,
2314
- paddingTop: '0.75rem',
2315
- paddingLeft: theme.controls.padding,
2316
- paddingRight: theme.controls.padding,
2317
- height: 'auto',
2318
- transition: theme.controls.transition,
2319
- ':focus': {
2320
- outline: 'none',
2321
- boxShadow: theme.controls.focusOutlineShadow
2322
- },
2323
- ':disabled': {
2324
- backgroundColor: theme.colors.disabled,
2325
- cursor: 'not-allowed'
2326
- },
2327
- ':invalid': {
2328
- borderColor: theme.colors.required,
2329
- ':focus': {
2330
- boxShadow: theme.controls.focusOutlineRequiredShadow
2331
- }
2332
- },
2333
- }, props.readOnly && {
2334
- backgroundColor: 'transparent',
2335
- cursor: 'default',
2336
- border: 'none',
2337
- ':focus': {
2338
- outline: 'none',
2339
- boxShadow: 'none'
2340
- }
2341
- });
2342
- return (React__namespace.createElement("textarea", Object.assign({}, otherProps, { className: css.cx(styles, className), autoComplete: (_a = props.autoComplete) !== null && _a !== void 0 ? _a : 'off', tabIndex: props.readOnly ? -1 : props.tabIndex, maxLength: props.maxLength || defaultMaxLength, rows: (_b = props.rows) !== null && _b !== void 0 ? _b : defaultRows, ref: ref, value: value !== null && value !== void 0 ? value : '', onChange: e => {
2343
- onChange(e.target.value || undefined, e);
2344
- } })));
2345
- });
2566
+ return value;
2567
+ };
2346
2568
 
2347
2569
  const TextInput = React__namespace.forwardRef((props, ref) => {
2348
2570
  var _a;
2349
- const { value, onChange } = props, otherProps = __rest(props, ["value", "onChange"]);
2350
- return (React__namespace.createElement(BaseInput, Object.assign({}, otherProps, { type: (_a = props.type) !== null && _a !== void 0 ? _a : 'text', ref: ref, value: value !== null && value !== void 0 ? value : '', onChange: e => {
2351
- onChange(e.target.value || undefined, e);
2571
+ const [localValue, setLocalValue] = React__namespace.useState(props.value);
2572
+ const inputRef = (ref !== null && ref !== void 0 ? ref : React__namespace.useRef(null));
2573
+ const [validationError, updateErrorMessage] = useInputValidationMessage(inputRef, props);
2574
+ const nativeProps = __rest(props, ["onValueChange", "customError", "patternErrorMessage"]);
2575
+ useIgnoreMount(() => {
2576
+ var _a;
2577
+ if ((_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.checkValidity()) {
2578
+ props.onValueChange(localValue);
2579
+ }
2580
+ else {
2581
+ props.onValueChange(undefined);
2582
+ }
2583
+ updateErrorMessage();
2584
+ }, [localValue]);
2585
+ useIgnoreMount(() => {
2586
+ if (document.activeElement !== inputRef.current) {
2587
+ setLocalValue(props.value);
2588
+ }
2589
+ updateErrorMessage();
2590
+ }, [props.value]);
2591
+ 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 => {
2592
+ var _a;
2593
+ setLocalValue(e.target.value || undefined);
2594
+ (_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, e);
2595
+ }, onBlur: e => {
2596
+ var _a;
2597
+ if (!e.target.checkValidity()) {
2598
+ setLocalValue(undefined);
2599
+ }
2600
+ (_a = props.onBlur) === null || _a === void 0 ? void 0 : _a.call(props, e);
2352
2601
  } })));
2353
2602
  });
2354
2603
 
@@ -2704,9 +2953,6 @@ const OmniLink = (props) => {
2704
2953
  ${props.round && `
2705
2954
  border-radius: ${theme.controls.roundRadius};
2706
2955
  `}
2707
- ${props.rounded && `
2708
- border-radius: ${theme.controls.roundedRadius};
2709
- `}
2710
2956
  ${props.small && `
2711
2957
  font-size: 0.8rem;
2712
2958
  height: ${theme.controls.heightSmall};
@@ -2736,7 +2982,7 @@ const OmniLink = (props) => {
2736
2982
  const Picker = (props) => {
2737
2983
  const selectProps = __rest(props
2738
2984
  // if we put numbers in, we expect them out
2739
- , ["value", "options", "onChange", "type", "rounded", "round", "readonly"]);
2985
+ , ["value", "options", "onChange", "readOnly", "round", "controlAlign"]);
2740
2986
  // if we put numbers in, we expect them out
2741
2987
  let isNumber = false;
2742
2988
  if (props.options && props.options.length) {
@@ -2769,13 +3015,10 @@ const Picker = (props) => {
2769
3015
  outline: none;
2770
3016
  box-shadow: ${theme.controls.focusOutlineShadow};
2771
3017
  }
2772
- ${props.rounded && `
2773
- border-radius: ${theme.controls.roundedRadius};
2774
- `}
2775
3018
  ${props.round && `
2776
3019
  border-radius: ${theme.controls.roundRadius};
2777
3020
  `}
2778
- ${props.readonly && `
3021
+ ${props.readOnly && `
2779
3022
  background-color: transparent !important;
2780
3023
  border: none;
2781
3024
  -webkit-appearance: none;
@@ -2786,9 +3029,9 @@ const Picker = (props) => {
2786
3029
  }
2787
3030
  `}
2788
3031
  `;
2789
- return (React__namespace.createElement("select", Object.assign({}, selectProps, { tabIndex: props.readonly ? -1 : selectProps.tabIndex, className: css.cx('picker', selectStyles, props.className), value: props.value, onKeyDown: e => {
3032
+ const select = (React__namespace.createElement("select", Object.assign({}, selectProps, { tabIndex: props.readOnly ? -1 : selectProps.tabIndex, className: css.cx('picker', selectStyles, props.className), value: props.value, onKeyDown: e => {
2790
3033
  var _a;
2791
- if (props.readonly) {
3034
+ if (props.readOnly) {
2792
3035
  if (e.keyCode === 9) {
2793
3036
  //TAB
2794
3037
  return;
@@ -2801,7 +3044,7 @@ const Picker = (props) => {
2801
3044
  }
2802
3045
  }, onMouseDown: e => {
2803
3046
  var _a;
2804
- if (props.readonly) {
3047
+ if (props.readOnly) {
2805
3048
  e.preventDefault();
2806
3049
  e.stopPropagation();
2807
3050
  }
@@ -2831,6 +3074,14 @@ const Picker = (props) => {
2831
3074
  }
2832
3075
  return React__namespace.createElement("option", { key: val, value: val }, label);
2833
3076
  })));
3077
+ if (props.controlAlign) {
3078
+ return (React__namespace.createElement("span", { className: css.css({
3079
+ display: 'inline-block',
3080
+ width: '100%',
3081
+ paddingBottom: theme.controls.inputErrorMinHeight
3082
+ }) }, select));
3083
+ }
3084
+ return select;
2834
3085
  };
2835
3086
 
2836
3087
  const Pager = (props) => {
@@ -2861,9 +3112,6 @@ const Pager = (props) => {
2861
3112
  @media(min-width: ${theme.breakpoints.tablet}) {
2862
3113
  grid-template-columns: ${theme.controls.height} 1fr 1fr 1fr ${theme.controls.height};
2863
3114
  }
2864
- ${props.rounded && `
2865
- border-radius: ${theme.controls.roundedRadius};
2866
- `}
2867
3115
  `;
2868
3116
  const controlStyles = css.css `
2869
3117
  display: none;
@@ -2898,8 +3146,8 @@ const BoundMemoryPager = (p) => {
2898
3146
  var _a, _b, _c;
2899
3147
  const { pager, showPageText } = p, rest = __rest(p, ["pager", "showPageText"]);
2900
3148
  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" },
2901
- React__namespace.createElement(Picker, { type: "select", value: pager.limit, options: pager.limitOptions, onChange: 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" },
2902
- React__namespace.createElement(Picker, { type: "select", value: (_c = pager.sort) !== null && _c !== void 0 ? _c : '', options: pager.sortOptions, onChange: v => { var _a; return (_a = p.onSort) === null || _a === void 0 ? void 0 : _a.call(p, v); } }))) : undefined, page: d => {
3149
+ React__namespace.createElement(Picker, { value: pager.limit, options: pager.limitOptions, onChange: 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" },
3150
+ React__namespace.createElement(Picker, { value: (_c = pager.sort) !== null && _c !== void 0 ? _c : '', options: pager.sortOptions, onChange: v => { var _a; return (_a = p.onSort) === null || _a === void 0 ? void 0 : _a.call(p, v); } }))) : undefined, page: d => {
2903
3151
  p.onPage(d);
2904
3152
  } })));
2905
3153
  };
@@ -2910,8 +3158,8 @@ const BoundStaticPager = (p) => {
2910
3158
  const showLimit = !!(result.limit && p.limitOptions && p.limitOptions.length > 1 && p.onLimit);
2911
3159
  const showSort = !!(p.sort !== undefined && p.sortOptions && p.sortOptions.length > 1 && p.onSort);
2912
3160
  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" },
2913
- React__namespace.createElement(Picker, { type: "select", value: (_b = result.limit) !== null && _b !== void 0 ? _b : 1, options: (_c = p.limitOptions) !== null && _c !== void 0 ? _c : [1], onChange: 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" },
2914
- React__namespace.createElement(Picker, { type: "select", value: (_e = p.sort) !== null && _e !== void 0 ? _e : '', options: (_f = p.sortOptions) !== null && _f !== void 0 ? _f : [], onChange: v => {
3161
+ React__namespace.createElement(Picker, { value: (_b = result.limit) !== null && _b !== void 0 ? _b : 1, options: (_c = p.limitOptions) !== null && _c !== void 0 ? _c : [1], onChange: 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" },
3162
+ React__namespace.createElement(Picker, { value: (_e = p.sort) !== null && _e !== void 0 ? _e : '', options: (_f = p.sortOptions) !== null && _f !== void 0 ? _f : [], onChange: v => {
2915
3163
  var _a;
2916
3164
  (_a = p.onSort) === null || _a === void 0 ? void 0 : _a.call(p, v);
2917
3165
  } }))) : undefined, page: d => {
@@ -3338,14 +3586,14 @@ const SearchBox = (props) => {
3338
3586
  return (_c = props.onSubmit) === null || _c === void 0 ? void 0 : _c.call(props);
3339
3587
  });
3340
3588
  const theme = useThemeSafely();
3341
- const submitButton = (React__namespace.createElement(Button, { disabled: waiting, readonly: !props.onSubmit, type: "submit", className: css.css({
3589
+ const submitButton = (React__namespace.createElement(Button, { disabled: waiting, readOnly: !props.onSubmit, type: "submit", className: css.css({
3342
3590
  color: `${theme.colors.font} !important;`,
3343
3591
  fontSize: '1rem'
3344
3592
  }), variant: "icon", small: true },
3345
3593
  React__namespace.createElement(Icon, { id: waiting ? 'waiting' : 'search', spin: waiting })));
3346
- //TB: replace with new inputs
3594
+ //TB: FUTURE replace with new inputs
3347
3595
  return (React__namespace.createElement(Form, { role: "search", className: css.cx('searchBox', props.className), onSubmit: onSubmit },
3348
- React__namespace.createElement(Input, { id: props.id, debounceMs: props.debounceMs, disabled: waiting, type: "text", value: props.value, placeholder: props.placeholder, round: props.round, rounded: props.rounded, onChange: props.onChange, rightControl: submitButton })));
3596
+ React__namespace.createElement(Input, { id: props.id, debounceMs: props.debounceMs, disabled: waiting, type: "text", value: props.value, placeholder: props.placeholder, round: props.round, onChange: props.onChange, rightControl: submitButton })));
3349
3597
  };
3350
3598
 
3351
3599
  const GlobalStyles = () => {
@@ -3504,10 +3752,6 @@ const TabHeader = (p) => {
3504
3752
  borderBottomRightRadius: 0,
3505
3753
  borderBottom: 'none',
3506
3754
  zIndex: 3,
3507
- }, active && p.rounded && {
3508
- borderRadius: p.rounded && theme.controls.roundedRadius,
3509
- borderBottomLeftRadius: 0,
3510
- borderBottomRightRadius: 0,
3511
3755
  });
3512
3756
  buttonVariant = 'link';
3513
3757
  buttonStyles = css.css({
@@ -3525,7 +3769,7 @@ const TabHeader = (p) => {
3525
3769
  });
3526
3770
  }
3527
3771
  return (React__namespace.createElement("li", { key: index, className: tabStyles },
3528
- React__namespace.createElement(Button, { className: buttonStyles, variant: buttonVariant, title: tab.name, readonly: active, rounded: p.rounded && variant === 'button', onClick: () => {
3772
+ React__namespace.createElement(Button, { className: buttonStyles, variant: buttonVariant, title: tab.name, readOnly: active, onClick: () => {
3529
3773
  setTabIndex(index);
3530
3774
  if (p.onTabChanged) {
3531
3775
  p.onTabChanged(index);
@@ -3657,6 +3901,86 @@ const ThSort = (props) => {
3657
3901
  props.rightContent)));
3658
3902
  };
3659
3903
 
3904
+ const defaultMaxLength = 200;
3905
+ const defaultRows = 10;
3906
+ const TextArea = React__namespace.forwardRef((props, ref) => {
3907
+ var _a, _b;
3908
+ const [localValue, setLocalValue] = React__namespace.useState(props.value);
3909
+ const [validationError, setValidationError] = React__namespace.useState('');
3910
+ const updateErrorMessage = React__namespace.useCallback(() => {
3911
+ setValidationError(getValidationMessage(inputRef.current));
3912
+ }, []);
3913
+ const inputRef = (ref !== null && ref !== void 0 ? ref : React__namespace.useRef(null));
3914
+ const nativeProps = __rest(props, ["onValueChange"]);
3915
+ const theme = useThemeSafely();
3916
+ React__namespace.useEffect(() => {
3917
+ updateErrorMessage();
3918
+ }, []);
3919
+ useIgnoreMount(() => {
3920
+ var _a;
3921
+ if ((_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.checkValidity()) {
3922
+ props.onValueChange(localValue);
3923
+ }
3924
+ else {
3925
+ props.onValueChange(undefined);
3926
+ }
3927
+ updateErrorMessage();
3928
+ }, [localValue]);
3929
+ useIgnoreMount(() => {
3930
+ if (document.activeElement !== inputRef.current) {
3931
+ setLocalValue(props.value);
3932
+ }
3933
+ updateErrorMessage();
3934
+ }, [props.value]);
3935
+ const styles = css.css({
3936
+ maxWidth: '100%',
3937
+ minHeight: theme.controls.height,
3938
+ fontFamily: theme.fonts.family,
3939
+ fontSize: theme.fonts.size,
3940
+ width: '100%',
3941
+ border: theme.controls.border,
3942
+ borderRadius: theme.controls.borderRadius,
3943
+ color: theme.colors.font,
3944
+ paddingTop: '0.75rem',
3945
+ paddingLeft: theme.controls.padding,
3946
+ paddingRight: theme.controls.padding,
3947
+ height: 'auto',
3948
+ transition: theme.controls.transition,
3949
+ ':focus': {
3950
+ outline: 'none',
3951
+ boxShadow: theme.controls.focusOutlineShadow
3952
+ },
3953
+ ':disabled': {
3954
+ backgroundColor: theme.colors.disabled,
3955
+ cursor: 'not-allowed'
3956
+ },
3957
+ ':invalid': {
3958
+ borderColor: theme.colors.required,
3959
+ ':focus': {
3960
+ boxShadow: theme.controls.focusOutlineRequiredShadow
3961
+ }
3962
+ },
3963
+ }, props.readOnly && {
3964
+ backgroundColor: 'transparent',
3965
+ cursor: 'default',
3966
+ border: 'none',
3967
+ ':focus': {
3968
+ outline: 'none',
3969
+ boxShadow: 'none'
3970
+ }
3971
+ });
3972
+ return (React__namespace.createElement("span", { className: css.css({
3973
+ display: 'inline-block',
3974
+ width: '100%'
3975
+ }) },
3976
+ React__namespace.createElement("textarea", Object.assign({}, nativeProps, { className: css.cx(styles, props.className), autoComplete: (_a = props.autoComplete) !== null && _a !== void 0 ? _a : 'off', tabIndex: props.readOnly ? -1 : props.tabIndex, maxLength: props.maxLength || defaultMaxLength, rows: (_b = props.rows) !== null && _b !== void 0 ? _b : defaultRows, ref: inputRef, value: localValue !== null && localValue !== void 0 ? localValue : '', onChange: e => {
3977
+ var _a;
3978
+ setLocalValue(e.target.value || undefined);
3979
+ (_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, e);
3980
+ } })),
3981
+ React__namespace.createElement(InputErrorDisplay, { error: validationError })));
3982
+ });
3983
+
3660
3984
  const ToggleButton = (props) => {
3661
3985
  return (React__namespace.createElement(Button, { type: "button", className: css.cx('toggleButton', props.checked && 'toggleButton--checked', props.className, props.checked && props.checkedClassName), rightIcon: props.checked ? props.checkedIcon : props.uncheckedIcon, disabled: props.disabled, enforceMinWidth: props.enforceMinWidth, variant: props.checked ? props.checkedVariant : props.variant, style: props.checked ? props.checkedStyle : props.style, onClick: props.onClick }, props.checked ? props.checkedText : props.uncheckedText));
3662
3986
  };
@@ -3724,10 +4048,9 @@ const ToggleButtonGroup = (props) => {
3724
4048
  })));
3725
4049
  };
3726
4050
 
3727
- const TogglePasswordInput = (p) => {
4051
+ const TogglePasswordInput = React__namespace.forwardRef((props, ref) => {
3728
4052
  const [show, setShow] = React__namespace.useState(false);
3729
- //TB: replace with new inputs
3730
- return (React__namespace.createElement(Input, Object.assign({}, p, { type: show ? 'text' : 'password', rightControl: (React__namespace.createElement(Button, { small: true, style: {
4053
+ return (React__namespace.createElement(TextInput, Object.assign({}, props, { ref: ref, type: show ? 'text' : 'password', rightControl: (React__namespace.createElement(Button, { small: true, style: {
3731
4054
  // small button is required here due to the icon pushing outside the boundries of the
3732
4055
  // parent textbox. increasing the font size here to fill the small button.
3733
4056
  fontSize: '1rem'
@@ -3735,7 +4058,7 @@ const TogglePasswordInput = (p) => {
3735
4058
  setShow(previous => !previous);
3736
4059
  } },
3737
4060
  React__namespace.createElement(Icon, { id: show ? 'show' : 'hide' }))) })));
3738
- };
4061
+ });
3739
4062
 
3740
4063
  const WaitingIndicator = (p) => {
3741
4064
  var _a, _b;
@@ -3801,6 +4124,7 @@ const WaitingIndicator = (p) => {
3801
4124
  React__default['default'].createElement(Icon, { id: "waiting", spin: true }))));
3802
4125
  };
3803
4126
 
4127
+ exports.Accordian = Accordian;
3804
4128
  exports.Autocomplete = Autocomplete;
3805
4129
  exports.Backdrop = Backdrop$1;
3806
4130
  exports.Backdrop2 = Backdrop;
@@ -3812,7 +4136,6 @@ exports.Checkbox = Checkbox;
3812
4136
  exports.ConfirmModal = ConfirmModal;
3813
4137
  exports.CopyButton = CopyButton;
3814
4138
  exports.DateInput = DateInput;
3815
- exports.DatePicker = DatePicker;
3816
4139
  exports.Divider = Divider;
3817
4140
  exports.ErrorModal = ErrorModal;
3818
4141
  exports.FileUploader = FileUploader;
@@ -3863,7 +4186,7 @@ exports.WaitingIndicator = WaitingIndicator;
3863
4186
  exports.calcDynamicThemeProps = calcDynamicThemeProps;
3864
4187
  exports.defaultTheme = defaultTheme;
3865
4188
  exports.getCurrencyDisplay = getCurrencyDisplay;
3866
- exports.mergeClassNames = mergeClassNames;
4189
+ exports.useAccordianState = useAccordianState;
3867
4190
  exports.useMediaQuery = useMediaQuery;
3868
4191
  exports.useThemeSafely = useThemeSafely;
3869
4192
  //# sourceMappingURL=index.js.map