orc-shared 5.10.0-dev.2 → 5.10.0-dev.21

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 (186) hide show
  1. package/dist/actions/metadata.js +30 -11
  2. package/dist/actions/requestsApi.js +10 -1
  3. package/dist/components/AppFrame/About.js +136 -100
  4. package/dist/components/AppFrame/Anchor.js +45 -21
  5. package/dist/components/AppFrame/AppFrame.js +53 -31
  6. package/dist/components/AppFrame/Help.js +35 -15
  7. package/dist/components/AppFrame/MenuItem.js +148 -114
  8. package/dist/components/AppFrame/Preferences.js +136 -97
  9. package/dist/components/AppFrame/Sidebar.js +51 -28
  10. package/dist/components/AppFrame/Topbar.js +61 -36
  11. package/dist/components/ColumnWrapper.js +28 -5
  12. package/dist/components/Culture.js +33 -14
  13. package/dist/components/DropMenu/Menu.js +79 -45
  14. package/dist/components/DropMenu/index.js +34 -29
  15. package/dist/components/Form/Combination.js +45 -16
  16. package/dist/components/Form/Field.js +57 -38
  17. package/dist/components/Form/FieldElements.js +0 -11
  18. package/dist/components/Form/Fieldset.js +47 -19
  19. package/dist/components/Form/Form.js +22 -9
  20. package/dist/components/Form/FormElement.js +40 -7
  21. package/dist/components/Form/Inputs/Button.js +63 -18
  22. package/dist/components/Form/Inputs/ReadOnly.js +50 -27
  23. package/dist/components/{AppFrame/ApplicationSelector/Header.js → Form/Inputs/Selector.js} +30 -31
  24. package/dist/components/Form/Inputs/Text.js +20 -37
  25. package/dist/components/Form/Inputs/Toggles.js +39 -40
  26. package/dist/components/Form/Inputs/index.js +2 -13
  27. package/dist/components/MaterialUI/DataDisplay/PredefinedElements/Placeholder.js +31 -11
  28. package/dist/components/MaterialUI/DataDisplay/PredefinedElements/SectionToolbar.js +89 -0
  29. package/dist/components/MaterialUI/DataDisplay/Table.js +109 -18
  30. package/dist/components/MaterialUI/DataDisplay/TableProps.js +5 -1
  31. package/dist/components/MaterialUI/DataDisplay/TableWithInMemoryPaging.js +198 -0
  32. package/dist/components/MaterialUI/DataDisplay/TooltippedElements/MultipleLinesText.js +4 -1
  33. package/dist/components/MaterialUI/Inputs/DatePicker.js +14 -14
  34. package/dist/components/MaterialUI/Inputs/PredefinedElements/SearchControl.js +1 -0
  35. package/dist/components/MaterialUI/Inputs/Select.js +2 -0
  36. package/dist/components/MaterialUI/Inputs/SelectProps.js +2 -0
  37. package/dist/components/MaterialUI/Inputs/Switch.js +17 -1
  38. package/dist/components/MaterialUI/Inputs/SwitchProps.js +2 -0
  39. package/dist/components/MaterialUI/Inputs/TimePicker.js +14 -21
  40. package/dist/components/MaterialUI/hocs/withDeferredTooltip.js +3 -1
  41. package/dist/components/MaterialUI/muiThemes.js +2 -1
  42. package/dist/components/Provision.js +1 -1
  43. package/dist/constants.js +2 -1
  44. package/dist/content/iconsSheet.svg +740 -116
  45. package/dist/hocs/withScrollBox.js +27 -12
  46. package/dist/hooks/useDaysAndMonthsLocalization.js +77 -0
  47. package/dist/hooks/useInMemoryPaging.js +135 -0
  48. package/dist/hooks/useMultipleFieldEditState.js +12 -3
  49. package/dist/reducers/metadata.js +6 -0
  50. package/dist/schemas/metadata.js +9 -1
  51. package/dist/selectors/locale.js +1 -0
  52. package/dist/selectors/metadata.js +14 -11
  53. package/dist/sharedMessages.js +184 -0
  54. package/dist/utils/ListHelper.js +271 -0
  55. package/dist/utils/comparisonHelper.js +185 -0
  56. package/dist/utils/propertyBagHelper.js +3 -1
  57. package/dist/utils/timezoneHelper.js +18 -31
  58. package/package.json +4 -3
  59. package/src/actions/metadata.js +11 -0
  60. package/src/actions/metadata.test.js +27 -0
  61. package/src/actions/requestsApi.js +6 -0
  62. package/src/components/AppFrame/About.js +97 -117
  63. package/src/components/AppFrame/About.test.js +128 -90
  64. package/src/components/AppFrame/Anchor.js +34 -36
  65. package/src/components/AppFrame/Anchor.test.js +5 -68
  66. package/src/components/AppFrame/AppFrame.js +31 -40
  67. package/src/components/AppFrame/AppFrame.test.js +424 -445
  68. package/src/components/AppFrame/Help.js +23 -20
  69. package/src/components/AppFrame/Help.test.js +3 -3
  70. package/src/components/AppFrame/MenuItem.js +106 -126
  71. package/src/components/AppFrame/MenuItem.test.js +78 -169
  72. package/src/components/AppFrame/Preferences.js +110 -98
  73. package/src/components/AppFrame/Preferences.test.js +115 -219
  74. package/src/components/AppFrame/Sidebar.js +39 -41
  75. package/src/components/AppFrame/Sidebar.test.js +88 -168
  76. package/src/components/AppFrame/Topbar.js +59 -52
  77. package/src/components/AppFrame/Topbar.test.js +31 -39
  78. package/src/components/ColumnWrapper.js +18 -9
  79. package/src/components/Culture.js +20 -10
  80. package/src/components/Culture.test.js +27 -16
  81. package/src/components/DropMenu/DropMenu.test.js +185 -224
  82. package/src/components/DropMenu/Menu.js +73 -80
  83. package/src/components/DropMenu/Menu.test.js +35 -86
  84. package/src/components/DropMenu/index.js +19 -15
  85. package/src/components/Form/Combination.js +35 -28
  86. package/src/components/Form/Combination.test.js +6 -19
  87. package/src/components/Form/Field.js +53 -66
  88. package/src/components/Form/Field.test.js +29 -51
  89. package/src/components/Form/FieldElements.js +0 -14
  90. package/src/components/Form/FieldElements.test.js +104 -111
  91. package/src/components/Form/Fieldset.js +42 -37
  92. package/src/components/Form/Fieldset.test.js +14 -7
  93. package/src/components/Form/Form.js +11 -7
  94. package/src/components/Form/Form.test.js +75 -56
  95. package/src/components/Form/FormElement.js +24 -16
  96. package/src/components/Form/InputField.test.js +24 -30
  97. package/src/components/Form/Inputs/Button.js +58 -14
  98. package/src/components/Form/Inputs/Button.test.js +32 -7
  99. package/src/components/Form/Inputs/Inputs.test.js +0 -7
  100. package/src/components/Form/Inputs/ReadOnly.js +34 -28
  101. package/src/components/Form/Inputs/ReadOnly.test.js +45 -7
  102. package/src/components/Form/Inputs/Selector.js +22 -0
  103. package/src/components/Form/Inputs/Selector.test.js +105 -0
  104. package/src/components/Form/Inputs/Text.js +15 -44
  105. package/src/components/Form/Inputs/Text.test.js +20 -29
  106. package/src/components/Form/Inputs/Toggles.js +27 -26
  107. package/src/components/Form/Inputs/Toggles.test.js +22 -28
  108. package/src/components/Form/Inputs/index.js +4 -15
  109. package/src/components/MaterialUI/DataDisplay/PredefinedElements/InformationItem.test.js +1 -4
  110. package/src/components/MaterialUI/DataDisplay/PredefinedElements/Placeholder.js +32 -6
  111. package/src/components/MaterialUI/DataDisplay/PredefinedElements/Placeholder.test.js +3 -1
  112. package/src/components/MaterialUI/DataDisplay/PredefinedElements/SectionToolbar.js +39 -0
  113. package/src/components/MaterialUI/DataDisplay/Table.js +190 -114
  114. package/src/components/MaterialUI/DataDisplay/Table.test.js +246 -1
  115. package/src/components/MaterialUI/DataDisplay/TableProps.js +4 -0
  116. package/src/components/MaterialUI/DataDisplay/TableProps.test.js +2 -0
  117. package/src/components/MaterialUI/DataDisplay/TableWithInMemoryPaging.js +145 -0
  118. package/src/components/MaterialUI/DataDisplay/TableWithInMemoryPaging.test.js +457 -0
  119. package/src/components/MaterialUI/DataDisplay/TooltippedElements/MultipleLinesText.js +5 -1
  120. package/src/components/MaterialUI/DataDisplay/TooltippedElements/MultipleLinesText.test.js +7 -1
  121. package/src/components/MaterialUI/Inputs/DatePicker.js +19 -20
  122. package/src/components/MaterialUI/Inputs/DatePicker.test.js +11 -6
  123. package/src/components/MaterialUI/Inputs/PredefinedElements/SearchControl.js +1 -0
  124. package/src/components/MaterialUI/Inputs/Select.js +2 -0
  125. package/src/components/MaterialUI/Inputs/SelectProps.js +2 -0
  126. package/src/components/MaterialUI/Inputs/SelectProps.test.js +2 -0
  127. package/src/components/MaterialUI/Inputs/Switch.js +22 -1
  128. package/src/components/MaterialUI/Inputs/Switch.test.js +23 -0
  129. package/src/components/MaterialUI/Inputs/SwitchProps.js +2 -0
  130. package/src/components/MaterialUI/Inputs/SwitchProps.test.js +2 -0
  131. package/src/components/MaterialUI/Inputs/TimePicker.js +10 -19
  132. package/src/components/MaterialUI/Inputs/TimePicker.test.js +278 -117
  133. package/src/components/MaterialUI/hocs/withDeferredTooltip.js +4 -1
  134. package/src/components/MaterialUI/hocs/withDeferredTooltip.test.js +27 -0
  135. package/src/components/MaterialUI/muiThemes.js +1 -0
  136. package/src/components/Navigation/Bar.test.js +92 -87
  137. package/src/components/Provision.js +1 -1
  138. package/src/components/TaskDetailsModal.test.js +1 -3
  139. package/src/constants.js +1 -0
  140. package/src/content/iconsSheet.svg +740 -116
  141. package/src/hocs/withScrollBox.js +32 -19
  142. package/src/hocs/withScrollBox.test.js +15 -3
  143. package/src/hooks/useDaysAndMonthsLocalization.js +79 -0
  144. package/src/hooks/useDaysAndMonthsLocalization.test.js +107 -0
  145. package/src/hooks/useInMemoryPaging.js +78 -0
  146. package/src/hooks/useInMemoryPaging.test.js +515 -0
  147. package/src/hooks/useMultipleFieldEditState.js +11 -4
  148. package/src/hooks/useMultipleFieldEditState.test.js +49 -1
  149. package/src/reducers/metadata.js +6 -1
  150. package/src/reducers/metadata.test.js +31 -0
  151. package/src/requests +1 -0
  152. package/src/schemas/metadata.js +3 -0
  153. package/src/selectors/locale.js +1 -1
  154. package/src/selectors/metadata.js +12 -9
  155. package/src/selectors/metadata.test.js +92 -11
  156. package/src/sharedMessages.js +184 -0
  157. package/src/timezones.json +883 -0
  158. package/src/translations/en-US.json +46 -0
  159. package/src/translations/fr-CA.json +46 -0
  160. package/src/utils/ListHelper.js +203 -0
  161. package/src/utils/ListHelper.test.js +710 -0
  162. package/src/utils/comparisonHelper.js +135 -0
  163. package/src/utils/comparisonHelper.test.js +334 -0
  164. package/src/utils/propertyBagHelper.js +2 -0
  165. package/src/utils/propertyBagHelper.test.js +6 -0
  166. package/src/utils/timezoneHelper.js +10 -135
  167. package/src/utils/timezoneHelper.test.js +7 -7
  168. package/dist/components/Form/FieldList.js +0 -270
  169. package/dist/components/Form/Inputs/FieldButtons.js +0 -66
  170. package/dist/components/Form/Inputs/Number.js +0 -117
  171. package/dist/components/Form/Inputs/SmallButton.js +0 -91
  172. package/dist/components/Form/Inputs/Time.js +0 -86
  173. package/dist/components/Form/Inputs/Translation.js +0 -169
  174. package/src/components/AppFrame/ApplicationSelector/Header.js +0 -34
  175. package/src/components/AppFrame/ApplicationSelector/Header.test.js +0 -23
  176. package/src/components/Form/FieldList.js +0 -210
  177. package/src/components/Form/FieldList.test.js +0 -558
  178. package/src/components/Form/Inputs/FieldButtons.js +0 -90
  179. package/src/components/Form/Inputs/Number.js +0 -60
  180. package/src/components/Form/Inputs/Number.test.js +0 -435
  181. package/src/components/Form/Inputs/SmallButton.js +0 -37
  182. package/src/components/Form/Inputs/SmallButton.test.js +0 -65
  183. package/src/components/Form/Inputs/Time.js +0 -32
  184. package/src/components/Form/Inputs/Time.test.js +0 -41
  185. package/src/components/Form/Inputs/Translation.js +0 -93
  186. package/src/components/Form/Inputs/Translation.test.js +0 -204
@@ -1,87 +1,80 @@
1
1
  import React from "react";
2
- import styled from "styled-components";
3
- import transition from "styled-transition-group";
4
- import { getThemeProp, ifFlag, safeGet } from "../../utils";
5
- import Icon from "../Icon";
6
- import Text from "../Text";
2
+ import { makeStyles } from "@material-ui/core/styles";
3
+ import { FormattedMessage } from "react-intl";
4
+ import Icon from "../MaterialUI/DataDisplay/Icon";
7
5
 
8
- export const Drawer = transition.div`
9
- position: absolute;
10
- z-index: 19999;
11
- margin: 4px 0 0;
12
- ${ifFlag("alignRight", "right", "left")}: 0;
6
+ const useStyles = makeStyles(theme => ({
7
+ drawer: {
8
+ position: "absolute",
9
+ zIndex: 19999,
10
+ margin: "4px 0 0",
11
+ left: props => (props.alignRight ? "auto" : "0"),
12
+ right: props => (props.alignRight ? "0" : "auto"),
13
+ transition: "opacity 100ms ease-out",
13
14
 
14
- transition: opacity ${props => props.timeout}ms ease-out;
15
+ "&.enter-active": {
16
+ opacity: 1,
17
+ visibility: "visible",
18
+ },
19
+ "&.exit-active": {
20
+ opacity: 0,
21
+ visibility: "hidden",
22
+ },
23
+ },
24
+ list: {
25
+ color: theme.palette.text.primary,
26
+ backgroundColor: "white",
27
+ border: `1px solid ${theme.palette.text.hint}`,
28
+ borderRadius: "5px",
29
+ listStyleType: "none",
30
+ padding: "5px 0",
31
+ margin: "0",
32
+ fontFamily: "Open Sans, sans-serif",
33
+ fontSize: "12px",
34
+ width: "max-content",
35
+ },
36
+ item: {
37
+ boxSizing: "border-box",
38
+ height: "30px",
39
+ minWidth: "178px",
40
+ padding: "9px 12px",
41
+ display: "flex",
42
+ alignItems: "center",
43
+ cursor: "pointer",
44
+ "&:hover": {
45
+ backgroundColor: theme.palette.primary.main,
46
+ color: "white",
47
+ },
48
+ },
49
+ itemIcon: {
50
+ paddingRight: "11px",
51
+ fontSize: "17px",
52
+ },
53
+ }));
15
54
 
16
- &:enter {
17
- opacity: 0.01;
18
- }
19
- &:enter-active {
20
- opacity: 1;
21
- }
22
- &:exit {
23
- opacity: 1;
24
- }
25
- &:exit-active {
26
- opacity: 0.01;
27
- }
28
- `;
29
- Drawer.defaultProps = {
30
- unmountOnExit: true,
31
- timeout: 100,
32
- };
33
-
34
- export const List = styled.ul`
35
- color: ${getThemeProp(["colors", "text"], "#333333")};
36
- background-color: white;
37
- border: 1px solid ${getThemeProp(["colors", "border"], "#999999")};
38
- border-radius: 5px;
39
- list-style-type: none;
40
- padding: 5px 0;
41
- margin: 0;
42
- font-family: Open Sans, sans-serif;
43
- font-size: 12px;
44
- width: max-content;
45
- `;
46
-
47
- export const Item = styled.li`
48
- box-sizing: border-box;
49
- height: 30px;
50
- min-width: 178px;
51
- padding: 9px 12px;
52
- display: flex;
53
- align-items: center;
54
- cursor: pointer;
55
+ const Menu = ({ id, open, menuItems, reset, alignRight }) => {
56
+ const classes = useStyles({ alignRight });
55
57
 
56
- &:hover {
57
- background-color: ${getThemeProp(["colors", "application", "base"], "#ffffff")};
58
- color: white;
59
- }
60
- `;
61
-
62
- export const ItemIcon = styled(Icon)`
63
- padding-right: 11px;
64
- font-size: 17px;
65
- `;
66
-
67
- const Menu = ({ id, open, menuItems, reset, alignRight }) => (
68
- <Drawer in={open} alignRight={alignRight}>
69
- <List id={id}>
70
- {menuItems.map(item => (
71
- <Item
72
- id={item.id}
73
- key={item.id || (item.label && safeGet(item.label, "id")) + (item.icon || "")}
74
- onClick={event => {
75
- reset();
76
- item.handler(event);
77
- }}
78
- >
79
- {item.icon ? <ItemIcon id={item.icon} /> : null}
80
- <Text message={item.label} />
81
- </Item>
82
- ))}
83
- </List>
84
- </Drawer>
85
- );
58
+ return (
59
+ <div className={`${classes.drawer} ${open ? "enter-active" : "exit-active"}`}>
60
+ <ul id={id} className={classes.list}>
61
+ {menuItems.map(item => (
62
+ <li
63
+ id={item.id}
64
+ key={item.id || item.label?.id + (item.icon || "")}
65
+ className={classes.item}
66
+ onClick={event => {
67
+ reset();
68
+ item.handler(event);
69
+ }}
70
+ >
71
+ {item.icon ? <Icon id={item.icon} className={classes.itemIcon} /> : null}
72
+ {typeof item.label === "string" ? item.label : <FormattedMessage {...item.label} />}
73
+ </li>
74
+ ))}
75
+ </ul>
76
+ </div>
77
+ );
78
+ };
86
79
 
87
80
  export default Menu;
@@ -1,16 +1,18 @@
1
1
  import React from "react";
2
2
  import { Provider } from "react-redux";
3
3
  import sinon from "sinon";
4
- import { getStyledClassSelector } from "../../utils/testUtils";
5
- import Menu, { Drawer, List, Item, ItemIcon } from "./Menu";
4
+ import { IntlProvider } from "react-intl";
5
+ import Menu from "./Menu";
6
+ import Icon from "../MaterialUI/DataDisplay/Icon";
6
7
 
7
8
  describe("Menu", () => {
8
9
  it("renders a closed menu", () =>
9
10
  expect(
10
11
  <Menu menuItems={[{ label: "First", icon: "one", handler: () => {} }]} />,
11
12
  "when mounted",
12
- "to satisfy",
13
- null,
13
+ "to have style rules satisfying",
14
+ "to match",
15
+ /visibility:\s*hidden;/,
14
16
  ));
15
17
 
16
18
  it("renders an open menu", () =>
@@ -28,18 +30,18 @@ describe("Menu", () => {
28
30
  </Provider>,
29
31
  "when mounted",
30
32
  "to satisfy",
31
- <Drawer in>
32
- <List id="testMenu">
33
- <Item id="first">
34
- <ItemIcon id="one" />
33
+ <div>
34
+ <ul id="testMenu">
35
+ <li id="first">
36
+ <Icon id="one" />
35
37
  First
36
- </Item>
37
- <Item id="second">
38
- <ItemIcon id="two" />
38
+ </li>
39
+ <li id="second">
40
+ <Icon id="two" />
39
41
  Second
40
- </Item>
41
- </List>
42
- </Drawer>,
42
+ </li>
43
+ </ul>
44
+ </div>,
43
45
  ));
44
46
 
45
47
  it("renders an open right-aligned menu", () =>
@@ -53,23 +55,22 @@ describe("Menu", () => {
53
55
  { id: "second", label: "Second", icon: "two", handler: () => {} },
54
56
  ]}
55
57
  toggle={() => {}}
56
- alignRight
57
58
  />
58
59
  </Provider>,
59
60
  "when mounted",
60
61
  "to satisfy",
61
- <Drawer in alignRight>
62
- <List id="testMenu">
63
- <Item id="first">
64
- <ItemIcon id="one" />
62
+ <div>
63
+ <ul id="testMenu">
64
+ <li id="first">
65
+ <Icon id="one" />
65
66
  First
66
- </Item>
67
- <Item id="second">
68
- <ItemIcon id="two" />
67
+ </li>
68
+ <li id="second">
69
+ <Icon id="two" />
69
70
  Second
70
- </Item>
71
- </List>
72
- </Drawer>,
71
+ </li>
72
+ </ul>
73
+ </div>,
73
74
  ));
74
75
 
75
76
  it("closes on click on item", () => {
@@ -77,71 +78,19 @@ describe("Menu", () => {
77
78
  const handler = sinon.spy().named("handler");
78
79
  return expect(
79
80
  <Provider store={{ getState: () => ({}), subscribe: () => {}, dispatch: () => {} }}>
80
- <Menu open menuItems={[{ label: "Foo", handler }]} reset={reset} />
81
+ <IntlProvider locale="en-US">
82
+ <Menu open menuItems={[{ label: { id: "foo", defaultMessage: "Foo" }, handler }]} reset={reset} />
83
+ </IntlProvider>
81
84
  </Provider>,
82
85
  "when mounted",
83
86
  "with event",
84
- { type: "click", target: getStyledClassSelector(Item) },
87
+ { type: "click", target: "li" },
85
88
  "to satisfy",
86
- <Drawer in>
87
- <List>
88
- <Item>Foo</Item>
89
- </List>
90
- </Drawer>,
89
+ <div>
90
+ <ul>
91
+ <li>Foo</li>
92
+ </ul>
93
+ </div>,
91
94
  ).then(() => Promise.all([expect(reset, "was called"), expect(handler, "was called")]));
92
95
  });
93
-
94
- describe("Drawer", () => {
95
- it("sets transition time according to its timeout", () =>
96
- expect(
97
- <Drawer in timeout={500} />,
98
- "when mounted",
99
- "to have style rules satisfying",
100
- "to contain",
101
- "transition: opacity 500ms ease-out;",
102
- ));
103
-
104
- it("defaults to left aligned position", () =>
105
- expect(
106
- <Drawer in timeout={500} />,
107
- "when mounted",
108
- "to have style rules satisfying",
109
- expect.it("to contain", "left: 0;").and("not to contain", "right: 0"),
110
- ));
111
-
112
- it("can align right", () =>
113
- expect(
114
- <Drawer in timeout={500} alignRight />,
115
- "when mounted",
116
- "to have style rules satisfying",
117
- expect.it("to contain", "right: 0;").and("not to contain", "left: 0"),
118
- ));
119
- });
120
-
121
- describe("Item", () => {
122
- let theme;
123
- beforeEach(() => {
124
- theme = {
125
- colors: { application: { base: "#ff00ff" } },
126
- };
127
- });
128
-
129
- it("shows a background with the highlight color when hovering", () =>
130
- expect(
131
- <Item theme={theme} />,
132
- "when mounted",
133
- "to have style rules satisfying",
134
- "to match",
135
- /:hover\s*\{[^}]*\bbackground-color: #ff00ff;[^}]*\}/,
136
- ));
137
-
138
- it("has a default highlight color", () =>
139
- expect(
140
- <Item />,
141
- "when mounted",
142
- "to have style rules satisfying",
143
- "to match",
144
- /:hover\s*\{[^}]*\bbackground-color: #ffffff;[^}]*\}/,
145
- ));
146
- });
147
96
  });
@@ -1,33 +1,37 @@
1
1
  import React from "react";
2
- import styled from "styled-components";
2
+ import { makeStyles } from "@material-ui/core/styles";
3
3
  import Menu from "./Menu";
4
4
  import useToggle from "../../hooks/useToggle";
5
5
  import withClickOutside from "../../hocs/withClickOutside";
6
6
 
7
- export const Wrapper = withClickOutside(styled.div`
8
- position: relative;
9
- `);
7
+ const useStyles = makeStyles(() => ({
8
+ wrapper: {
9
+ position: "relative",
10
+ },
11
+ }));
10
12
 
11
- export const AnchorWrapper = styled.div``;
13
+ export const Wrapper = withClickOutside(
14
+ React.forwardRef(({ children, className }, ref) => {
15
+ const classes = useStyles();
12
16
 
13
- export const Background = styled.div`
14
- position: absolute;
15
- top: 0;
16
- left: 0;
17
- bottom: 0;
18
- right: 0;
19
- z-index: 19998;
20
- `;
17
+ return (
18
+ <div ref={ref} className={`${classes.wrapper} ${className ? className : ""}`}>
19
+ {children}
20
+ </div>
21
+ );
22
+ }),
23
+ );
21
24
 
22
25
  const DropMenu = ({ id, initOpen, menuItems, alignRight, className = "", children }) => {
23
26
  const [open, toggle, reset] = useToggle(initOpen);
27
+
24
28
  return (
25
29
  <Wrapper className={className} onClickOutside={reset}>
26
- <AnchorWrapper id={id + "Anchor"} onClick={toggle} open={open}>
30
+ <div id={id + "Anchor"} onClick={toggle}>
27
31
  {React.Children.map(children, child =>
28
32
  typeof child === "object" ? React.cloneElement(child, { open }) : child,
29
33
  )}
30
- </AnchorWrapper>
34
+ </div>
31
35
  <Menu id={id + "Dropdown"} {...{ open, menuItems, reset }} alignRight={alignRight} />
32
36
  </Wrapper>
33
37
  );
@@ -1,34 +1,41 @@
1
1
  import React from "react";
2
- import styled, { css } from "styled-components";
3
- import Field, { FieldBox } from "./Field";
2
+ import { makeStyles } from "@material-ui/core/styles";
3
+ import Field from "./Field";
4
4
 
5
- export const CombiningRow = styled.div`
6
- display: flex;
7
- flex-direction: row;
5
+ const useStyles = makeStyles(() => ({
6
+ combiningRow: props => {
7
+ const flexStyles = props.proportions.reduce((styles, width, index) => {
8
+ if (width) {
9
+ styles[`& > *:nth-child(${index + 1})`] = {
10
+ flex: typeof width === "string" ? `0 0 ${width}` : `0 1 ${width}%`,
11
+ };
12
+ }
13
+ return styles;
14
+ }, {});
8
15
 
9
- & > ${FieldBox} {
10
- margin-top: 0;
11
- margin-right: 15px;
12
- }
13
- & > ${FieldBox}:last-child {
14
- margin-right: 0;
15
- }
16
- ${props =>
17
- props.proportions.map((width, index) =>
18
- width
19
- ? css`
20
- & > ${FieldBox}:nth-child(${index + 1}) {
21
- flex: ${typeof width === "string" ? "0 0 " + width : "0 1 " + width + "%"};
22
- }
23
- `
24
- : "",
25
- )};
26
- `;
16
+ return {
17
+ display: "flex",
18
+ flexDirection: "row",
19
+ "& > *": {
20
+ marginTop: 0,
21
+ marginRight: 15,
22
+ },
23
+ "& > :last-child": {
24
+ marginRight: 0,
25
+ },
26
+ ...flexStyles,
27
+ };
28
+ },
29
+ }));
27
30
 
28
- const CombinationField = ({ label, children, proportions = [] }) => (
29
- <Field label={label}>
30
- <CombiningRow proportions={proportions}>{children}</CombiningRow>
31
- </Field>
32
- );
31
+ const CombinationField = ({ label, children, proportions = [] }) => {
32
+ const classes = useStyles({ proportions });
33
+
34
+ return (
35
+ <Field label={label}>
36
+ <div className={classes.combiningRow}>{children}</div>
37
+ </Field>
38
+ );
39
+ };
33
40
 
34
41
  export default CombinationField;
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import { Provider } from "react-redux";
3
3
  import Field from "./Field";
4
- import Combination, { CombiningRow } from "./Combination";
4
+ import Combination from "./Combination";
5
5
 
6
6
  describe("Combination", () => {
7
7
  it("renders a combining box around a list of fields", () =>
@@ -13,7 +13,7 @@ describe("Combination", () => {
13
13
  getState: () => ({}),
14
14
  }}
15
15
  >
16
- <Combination label="A combination" proportions={[30, 70]}>
16
+ <Combination label="A combination" proportions={[30, 70, undefined]}>
17
17
  <div id="child1" />
18
18
  <div id="child2" />
19
19
  </Combination>
@@ -28,10 +28,10 @@ describe("Combination", () => {
28
28
  }}
29
29
  >
30
30
  <Field label="A combination">
31
- <CombiningRow proportions={[30, 70]}>
31
+ <div>
32
32
  <div id="child1" />
33
33
  <div id="child2" />
34
- </CombiningRow>
34
+ </div>
35
35
  </Field>
36
36
  </Provider>,
37
37
  ));
@@ -45,23 +45,10 @@ describe("Combination", () => {
45
45
  "when mounted",
46
46
  "to satisfy",
47
47
  <Field label={undefined}>
48
- <CombiningRow proportions={[]}>
48
+ <div>
49
49
  <div id="child1" />
50
50
  <div id="child2" />
51
- </CombiningRow>
51
+ </div>
52
52
  </Field>,
53
53
  ));
54
54
  });
55
-
56
- describe("CombiningRow", () => {
57
- it("sets flex rules on its children to control their proportions", () =>
58
- expect(
59
- <CombiningRow proportions={[50, undefined, "70px"]} />,
60
- "when mounted",
61
- "to have style rules satisfying",
62
- expect
63
- .it("to match", /:nth-child\(1\) \{[^{]*flex: 0 1 50%;/)
64
- .and("not to match", /:nth-child\(2\)/)
65
- .and("to match", /:nth-child\(3\) \{[^{]*flex: 0 0 70px;/),
66
- ));
67
- });
@@ -1,81 +1,68 @@
1
1
  import React from "react";
2
- import styled, { css } from "styled-components";
3
- import { ifFlag, getThemeProp } from "../../utils";
4
- import Text from "../Text";
2
+ import { makeStyles } from "@material-ui/core/styles";
3
+ import { FormattedMessage } from "react-intl";
5
4
 
6
- export const FieldBox = styled.div`
7
- flex: 0 1 auto;
8
- display: flex;
9
- flex-direction: column;
10
- margin-top: 20px;
11
- position: relative;
12
- `;
13
-
14
- export const Label = styled.label`
15
- ${ifFlag(
16
- "invalid",
17
- css`
18
- color: ${getThemeProp(["colors", "error"], "#ce4844")};
19
- `,
20
- css`
21
- color: ${getThemeProp(["colors", "textMedium"], "#999999")};
22
- `,
23
- )}
24
- min-height: 17px;
25
- ${ifFlag(
26
- "center",
27
- css`
28
- text-align: center;
29
- `,
30
- )};
31
- ${ifFlag(
32
- "labelOnly",
33
- "",
34
- css`
35
- margin-bottom: 10px;
36
- `,
37
- )};
38
- ${ifFlag(
39
- "required",
40
- css`
41
- &::after {
42
- content: " *";
43
- color: #666;
44
- }
45
- `,
46
- )}
47
- `;
48
-
49
- export const RequiredNotice = styled.div`
50
- position: absolute;
51
- bottom: -1.6em;
52
- right: 0;
53
- color: ${getThemeProp(["colors", "error"], "#ce4844")};
54
- `;
5
+ const useStyles = makeStyles(theme => ({
6
+ fieldBox: {
7
+ flex: "0 1 auto",
8
+ display: "flex",
9
+ flexDirection: "column",
10
+ marginTop: 20,
11
+ position: "relative",
12
+ },
13
+ label: {
14
+ minHeight: 17,
15
+ color: theme.palette.text.hint,
16
+ marginBottom: "10px",
17
+ },
18
+ invalidLabel: {
19
+ color: theme.palette.error.main,
20
+ },
21
+ centerLabel: {
22
+ textAlign: "center",
23
+ },
24
+ labelOnly: {
25
+ marginBottom: "0px",
26
+ },
27
+ requiredLabel: {
28
+ "&::after": {
29
+ content: '" *"',
30
+ color: "#666",
31
+ },
32
+ },
33
+ requiredNotice: {
34
+ position: "absolute",
35
+ bottom: "-1.6em",
36
+ right: 0,
37
+ color: theme.palette.error.main,
38
+ },
39
+ }));
55
40
 
56
41
  const Field = ({ id, label, center, labelOnly, required, invalid, children }) => {
57
- const reqFlag = { invalid };
58
- if (required) reqFlag.required = true;
42
+ const classes = useStyles();
43
+
59
44
  return (
60
- <FieldBox>
45
+ <div className={classes.fieldBox}>
61
46
  {label !== undefined ? (
62
- <Label
47
+ <label
63
48
  htmlFor={labelOnly ? undefined : id}
64
- labelOnly={labelOnly}
65
- id={id + "_label"}
66
- center={center}
67
- {...reqFlag}
49
+ id={`${id}_label`}
50
+ className={`${classes.label}
51
+ ${invalid ? classes.invalidLabel : ""}
52
+ ${center ? classes.centerLabel : ""}
53
+ ${labelOnly ? classes.labelOnly : ""}
54
+ ${required ? classes.requiredLabel : ""}`}
68
55
  >
69
- <Text message={label} />
70
- </Label>
56
+ {typeof label === "string" ? label : <FormattedMessage {...label} />}
57
+ </label>
71
58
  ) : null}
72
59
  {labelOnly ? null : children}
73
60
  {!labelOnly && required && invalid ? (
74
- <RequiredNotice>
75
- <Text message={required} />
76
- </RequiredNotice>
61
+ <div className={classes.requiredNotice}>
62
+ {typeof required === "string" ? required : <FormattedMessage {...required} />}
63
+ </div>
77
64
  ) : null}
78
- </FieldBox>
65
+ </div>
79
66
  );
80
67
  };
81
68