@evoke-platform/ui-components 1.0.0-dev.184 → 1.0.0-dev.187

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 (123) hide show
  1. package/README.md +1 -0
  2. package/dist/published/components/core/Autocomplete/Autocomplete.d.ts +3 -3
  3. package/dist/published/components/core/Autocomplete/Autocomplete.js +5 -5
  4. package/dist/published/components/core/Autocomplete/Autocomplete.test.d.ts +1 -0
  5. package/dist/published/components/core/Autocomplete/Autocomplete.test.js +11 -0
  6. package/dist/published/components/core/Autocomplete/index.d.ts +2 -1
  7. package/dist/published/components/core/LocalizationProvider/LocalizationProvider.js +6 -4
  8. package/dist/published/components/core/Select/Select.d.ts +1 -2
  9. package/dist/published/components/core/Snackbar/Snackbar.d.ts +2 -2
  10. package/dist/published/components/core/TextField/TextField.js +4 -5
  11. package/dist/published/components/core/TextField/TextField.test.js +9 -9
  12. package/dist/published/components/core/Typography/index.js +1 -0
  13. package/dist/published/components/core/index.d.ts +4 -2
  14. package/dist/published/components/custom/BuilderGrid/EmptyContent.d.ts +1 -1
  15. package/dist/published/components/custom/BuilderGrid/EmptyContent.js +1 -0
  16. package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.d.ts +7 -3
  17. package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.js +55 -17
  18. package/dist/published/components/custom/CriteriaBuilder/ValueEditor.js +38 -18
  19. package/dist/published/components/custom/DataGrid/Toolbar.d.ts +2 -1
  20. package/dist/published/components/custom/FormField/AddressFieldComponent/AddressFieldComponent.test.d.ts +1 -0
  21. package/dist/published/components/custom/FormField/AddressFieldComponent/AddressFieldComponent.test.js +89 -0
  22. package/dist/published/components/custom/FormField/AddressFieldComponent/addressFieldComponent.d.ts +13 -1
  23. package/dist/published/components/custom/FormField/AddressFieldComponent/addressFieldComponent.js +8 -13
  24. package/dist/published/components/custom/FormField/BooleanSelect/BooleanSelect.d.ts +3 -1
  25. package/dist/published/components/custom/FormField/BooleanSelect/BooleanSelect.js +2 -3
  26. package/dist/published/components/custom/FormField/BooleanSelect/BooleanSelect.test.d.ts +1 -0
  27. package/dist/published/components/custom/FormField/BooleanSelect/BooleanSelect.test.js +32 -0
  28. package/dist/published/components/custom/FormField/DatePickerSelect/DatePickerSelect.d.ts +3 -1
  29. package/dist/published/components/custom/FormField/DatePickerSelect/DatePickerSelect.js +2 -3
  30. package/dist/published/components/custom/FormField/DatePickerSelect/DatePickerSelect.test.d.ts +1 -0
  31. package/dist/published/components/custom/FormField/DatePickerSelect/DatePickerSelect.test.js +73 -0
  32. package/dist/published/components/custom/FormField/FileUpload/FileUpload.d.ts +3 -1
  33. package/dist/published/components/custom/FormField/FileUpload/FileUpload.js +7 -6
  34. package/dist/published/components/custom/FormField/FormField.d.ts +10 -6
  35. package/dist/published/components/custom/FormField/FormField.js +2 -3
  36. package/dist/published/components/custom/FormField/InputFieldComponent/InputFieldComponent.d.ts +3 -1
  37. package/dist/published/components/custom/FormField/InputFieldComponent/InputFieldComponent.js +3 -5
  38. package/dist/published/components/custom/FormField/InputFieldComponent/InputFieldComponent.test.d.ts +1 -0
  39. package/dist/published/components/custom/FormField/InputFieldComponent/InputFieldComponent.test.js +52 -0
  40. package/dist/published/components/custom/FormField/Select/Select.d.ts +3 -1
  41. package/dist/published/components/custom/FormField/Select/Select.js +6 -5
  42. package/dist/published/components/custom/FormField/Select/Select.test.d.ts +1 -0
  43. package/dist/published/components/custom/FormField/Select/Select.test.js +68 -0
  44. package/dist/published/components/custom/FormField/TimePickerSelect/TimePickerSelect.d.ts +3 -1
  45. package/dist/published/components/custom/FormField/TimePickerSelect/TimePickerSelect.js +7 -6
  46. package/dist/published/components/custom/Menubar/Menubar.d.ts +2 -4
  47. package/dist/published/components/custom/Menubar/Menubar.js +1 -4
  48. package/dist/published/components/custom/MultiSelect/MultiSelect.d.ts +5 -6
  49. package/dist/published/components/custom/MultiSelect/MultiSelect.js +9 -5
  50. package/dist/published/components/custom/MultiSelect/SortableItem.js +1 -0
  51. package/dist/published/components/custom/RepeatableField/RepeatableField.d.ts +2 -3
  52. package/dist/published/components/custom/RepeatableField/RepeatableField.js +2 -2
  53. package/dist/published/components/custom/UserAvatar/UserAvatar.js +5 -3
  54. package/dist/published/components/custom/util.js +2 -1
  55. package/dist/published/icons/custom/Inherited.d.ts +6 -1
  56. package/dist/published/icons/custom/Overrides.d.ts +22 -2
  57. package/dist/published/icons/custom/TrashCan.d.ts +22 -2
  58. package/dist/published/index.d.ts +2 -1
  59. package/dist/published/index.js +2 -3
  60. package/dist/published/stories/Accordion.stories.d.ts +3 -2
  61. package/dist/published/stories/Alert.stories.d.ts +3 -2
  62. package/dist/published/stories/Appbar.stories.js +1 -1
  63. package/dist/published/stories/Autocomplete.stories.d.ts +3 -20
  64. package/dist/published/stories/Autocomplete.stories.js +1 -1
  65. package/dist/published/stories/Avatar.stories.js +1 -1
  66. package/dist/published/stories/Backdrop.stories.d.ts +3 -2
  67. package/dist/published/stories/Backdrop.stories.js +1 -1
  68. package/dist/published/stories/Badge.stories.d.ts +3 -2
  69. package/dist/published/stories/Box.stories.d.ts +2 -2
  70. package/dist/published/stories/Box.stories.js +2 -2
  71. package/dist/published/stories/Breadcrumbs.stories.d.ts +3 -2
  72. package/dist/published/stories/Button.stories.d.ts +3 -2
  73. package/dist/published/stories/ButtonGroup.stories.d.ts +3 -2
  74. package/dist/published/stories/Card.stories.d.ts +3 -2
  75. package/dist/published/stories/Checkbox.stories.d.ts +3 -2
  76. package/dist/published/stories/Chip.stories.d.ts +3 -2
  77. package/dist/published/stories/CircularProgress.stories.d.ts +3 -2
  78. package/dist/published/stories/Collapse.stories.d.ts +3 -2
  79. package/dist/published/stories/Container.stories.d.ts +3 -2
  80. package/dist/published/stories/CriteriaBuilder.stories.d.ts +5 -4
  81. package/dist/published/stories/CriteriaBuilder.stories.js +1 -1
  82. package/dist/published/stories/DataGrid.stories.js +1 -1
  83. package/dist/published/stories/Dialog.stories.d.ts +3 -2
  84. package/dist/published/stories/Dialog.stories.js +3 -3
  85. package/dist/published/stories/Divider.stories.d.ts +3 -2
  86. package/dist/published/stories/Drawer.stories.d.ts +3 -2
  87. package/dist/published/stories/FormControl.stories.d.ts +3 -2
  88. package/dist/published/stories/FormControlLabel.stories.d.ts +3 -2
  89. package/dist/published/stories/FormControlLabel.stories.js +1 -1
  90. package/dist/published/stories/FormField.stories.d.ts +12 -10
  91. package/dist/published/stories/FormGroup.stories.d.ts +3 -2
  92. package/dist/published/stories/FormHelperText.stories.d.ts +3 -2
  93. package/dist/published/stories/FormLabel.stories.d.ts +3 -2
  94. package/dist/published/stories/Grid.stories.d.ts +3 -2
  95. package/dist/published/stories/IconButton.stories.d.ts +3 -2
  96. package/dist/published/stories/LinearProgress.stories.d.ts +3 -2
  97. package/dist/published/stories/Link.stories.d.ts +3 -2
  98. package/dist/published/stories/List.stories.d.ts +3 -2
  99. package/dist/published/stories/List.stories.js +1 -1
  100. package/dist/published/stories/Menu.stories.d.ts +3 -2
  101. package/dist/published/stories/Menu.stories.js +2 -2
  102. package/dist/published/stories/MenuBar.stories.js +2 -1
  103. package/dist/published/stories/Palette.stories.js +1 -1
  104. package/dist/published/stories/Paper.stories.d.ts +3 -2
  105. package/dist/published/stories/RadioGroup.stories.d.ts +3 -2
  106. package/dist/published/stories/Skeleton.stories.d.ts +3 -2
  107. package/dist/published/stories/Stack.stories.d.ts +3 -2
  108. package/dist/published/stories/Stepper.stories.d.ts +3 -2
  109. package/dist/published/stories/Switch.stories.d.ts +3 -2
  110. package/dist/published/stories/Table.stories.d.ts +3 -2
  111. package/dist/published/stories/Tabs.stories.d.ts +3 -2
  112. package/dist/published/stories/TextField.stories.d.ts +4 -3
  113. package/dist/published/stories/TextField.stories.js +2 -2
  114. package/dist/published/stories/TimePicker.stories.js +1 -1
  115. package/dist/published/stories/TimePickerSelect.stories.d.ts +6 -2
  116. package/dist/published/stories/TimePickerSelect.stories.js +2 -1
  117. package/dist/published/stories/ToggleButton.stories.d.ts +3 -2
  118. package/dist/published/stories/ToggleButton.stories.js +4 -4
  119. package/dist/published/stories/Typography.stories.js +1 -1
  120. package/dist/published/theme/UIThemeProvider.d.ts +4 -1
  121. package/dist/published/theme/UIThemeProvider.js +1 -1
  122. package/dist/published/theme/defaultTheme.js +5 -5
  123. package/package.json +31 -14
@@ -0,0 +1,89 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import '@testing-library/jest-dom/extend-expect';
11
+ import React from 'react';
12
+ import { render, screen } from '@testing-library/react';
13
+ import { userEvent } from '@testing-library/user-event';
14
+ import AddressFieldComponent from './addressFieldComponent';
15
+ // Right now an object property is required for this to function, but eventually this should go
16
+ // away.
17
+ const addressProperty = {
18
+ id: 'addressLine1',
19
+ name: 'Line 1',
20
+ type: 'text',
21
+ };
22
+ test('displays matching addresses', () => __awaiter(void 0, void 0, void 0, function* () {
23
+ const user = userEvent.setup();
24
+ const queryAddresses = (search) => __awaiter(void 0, void 0, void 0, function* () {
25
+ return [
26
+ {
27
+ address: {
28
+ line1: '1234 Main Street',
29
+ city: 'Columbia',
30
+ county: 'Howard',
31
+ state: 'Maryland',
32
+ zipCode: '21046',
33
+ },
34
+ },
35
+ {
36
+ address: {
37
+ line1: '12345 Main Avenue',
38
+ city: 'Columbia',
39
+ county: 'Howard',
40
+ state: 'Maryland',
41
+ zipCode: '21046',
42
+ },
43
+ },
44
+ ];
45
+ });
46
+ render(React.createElement(AddressFieldComponent, { id: "addressSearch", property: addressProperty, onChange: () => { }, queryAddresses: queryAddresses }));
47
+ const addressField = screen.getByRole('searchbox');
48
+ yield user.type(addressField, '1234 Main');
49
+ yield screen.findByRole('menuitem', { name: /1234 Main Street/ });
50
+ yield screen.findByRole('menuitem', { name: /12345 Main Avenue/ });
51
+ }));
52
+ test('returns manually typed address', () => __awaiter(void 0, void 0, void 0, function* () {
53
+ const user = userEvent.setup();
54
+ const onChangeMock = jest.fn((name, value, property, unused) => { });
55
+ render(React.createElement(AddressFieldComponent, { id: "addressSearch", property: addressProperty, onChange: onChangeMock }));
56
+ const addressField = screen.getByRole('searchbox');
57
+ yield user.type(addressField, '1234 Main St');
58
+ expect(onChangeMock).toBeCalledTimes(12);
59
+ expect(onChangeMock).lastCalledWith('addressLine1', '1234 Main St', addressProperty, undefined);
60
+ }));
61
+ test('returns selected search result', () => __awaiter(void 0, void 0, void 0, function* () {
62
+ const user = userEvent.setup();
63
+ const onChangeMock = jest.fn((name, value, property, unused) => { });
64
+ const queryAddresses = (search) => __awaiter(void 0, void 0, void 0, function* () {
65
+ return [
66
+ {
67
+ address: {
68
+ line1: '1234 Main Street',
69
+ city: 'Columbia',
70
+ county: 'Howard',
71
+ state: 'Maryland',
72
+ zipCode: '21046',
73
+ },
74
+ },
75
+ ];
76
+ });
77
+ render(React.createElement(AddressFieldComponent, { id: "addressSearch", property: addressProperty, onChange: onChangeMock, queryAddresses: queryAddresses }));
78
+ const addressField = screen.getByRole('searchbox');
79
+ yield user.type(addressField, '1234 Main');
80
+ const searchResult = yield screen.findByRole('menuitem', { name: /1234 Main Street/ });
81
+ yield user.click(searchResult);
82
+ expect(onChangeMock).lastCalledWith('addressLine1', {
83
+ line1: '1234 Main Street',
84
+ city: 'Columbia',
85
+ county: 'Howard',
86
+ state: 'Maryland',
87
+ zipCode: '21046',
88
+ }, addressProperty, undefined);
89
+ }));
@@ -1,4 +1,16 @@
1
1
  /// <reference types="react" />
2
2
  import { FormFieldProps } from '../FormField';
3
- declare const AddressFieldComponent: (props: FormFieldProps) => JSX.Element;
3
+ export declare type Address = {
4
+ address: {
5
+ line1?: string;
6
+ line2?: string;
7
+ city?: string;
8
+ county?: string;
9
+ state?: string;
10
+ zipCode?: string;
11
+ };
12
+ };
13
+ declare const AddressFieldComponent: (props: FormFieldProps & {
14
+ id: string;
15
+ }) => JSX.Element;
4
16
  export default AddressFieldComponent;
@@ -2,19 +2,19 @@ import { Popover } from '@mui/material';
2
2
  import React, { useEffect, useState } from 'react';
3
3
  import InputMask from 'react-input-mask';
4
4
  import { CancelOutlined } from '@mui/icons-material';
5
- import { Button, List, ListItem, TextField, Typography } from '../../../core';
5
+ import { Button, List, ListItem, MenuItem, TextField, Typography } from '../../../core';
6
6
  import { Box } from '../../../layout';
7
7
  const AddressFieldComponent = (props) => {
8
- const { property, defaultValue, error, errorMessage, onBlur, readOnly, required, size, placeholder, mask, isMultiLineText, rows, inputMaskPlaceholderChar, queryAddresses, } = props;
8
+ const { id, property, defaultValue, error, errorMessage, onBlur, readOnly, required, size, placeholder, mask, isMultiLineText, rows, inputMaskPlaceholderChar, queryAddresses, } = props;
9
9
  const [value, setValue] = useState(defaultValue !== null && defaultValue !== void 0 ? defaultValue : '');
10
10
  const [selectOptions, setSelectOptions] = useState([]);
11
11
  const [anchorEl, setAnchorEl] = React.useState(null);
12
- const id = property.id;
13
12
  const open = Boolean(anchorEl);
14
13
  const popoverId = open ? `${id}-popover` : undefined;
15
14
  useEffect(() => {
16
15
  setValue(defaultValue !== null && defaultValue !== void 0 ? defaultValue : '');
17
16
  }, [defaultValue]);
17
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
18
18
  const handleChange = (e) => {
19
19
  setAnchorEl(e.currentTarget);
20
20
  const inputValue = e.target.value || '';
@@ -45,18 +45,18 @@ const AddressFieldComponent = (props) => {
45
45
  return { label, sublabel, value: address.address };
46
46
  }));
47
47
  });
48
- props.onChange(id, inputValue, property, undefined);
48
+ props.onChange(property.id, inputValue, property, undefined);
49
49
  };
50
50
  const handleClick = (option) => {
51
51
  setAnchorEl(null);
52
52
  setValue(option.value.line1);
53
- props.onChange(id, option.value, property, undefined);
53
+ props.onChange(property.id, option.value, property, undefined);
54
54
  };
55
55
  const handleClose = () => {
56
56
  setAnchorEl(null);
57
57
  };
58
58
  return (React.createElement(Box, null,
59
- !mask ? (React.createElement(TextField, { id: id, "aria-describedby": popoverId, onChange: !readOnly ? handleChange : undefined, error: error, errorMessage: errorMessage, value: value, fullWidth: true, onBlur: onBlur, size: size !== null && size !== void 0 ? size : 'medium', placeholder: placeholder, InputProps: {
59
+ !mask ? (React.createElement(TextField, { id: id, onChange: !readOnly ? handleChange : undefined, error: error, errorMessage: errorMessage, value: value, fullWidth: true, onBlur: onBlur, size: size !== null && size !== void 0 ? size : 'medium', placeholder: placeholder, InputProps: {
60
60
  type: 'search',
61
61
  autoComplete: 'off',
62
62
  }, required: required, readOnly: readOnly, multiline: property.type === 'string' && !readOnly && isMultiLineText, rows: isMultiLineText ? (rows ? rows : 3) : undefined })) : (React.createElement(InputMask, { mask: mask, maskChar: inputMaskPlaceholderChar !== null && inputMaskPlaceholderChar !== void 0 ? inputMaskPlaceholderChar : '_', value: value, onChange: !readOnly ? handleChange : undefined, onBlur: onBlur, alwaysShowMask: true }, () => (React.createElement(TextField, { id: id, sx: readOnly
@@ -70,7 +70,7 @@ const AddressFieldComponent = (props) => {
70
70
  },
71
71
  }
72
72
  : undefined, required: required, error: error, errorMessage: errorMessage, InputProps: { readOnly: readOnly }, fullWidth: true, size: size !== null && size !== void 0 ? size : 'medium', type: 'text', multiline: property.type === 'string' && !readOnly && isMultiLineText, rows: isMultiLineText ? (rows ? rows : 3) : undefined, value: value })))),
73
- !readOnly && (React.createElement(Popover, { id: popoverId, open: open, anchorEl: anchorEl, onClose: handleClose, disableAutoFocus: true, marginThreshold: null, anchorOrigin: {
73
+ !readOnly && (React.createElement(Popover, { id: popoverId, open: open, anchorEl: anchorEl, onClose: handleClose, disableAutoFocus: true, marginThreshold: undefined, anchorOrigin: {
74
74
  vertical: 'bottom',
75
75
  horizontal: 'left',
76
76
  }, transformOrigin: {
@@ -87,12 +87,7 @@ const AddressFieldComponent = (props) => {
87
87
  } },
88
88
  React.createElement(List, null,
89
89
  selectOptions.map((option) => {
90
- return (React.createElement(ListItem, { onClick: () => handleClick(option), sx: {
91
- '&:hover': {
92
- cursor: 'pointer',
93
- backgroundColor: 'rgba(0, 0, 0, 0.04)',
94
- },
95
- } },
90
+ return (React.createElement(MenuItem, { key: option.label + option.sublabel, onClick: () => handleClick(option) },
96
91
  React.createElement(Box, { sx: {
97
92
  flexGrow: 1,
98
93
  } },
@@ -1,4 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import { FormFieldProps } from '../FormField';
3
- declare const BooleanSelect: (props: FormFieldProps) => JSX.Element;
3
+ declare const BooleanSelect: (props: FormFieldProps & {
4
+ id: string;
5
+ }) => JSX.Element;
4
6
  export default BooleanSelect;
@@ -2,15 +2,14 @@ import React, { useEffect, useState } from 'react';
2
2
  import { Autocomplete, TextField } from '../../../core';
3
3
  import InputFieldComponent from '../InputFieldComponent/InputFieldComponent';
4
4
  const BooleanSelect = (props) => {
5
- const { property, defaultValue, error, errorMessage, readOnly, size, placeholder, onBlur } = props;
5
+ const { id, property, defaultValue, error, errorMessage, readOnly, size, placeholder, onBlur } = props;
6
6
  const [value, setValue] = useState(defaultValue);
7
- const id = property.id;
8
7
  useEffect(() => {
9
8
  setValue(defaultValue);
10
9
  }, [defaultValue]);
11
10
  const handleChange = (event, selected) => {
12
11
  setValue(selected.label);
13
- props.onChange(id, selected.label, property);
12
+ props.onChange(property.id, selected.label, property);
14
13
  };
15
14
  const booleanOptions = [
16
15
  {
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom/extend-expect';
@@ -0,0 +1,32 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import '@testing-library/jest-dom/extend-expect';
11
+ import React from 'react';
12
+ import { render, screen } from '@testing-library/react';
13
+ import { userEvent } from '@testing-library/user-event';
14
+ import BooleanSelect from './BooleanSelect';
15
+ // Right now an object property is required for this to function, but eventually this should go
16
+ // away.
17
+ const booleanProperty = {
18
+ id: 'theQuestion',
19
+ name: 'Question',
20
+ type: 'boolean',
21
+ };
22
+ test('returns selected option', () => __awaiter(void 0, void 0, void 0, function* () {
23
+ const user = userEvent.setup();
24
+ const onChangeMock = jest.fn((name, value, property) => { });
25
+ render(React.createElement(BooleanSelect, { id: "chooseYesOrNo", property: booleanProperty, onChange: onChangeMock }));
26
+ const inputField = screen.getByRole('combobox');
27
+ yield user.click(inputField);
28
+ const yesOption = yield screen.findByRole('option', { name: 'Yes' });
29
+ yield user.click(yesOption);
30
+ expect(onChangeMock).toBeCalledWith('theQuestion', 'Yes', // ?? why not true/false?
31
+ booleanProperty);
32
+ }));
@@ -1,4 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import { FormFieldProps } from '../FormField';
3
- declare const DatePickerSelect: (props: FormFieldProps) => JSX.Element;
3
+ declare const DatePickerSelect: (props: FormFieldProps & {
4
+ id: string;
5
+ }) => JSX.Element;
4
6
  export default DatePickerSelect;
@@ -26,15 +26,14 @@ const asMonthDayYearFormat = (date) => {
26
26
  }
27
27
  };
28
28
  const DatePickerSelect = (props) => {
29
- const { property, defaultValue, error, errorMessage, readOnly, required, size, onBlur } = props;
29
+ const { id, property, defaultValue, error, errorMessage, readOnly, required, size, onBlur } = props;
30
30
  const [value, setValue] = useState(asCalendarDate(defaultValue));
31
- const id = property.id;
32
31
  useEffect(() => {
33
32
  setValue(asCalendarDate(defaultValue));
34
33
  }, [defaultValue]);
35
34
  const handleChange = (date) => {
36
35
  setValue(date);
37
- props.onChange(id, date, property);
36
+ props.onChange(property.id, date, property);
38
37
  };
39
38
  return readOnly ? (React.createElement(InputFieldComponent, Object.assign({}, Object.assign(Object.assign({}, props), { defaultValue: asMonthDayYearFormat(value) })))) : (React.createElement(LocalizationProvider, null,
40
39
  React.createElement(DatePicker, { value: value, onChange: handleChange, inputFormat: "MM/dd/yyyy", renderInput: (params) => (React.createElement(TextField, Object.assign({}, params, { id: id, error: error, errorMessage: errorMessage, onBlur: onBlur, fullWidth: true, required: required, sx: { background: 'white', borderRadius: '8px' }, size: size !== null && size !== void 0 ? size : 'medium' }))) })));
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom/extend-expect';
@@ -0,0 +1,73 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import '@testing-library/jest-dom/extend-expect';
11
+ import React from 'react';
12
+ import { render, screen, within } from '@testing-library/react';
13
+ import { userEvent } from '@testing-library/user-event';
14
+ import DatePickerSelect from './DatePickerSelect';
15
+ import { LocalDate, Month } from '@js-joda/core';
16
+ import { InvalidDate } from '../../../../util';
17
+ // Right now an object property is required for this to function, but eventually this should go
18
+ // away.
19
+ const dateProperty = {
20
+ id: 'testDate',
21
+ name: 'Date',
22
+ type: 'date',
23
+ };
24
+ beforeAll(() => {
25
+ // Set specific date for a repeatable test.
26
+ jest.useFakeTimers({
27
+ now: new Date('2024-02-11'),
28
+ // Only want to set current time, don't override timer functions as that will
29
+ // confuse @testing-library.
30
+ doNotFake: [
31
+ 'setImmediate',
32
+ 'clearImmediate',
33
+ 'setTimeout',
34
+ 'clearTimeout',
35
+ 'setInterval',
36
+ 'clearInterval',
37
+ 'nextTick',
38
+ 'queueMicrotask',
39
+ ],
40
+ });
41
+ });
42
+ afterAll(() => {
43
+ jest.useRealTimers();
44
+ });
45
+ test('returns selected date', () => __awaiter(void 0, void 0, void 0, function* () {
46
+ const user = userEvent.setup();
47
+ const onChangeMock = jest.fn((name, value, property) => { });
48
+ render(React.createElement(DatePickerSelect, { id: "pickDate", property: dateProperty, onChange: onChangeMock }));
49
+ const calendarIcon = screen.getByRole('button', { name: /Choose date/i });
50
+ yield user.click(calendarIcon);
51
+ const calendar = yield screen.findByRole('dialog');
52
+ const feb29 = yield within(calendar).findByRole('gridcell', { name: '29' });
53
+ yield user.click(feb29);
54
+ expect(onChangeMock).toBeCalledWith('testDate', LocalDate.of(2024, Month.FEBRUARY, 29), dateProperty);
55
+ }));
56
+ test('returns manually entered date', () => __awaiter(void 0, void 0, void 0, function* () {
57
+ const user = userEvent.setup();
58
+ const onChangeMock = jest.fn((name, value, property) => { });
59
+ render(React.createElement(DatePickerSelect, { id: "pickDate", property: dateProperty, onChange: onChangeMock }));
60
+ const input = screen.getByRole('textbox');
61
+ yield user.type(input, '03/27/2024');
62
+ expect(onChangeMock).toBeCalledTimes(8); // component ignores '/', i.e. input could also have been '03272024'
63
+ expect(onChangeMock).lastCalledWith('testDate', LocalDate.of(2024, Month.MARCH, 27), dateProperty);
64
+ }));
65
+ test('returns incomplete dates', () => __awaiter(void 0, void 0, void 0, function* () {
66
+ const user = userEvent.setup();
67
+ const onChangeMock = jest.fn((name, value, property) => { });
68
+ render(React.createElement(DatePickerSelect, { id: "pickDate", property: dateProperty, onChange: onChangeMock }));
69
+ const input = screen.getByRole('textbox');
70
+ yield user.type(input, '08/20');
71
+ // Component automatically appends '/' as needed.
72
+ expect(onChangeMock).lastCalledWith('testDate', new InvalidDate('08/20/'), dateProperty);
73
+ }));
@@ -1,4 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import { FormFieldProps } from '../FormField';
3
- declare const FileUploadControl: (props: FormFieldProps) => JSX.Element;
3
+ declare const FileUploadControl: (props: FormFieldProps & {
4
+ id: string;
5
+ }) => JSX.Element;
4
6
  export default FileUploadControl;
@@ -5,8 +5,7 @@ import { Button, TextField } from '../../../core';
5
5
  const FileUploadControl = (props) => {
6
6
  var _a;
7
7
  const [uploadedFile, setUploadedFile] = useState(undefined);
8
- const { property, required, error, errorMessage } = props;
9
- const id = property.id;
8
+ const { id, property, required, error, errorMessage } = props;
10
9
  const styles = {
11
10
  button: {
12
11
  textTransform: 'initial',
@@ -32,16 +31,18 @@ const FileUploadControl = (props) => {
32
31
  };
33
32
  useEffect(() => {
34
33
  if (uploadedFile) {
35
- props.onChange(id, uploadedFile, property);
34
+ props.onChange(property.id, uploadedFile, property);
36
35
  }
37
36
  }, [uploadedFile]);
38
37
  const handleSelectFile = () => {
39
38
  if (uploadedFile) {
40
39
  setUploadedFile(undefined);
41
- props.onChange(id, undefined, property);
40
+ props.onChange(property.id, undefined, property);
42
41
  }
43
42
  };
44
- const onDrop = useCallback((acceptedFile) => {
43
+ const onDrop = useCallback(
44
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
+ (acceptedFile) => {
45
46
  setUploadedFile(acceptedFile[0]);
46
47
  }, [setUploadedFile]);
47
48
  const { getRootProps, getInputProps, isDragActive } = useDropzone({
@@ -58,7 +59,7 @@ const FileUploadControl = (props) => {
58
59
  })),
59
60
  React.createElement(Grid, { item: true, flexGrow: 1 },
60
61
  React.createElement("input", Object.assign({ disabled: true }, getInputProps())),
61
- React.createElement(TextField, { sx: { '& fieldset': { border: 'none' } }, fullWidth: true, value: (_a = uploadedFile === null || uploadedFile === void 0 ? void 0 : uploadedFile.name) !== null && _a !== void 0 ? _a : (isDragActive ? 'Drop your file here' : 'File'), error: error, errorMessage: errorMessage, required: required })),
62
+ React.createElement(TextField, { id: id, sx: { '& fieldset': { border: 'none' } }, fullWidth: true, value: (_a = uploadedFile === null || uploadedFile === void 0 ? void 0 : uploadedFile.name) !== null && _a !== void 0 ? _a : (isDragActive ? 'Drop your file here' : 'File'), error: error, errorMessage: errorMessage, required: required })),
62
63
  React.createElement(Grid, { item: true },
63
64
  React.createElement(Button, { sx: Object.assign(Object.assign({}, styles.button), styles.selectFileBtn), onClick: () => handleSelectFile() }, uploadedFile ? 'Remove' : 'Select File'))));
64
65
  };
@@ -1,8 +1,12 @@
1
+ import React from 'react';
2
+ import { Address } from './AddressFieldComponent/addressFieldComponent';
1
3
  import { ObjectProperty } from '../../../types';
4
+ import { AutocompleteOption } from '../../core';
2
5
  export declare type FormFieldProps = {
6
+ id?: string;
3
7
  property: ObjectProperty;
4
8
  onChange: Function;
5
- onBlur?: Function;
9
+ onBlur?: React.FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>;
6
10
  defaultValue?: unknown;
7
11
  error?: boolean;
8
12
  errorMessage?: string;
@@ -18,11 +22,11 @@ export declare type FormFieldProps = {
18
22
  isMultiLineText?: boolean;
19
23
  rows?: number;
20
24
  inputMaskPlaceholderChar?: string;
21
- queryAddresses?: Function;
22
- isOptionEqualToValue?: Function;
23
- renderOption?: Function;
24
- getOptionLabel?: Function;
25
+ queryAddresses?: (input: string) => Promise<Address[]>;
26
+ isOptionEqualToValue?: (option: AutocompleteOption | string, value: unknown) => boolean;
27
+ renderOption?: (props: unknown, option: AutocompleteOption | string, state: unknown) => React.ReactNode;
28
+ getOptionLabel?: (option: AutocompleteOption) => string;
25
29
  disableCloseOnSelect?: boolean;
26
30
  };
27
- declare const FormField: (props: FormFieldProps) => any;
31
+ declare const FormField: (props: FormFieldProps) => JSX.Element;
28
32
  export default FormField;
@@ -7,11 +7,10 @@ import InputFieldComponent from './InputFieldComponent/InputFieldComponent';
7
7
  import Select from './Select/Select';
8
8
  import TimePickerSelect from './TimePickerSelect/TimePickerSelect';
9
9
  const FormField = (props) => {
10
- const { defaultValue, error, onChange, property, readOnly, selectOptions, required, size, placeholder, errorMessage, onBlur, mask, max, min, isMultiLineText, rows, inputMaskPlaceholderChar, queryAddresses, isOptionEqualToValue, renderOption, disableCloseOnSelect, getOptionLabel } = props;
11
- const id = property.id;
10
+ const { id, defaultValue, error, onChange, property, readOnly, selectOptions, required, size, placeholder, errorMessage, onBlur, mask, max, min, isMultiLineText, rows, inputMaskPlaceholderChar, queryAddresses, isOptionEqualToValue, renderOption, disableCloseOnSelect, getOptionLabel, } = props;
12
11
  let control;
13
12
  const commonProps = {
14
- id,
13
+ id: id !== null && id !== void 0 ? id : property.id,
15
14
  property,
16
15
  onChange,
17
16
  onBlur,
@@ -1,5 +1,7 @@
1
1
  import { FunctionComponent } from 'react';
2
2
  import { FormFieldProps } from '../FormField';
3
3
  export declare const NumericFormat: FunctionComponent<any>;
4
- declare const InputFieldComponent: (props: FormFieldProps) => JSX.Element;
4
+ declare const InputFieldComponent: (props: FormFieldProps & {
5
+ id: string;
6
+ }) => JSX.Element;
5
7
  export default InputFieldComponent;
@@ -15,7 +15,6 @@ import { Autocomplete, TextField } from '../../../core';
15
15
  import InputMask from 'react-input-mask';
16
16
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
17
  export const NumericFormat = (props) => {
18
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
19
18
  const { inputRef, onChange, defaultValue } = props, other = __rest(props, ["inputRef", "onChange", "defaultValue"]);
20
19
  return (React.createElement(NumberFormat, Object.assign({}, other, { getInputRef: inputRef, onValueChange: (values) => {
21
20
  onChange === null || onChange === void 0 ? void 0 : onChange({
@@ -27,10 +26,9 @@ export const NumericFormat = (props) => {
27
26
  };
28
27
  const InputFieldComponent = (props) => {
29
28
  var _a;
30
- const { property, defaultValue, error, errorMessage, onBlur, readOnly, required, size, placeholder, mask, min, max, isMultiLineText, rows, inputMaskPlaceholderChar, } = props;
29
+ const { id, property, defaultValue, error, errorMessage, onBlur, readOnly, required, size, placeholder, mask, min, max, isMultiLineText, rows, inputMaskPlaceholderChar, } = props;
31
30
  const [value, setValue] = useState(defaultValue !== null && defaultValue !== void 0 ? defaultValue : '');
32
31
  const [inputValue, setInputValue] = useState('');
33
- const id = property.id;
34
32
  useEffect(() => {
35
33
  setValue(defaultValue !== null && defaultValue !== void 0 ? defaultValue : '');
36
34
  }, [defaultValue]);
@@ -39,11 +37,11 @@ const InputFieldComponent = (props) => {
39
37
  ? parseInt(e.target.value, 10)
40
38
  : e.target.value;
41
39
  setValue(inputValue);
42
- props.onChange(id, inputValue, property);
40
+ props.onChange(property.id, inputValue, property);
43
41
  };
44
42
  const handleSelectChange = (e, selected) => {
45
43
  setValue(selected.label);
46
- props.onChange(id, selected.label, property);
44
+ props.onChange(property.id, selected.label, property);
47
45
  };
48
46
  const handleInputValueChange = (event, selectValue) => {
49
47
  setInputValue(selectValue);
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom/extend-expect';
@@ -0,0 +1,52 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import '@testing-library/jest-dom/extend-expect';
11
+ import React from 'react';
12
+ import { render, screen } from '@testing-library/react';
13
+ import { userEvent } from '@testing-library/user-event';
14
+ import InputField from './InputFieldComponent';
15
+ describe('Free-text input', () => {
16
+ // Right now an object property is required for this to function, but eventually this should go
17
+ // away.
18
+ const textProperty = {
19
+ id: 'inputField',
20
+ name: 'Input Field',
21
+ type: 'string',
22
+ };
23
+ test('returns entered value', () => __awaiter(void 0, void 0, void 0, function* () {
24
+ const user = userEvent.setup();
25
+ const onChangeMock = jest.fn((name, value, property) => { });
26
+ render(React.createElement(InputField, { id: "testInput", property: textProperty, onChange: onChangeMock }));
27
+ const input = screen.getByRole('textbox');
28
+ yield user.type(input, 'test value');
29
+ expect(onChangeMock).toBeCalledTimes(10);
30
+ expect(onChangeMock).lastCalledWith('inputField', 'test value', textProperty);
31
+ }));
32
+ });
33
+ describe('Autocomplete', () => {
34
+ // Right now an object property is required for this to function, but eventually this should go
35
+ // away.
36
+ const enumProperty = {
37
+ id: 'enumField',
38
+ name: 'Enum Field',
39
+ type: 'string',
40
+ enum: ['option 1', 'option 2'],
41
+ };
42
+ test('returns selected value', () => __awaiter(void 0, void 0, void 0, function* () {
43
+ const user = userEvent.setup();
44
+ const onChangeMock = jest.fn((name, value, property) => { });
45
+ render(React.createElement(InputField, { id: "testInput", property: enumProperty, onChange: onChangeMock }));
46
+ const input = screen.getByRole('combobox');
47
+ yield user.click(input);
48
+ const option2 = yield screen.findByRole('option', { name: 'option 2' });
49
+ yield user.click(option2);
50
+ expect(onChangeMock).toBeCalledWith('enumField', 'option 2', enumProperty);
51
+ }));
52
+ });
@@ -1,4 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import { FormFieldProps } from '../FormField';
3
- declare const Select: (props: FormFieldProps) => JSX.Element;
3
+ declare const Select: (props: FormFieldProps & {
4
+ id: string;
5
+ }) => JSX.Element;
4
6
  export default Select;
@@ -3,23 +3,24 @@ import { Autocomplete, TextField } from '../../../core';
3
3
  import InputFieldComponent from '../InputFieldComponent/InputFieldComponent';
4
4
  const Select = (props) => {
5
5
  var _a, _b;
6
- const { property, defaultValue, error, errorMessage, onBlur, readOnly, selectOptions, required, size, isOptionEqualToValue, renderOption, getOptionLabel, disableCloseOnSelect, } = props;
6
+ const { id, property, defaultValue, error, errorMessage, onBlur, readOnly, selectOptions, required, size, isOptionEqualToValue, renderOption, getOptionLabel, disableCloseOnSelect, } = props;
7
7
  const [value, setValue] = useState(defaultValue);
8
8
  const [inputValue, setInputValue] = useState('');
9
9
  useEffect(() => {
10
10
  setValue(defaultValue);
11
11
  }, [defaultValue]);
12
- const id = property.id;
12
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
13
  const handleChange = (event, selected) => {
14
14
  if (Array.isArray(selected)) {
15
15
  setValue(selected.map((option) => { var _a; return (_a = option.value) !== null && _a !== void 0 ? _a : option; }));
16
- props.onChange(id, selected.map((option) => { var _a; return (_a = option.value) !== null && _a !== void 0 ? _a : option; }), property);
16
+ props.onChange(property.id, selected.map((option) => { var _a; return (_a = option.value) !== null && _a !== void 0 ? _a : option; }), property);
17
17
  }
18
18
  else {
19
19
  setValue(selected);
20
- props.onChange(id, selected, property);
20
+ props.onChange(property.id, selected, property);
21
21
  }
22
22
  };
23
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
24
  const handleInputValueChange = (event, selectValue) => {
24
25
  if (Array.isArray(selectValue)) {
25
26
  setValue(selectValue.map((item) => { var _a; return (_a = item.value) !== null && _a !== void 0 ? _a : item; }));
@@ -28,7 +29,7 @@ const Select = (props) => {
28
29
  setInputValue(selectValue);
29
30
  }
30
31
  };
31
- return readOnly ? (React.createElement(InputFieldComponent, Object.assign({}, props))) : (React.createElement(Autocomplete, { multiple: (property === null || property === void 0 ? void 0 : property.type) === 'array' ? true : false, id: id, renderInput: (params) => React.createElement(TextField, Object.assign({}, params, { value: value, fullWidth: true, onBlur: onBlur })), value: value !== null && value !== void 0 ? value : ((property === null || property === void 0 ? void 0 : property.type) === 'array' ? [] : undefined), onChange: handleChange, options: (_b = (_a = selectOptions) !== null && _a !== void 0 ? _a : property === null || property === void 0 ? void 0 : property.enum) !== null && _b !== void 0 ? _b : [], disableClearable: true, inputValue: inputValue !== null && inputValue !== void 0 ? inputValue : '', error: error, errorMessage: errorMessage, required: required, onInputChange: handleInputValueChange, size: size, isOptionEqualToValue: isOptionEqualToValue
32
+ return readOnly ? (React.createElement(InputFieldComponent, Object.assign({}, props))) : (React.createElement(Autocomplete, { multiple: (property === null || property === void 0 ? void 0 : property.type) === 'array' ? true : false, id: id, renderInput: (params) => (React.createElement(TextField, Object.assign({}, params, { value: value, fullWidth: true, onBlur: onBlur }))), value: value !== null && value !== void 0 ? value : ((property === null || property === void 0 ? void 0 : property.type) === 'array' ? [] : undefined), onChange: handleChange, options: (_b = (_a = selectOptions) !== null && _a !== void 0 ? _a : property === null || property === void 0 ? void 0 : property.enum) !== null && _b !== void 0 ? _b : [], disableClearable: true, inputValue: inputValue !== null && inputValue !== void 0 ? inputValue : '', error: error, errorMessage: errorMessage, required: required, onInputChange: handleInputValueChange, size: size, isOptionEqualToValue: isOptionEqualToValue
32
33
  ? (option, value) => isOptionEqualToValue(option, value)
33
34
  : undefined, getOptionLabel: getOptionLabel ? (option) => getOptionLabel(option) : undefined, renderOption: renderOption
34
35
  ? (props, option, state) => renderOption(props, option, state)
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom/extend-expect';