orc-shared 5.10.2 → 5.99.0-dev.10

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 (234) hide show
  1. package/dist/components/AppFrame/About.js +13 -13
  2. package/dist/components/AppFrame/Anchor.js +7 -7
  3. package/dist/components/AppFrame/AppFrame.js +3 -3
  4. package/dist/components/AppFrame/Help.js +4 -4
  5. package/dist/components/AppFrame/MenuItem.js +17 -26
  6. package/dist/components/AppFrame/Preferences.js +14 -14
  7. package/dist/components/AppFrame/Sidebar.js +6 -6
  8. package/dist/components/AppFrame/Topbar.js +6 -6
  9. package/dist/components/ApplicationModuleLoader.js +3 -2
  10. package/dist/components/Authenticate.js +29 -22
  11. package/dist/components/DropMenu/Menu.js +9 -9
  12. package/dist/components/ErrorPlaceholder.js +8 -24
  13. package/dist/components/Form/Field.js +4 -4
  14. package/dist/components/Form/Inputs/Button.js +2 -2
  15. package/dist/components/Form/Inputs/MultiSelector.js +137 -0
  16. package/dist/components/Form/Inputs/Selector.js +13 -10
  17. package/dist/components/Form/Inputs/index.js +1 -1
  18. package/dist/components/InternetExplorerWarningMessage.js +15 -15
  19. package/dist/components/LoadingIcon.js +38 -17
  20. package/dist/components/MaterialUI/DataDisplay/Modal.js +3 -3
  21. package/dist/components/MaterialUI/DataDisplay/PredefinedElements/Placeholder.js +6 -6
  22. package/dist/components/MaterialUI/DataDisplay/PredefinedElements/StepperModal.js +1 -1
  23. package/dist/components/MaterialUI/DataDisplay/PredefinedElements/TableInfoBar.js +1 -1
  24. package/dist/components/MaterialUI/DataDisplay/SelectionList.js +1 -1
  25. package/dist/components/MaterialUI/DataDisplay/Table.js +2 -1
  26. package/dist/components/MaterialUI/DataDisplay/TableProps.js +3 -1
  27. package/dist/components/MaterialUI/DataDisplay/TransferList.js +1 -1
  28. package/dist/components/MaterialUI/Inputs/CheckboxGroup.js +1 -1
  29. package/dist/components/MaterialUI/Inputs/DatePicker.js +1 -1
  30. package/dist/components/MaterialUI/Inputs/PredefinedElements/SearchControl.js +1 -1
  31. package/dist/components/MaterialUI/Inputs/Select.js +175 -109
  32. package/dist/components/MaterialUI/Inputs/SelectProps.js +11 -1
  33. package/dist/components/MaterialUI/Inputs/Switch.js +1 -1
  34. package/dist/components/MaterialUI/Navigation/DropDownMenu.js +2 -4
  35. package/dist/components/MaterialUI/ScopeSelector/ScopeSelector.js +1 -1
  36. package/dist/components/MaterialUI/ScopeSelector/TreeItem.js +27 -42
  37. package/dist/components/MaterialUI/Surfaces/Paper.js +1 -1
  38. package/dist/components/MaterialUI/Surfaces/SectionExpansionPanel.js +3 -2
  39. package/dist/components/MaterialUI/muiThemes.js +3 -1
  40. package/dist/components/Provision.js +30 -13
  41. package/dist/components/Routing/SegmentPage.js +117 -56
  42. package/dist/components/Scope/ScopeNode.js +62 -57
  43. package/dist/components/Sidepanel.js +59 -23
  44. package/dist/components/Spritesheet.js +35 -17
  45. package/dist/components/Text.js +1 -60
  46. package/dist/components/ToastList.js +95 -64
  47. package/dist/components/Treeview/Branch.js +82 -20
  48. package/dist/components/Treeview/Label.js +108 -31
  49. package/dist/components/Treeview/Leaf.js +56 -12
  50. package/dist/components/Treeview/Node.js +22 -9
  51. package/dist/components/Treeview/index.js +7 -1
  52. package/dist/components/Treeview/settings.js +17 -6
  53. package/dist/{components/Modal/index.js → hooks/useWindowSize.js} +38 -36
  54. package/dist/sharedMessages.js +8 -0
  55. package/dist/utils/index.js +0 -4
  56. package/dist/utils/testUtils.js +1 -12
  57. package/dist/{components/Modal/Background.js → utils/toastHelper.js} +11 -14
  58. package/package.json +2 -2
  59. package/src/components/AppFrame/About.js +13 -13
  60. package/src/components/AppFrame/Anchor.js +7 -7
  61. package/src/components/AppFrame/AppFrame.js +3 -3
  62. package/src/components/AppFrame/Help.js +4 -4
  63. package/src/components/AppFrame/MenuItem.js +15 -23
  64. package/src/components/AppFrame/Preferences.js +14 -14
  65. package/src/components/AppFrame/Sidebar.js +6 -6
  66. package/src/components/AppFrame/Topbar.js +6 -6
  67. package/src/components/ApplicationModuleLoader.js +2 -2
  68. package/src/components/ApplicationModuleLoader.test.js +15 -28
  69. package/src/components/Authenticate.js +21 -23
  70. package/src/components/Authenticate.test.js +19 -27
  71. package/src/components/DropMenu/Menu.js +9 -9
  72. package/src/components/ErrorPlaceholder.js +4 -21
  73. package/src/components/ErrorPlaceholder.test.js +7 -14
  74. package/src/components/Form/Field.js +4 -4
  75. package/src/components/Form/InputField.test.js +2 -1
  76. package/src/components/Form/Inputs/Button.js +2 -2
  77. package/src/components/Form/Inputs/MultiSelector.js +73 -0
  78. package/src/components/Form/Inputs/MultiSelector.test.js +332 -0
  79. package/src/components/Form/Inputs/Selector.js +12 -4
  80. package/src/components/Form/Inputs/Selector.test.js +27 -12
  81. package/src/components/Form/Inputs/index.js +1 -1
  82. package/src/components/InternetExplorerWarningMessage.js +15 -15
  83. package/src/components/Loader.test.js +50 -59
  84. package/src/components/LoadingIcon.js +27 -14
  85. package/src/components/LoadingIcon.test.js +11 -15
  86. package/src/components/MaterialUI/DataDisplay/Modal.js +3 -3
  87. package/src/components/MaterialUI/DataDisplay/PredefinedElements/Placeholder.js +6 -6
  88. package/src/components/MaterialUI/DataDisplay/PredefinedElements/StepperModal.js +1 -1
  89. package/src/components/MaterialUI/DataDisplay/PredefinedElements/TableInfoBar.js +1 -1
  90. package/src/components/MaterialUI/DataDisplay/SelectionList.js +1 -1
  91. package/src/components/MaterialUI/DataDisplay/Table.js +6 -1
  92. package/src/components/MaterialUI/DataDisplay/Table.test.js +21 -1
  93. package/src/components/MaterialUI/DataDisplay/TableProps.js +2 -0
  94. package/src/components/MaterialUI/DataDisplay/TableProps.test.js +20 -2
  95. package/src/components/MaterialUI/DataDisplay/TransferList.js +1 -1
  96. package/src/components/MaterialUI/Inputs/CheckboxGroup.js +1 -1
  97. package/src/components/MaterialUI/Inputs/DatePicker.js +1 -1
  98. package/src/components/MaterialUI/Inputs/PredefinedElements/SearchControl.js +1 -1
  99. package/src/components/MaterialUI/Inputs/PredefinedElements/SearchControl.test.js +1 -1
  100. package/src/components/MaterialUI/Inputs/Select.js +143 -83
  101. package/src/components/MaterialUI/Inputs/Select.test.js +199 -14
  102. package/src/components/MaterialUI/Inputs/SelectProps.js +10 -0
  103. package/src/components/MaterialUI/Inputs/SelectProps.test.js +10 -0
  104. package/src/components/MaterialUI/Inputs/Switch.js +1 -1
  105. package/src/components/MaterialUI/Navigation/DropDownMenu.js +2 -2
  106. package/src/components/MaterialUI/Navigation/DropDownMenu.test.js +5 -6
  107. package/src/components/MaterialUI/ScopeSelector/ScopeSelector.js +1 -2
  108. package/src/components/MaterialUI/ScopeSelector/TreeItem.js +8 -31
  109. package/src/components/MaterialUI/Surfaces/Paper.js +1 -1
  110. package/src/components/MaterialUI/Surfaces/SectionExpansionPanel.js +2 -1
  111. package/src/components/MaterialUI/muiThemes.js +4 -1
  112. package/src/components/Navigation/Navigation.test.js +0 -5
  113. package/src/components/Navigation/useNavigationState.test.js +79 -222
  114. package/src/components/Provision.js +36 -42
  115. package/src/components/Provision.test.js +10 -26
  116. package/src/components/Routing/SegmentPage.js +68 -52
  117. package/src/components/Routing/SegmentPage.test.js +4 -12
  118. package/src/components/Scope/ScopeNode.js +44 -55
  119. package/src/components/Scope/ScopeNode.test.js +84 -163
  120. package/src/components/ScopeExtendedConfigurationLoader.test.js +1 -4
  121. package/src/components/Sidepanel.js +38 -32
  122. package/src/components/Sidepanel.test.js +54 -27
  123. package/src/components/Spritesheet.js +23 -21
  124. package/src/components/Spritesheet.test.js +10 -10
  125. package/src/components/Text.js +0 -49
  126. package/src/components/ToastList.js +79 -90
  127. package/src/components/ToastList.test.js +29 -103
  128. package/src/components/Treeview/Branch.js +65 -47
  129. package/src/components/Treeview/Branch.test.js +2 -43
  130. package/src/components/Treeview/Label.js +68 -54
  131. package/src/components/Treeview/Label.test.js +55 -63
  132. package/src/components/Treeview/Leaf.js +41 -22
  133. package/src/components/Treeview/Leaf.test.js +1 -15
  134. package/src/components/Treeview/Node.js +16 -9
  135. package/src/components/Treeview/Node.test.js +269 -200
  136. package/src/components/Treeview/Treeview.test.js +248 -248
  137. package/src/components/Treeview/index.js +6 -0
  138. package/src/components/Treeview/settings.js +10 -6
  139. package/src/hooks/useMultipleFieldEditState.test.js +0 -1
  140. package/src/hooks/useWindowSize.js +39 -0
  141. package/src/hooks/useWindowSize.test.js +68 -0
  142. package/src/sharedMessages.js +8 -0
  143. package/src/translations/en-US.json +2 -0
  144. package/src/translations/fr-CA.json +2 -0
  145. package/src/utils/index.js +0 -4
  146. package/src/utils/testUtils.js +0 -10
  147. package/src/utils/testUtils.test.js +0 -68
  148. package/src/utils/toastHelper.js +8 -0
  149. package/src/utils/toastHelper.test.js +41 -0
  150. package/dist/components/Button.js +0 -70
  151. package/dist/components/CategoryList.js +0 -197
  152. package/dist/components/Checkbox.js +0 -103
  153. package/dist/components/Icon.js +0 -69
  154. package/dist/components/IconButton.js +0 -80
  155. package/dist/components/Input.js +0 -101
  156. package/dist/components/List/DataCell.js +0 -129
  157. package/dist/components/List/HeadCell.js +0 -125
  158. package/dist/components/List/HeadRow.js +0 -73
  159. package/dist/components/List/List.js +0 -274
  160. package/dist/components/List/Row.js +0 -109
  161. package/dist/components/List/enhanceColumnDefs.js +0 -111
  162. package/dist/components/List/index.js +0 -59
  163. package/dist/components/Modal/Dialog.js +0 -75
  164. package/dist/components/Modal/Wrapper.js +0 -69
  165. package/dist/components/MultiSelector.js +0 -187
  166. package/dist/components/Navigation/Bar.js +0 -293
  167. package/dist/components/Navigation/Tab.js +0 -182
  168. package/dist/components/Placeholder.js +0 -114
  169. package/dist/components/Scope/Selector.js +0 -123
  170. package/dist/components/Selector.js +0 -185
  171. package/dist/components/Switch.js +0 -128
  172. package/dist/components/Toolbar.js +0 -227
  173. package/dist/components/Tooltip.js +0 -66
  174. package/dist/getTheme.js +0 -158
  175. package/dist/getThemeOverrides.js +0 -93
  176. package/dist/hocs/withAuthentication.js +0 -72
  177. package/dist/utils/styledPropFuncs.js +0 -88
  178. package/src/components/Button.js +0 -90
  179. package/src/components/Button.test.js +0 -49
  180. package/src/components/CategoryList.js +0 -140
  181. package/src/components/CategoryList.test.js +0 -667
  182. package/src/components/Checkbox.js +0 -63
  183. package/src/components/Checkbox.test.js +0 -122
  184. package/src/components/Icon.js +0 -18
  185. package/src/components/IconButton.js +0 -30
  186. package/src/components/IconButton.test.js +0 -61
  187. package/src/components/Input.js +0 -35
  188. package/src/components/Input.test.js +0 -34
  189. package/src/components/List/DataCell.js +0 -77
  190. package/src/components/List/DataCell.test.js +0 -357
  191. package/src/components/List/HeadCell.js +0 -105
  192. package/src/components/List/HeadCell.test.js +0 -331
  193. package/src/components/List/HeadRow.js +0 -21
  194. package/src/components/List/HeadRow.test.js +0 -27
  195. package/src/components/List/List.js +0 -162
  196. package/src/components/List/List.test.js +0 -705
  197. package/src/components/List/Row.js +0 -72
  198. package/src/components/List/Row.test.js +0 -194
  199. package/src/components/List/enhanceColumnDefs.js +0 -54
  200. package/src/components/List/enhanceColumnDefs.test.js +0 -179
  201. package/src/components/List/index.js +0 -6
  202. package/src/components/Modal/Background.js +0 -10
  203. package/src/components/Modal/Dialog.js +0 -27
  204. package/src/components/Modal/Dialog.test.js +0 -20
  205. package/src/components/Modal/Modal.test.js +0 -52
  206. package/src/components/Modal/Wrapper.js +0 -32
  207. package/src/components/Modal/Wrapper.test.js +0 -55
  208. package/src/components/Modal/index.js +0 -22
  209. package/src/components/MultiSelector.js +0 -104
  210. package/src/components/MultiSelector.test.js +0 -348
  211. package/src/components/Navigation/Bar.js +0 -212
  212. package/src/components/Navigation/Bar.test.js +0 -552
  213. package/src/components/Navigation/Tab.js +0 -156
  214. package/src/components/Navigation/Tab.test.js +0 -404
  215. package/src/components/Placeholder.js +0 -61
  216. package/src/components/Placeholder.test.js +0 -106
  217. package/src/components/Scope/Selector.js +0 -70
  218. package/src/components/Scope/Selector.test.js +0 -138
  219. package/src/components/Selector.js +0 -191
  220. package/src/components/Selector.test.js +0 -157
  221. package/src/components/Switch.js +0 -112
  222. package/src/components/Switch.test.js +0 -130
  223. package/src/components/Text.test.js +0 -132
  224. package/src/components/Toolbar.js +0 -178
  225. package/src/components/Toolbar.test.js +0 -478
  226. package/src/components/Tooltip.js +0 -51
  227. package/src/components/Tooltip.test.js +0 -21
  228. package/src/getTheme.js +0 -103
  229. package/src/getTheme.test.js +0 -92
  230. package/src/getThemeOverrides.js +0 -27
  231. package/src/hocs/withAuthentication.js +0 -18
  232. package/src/hocs/withAuthentication.test.js +0 -120
  233. package/src/utils/styledPropFuncs.js +0 -20
  234. package/src/utils/styledPropFuncs.test.js +0 -166
@@ -1,552 +0,0 @@
1
- import React, { useRef, useEffect } from "react";
2
- import ReactDOM from "react-dom";
3
- import { IntlProvider } from "react-intl";
4
- import { act } from "react-dom/test-utils";
5
- import { Provider } from "react-redux";
6
- import { MemoryRouter, Router } from "react-router-dom";
7
- import { createMemoryHistory } from "history";
8
- import sinon from "sinon";
9
- import { StylesProvider } from "@material-ui/core";
10
- import { getStyledClassSelector, generateClassName } from "../../utils/testUtils";
11
- import Tab, { PageTab } from "./Tab";
12
- import Bar, { TabBar, ScrollableBar, InnerBar, useTabScroll, StyledMenu, MenuButton } from "./Bar";
13
-
14
- describe("Bar", () => {
15
- let closers;
16
- beforeEach(() => {
17
- closers = [0, 1, 2, 3].map(id => sinon.spy().named("close" + id));
18
- });
19
-
20
- it("renders a bar containing tabs", () =>
21
- expect(
22
- <Provider
23
- store={{
24
- subscribe: () => {},
25
- dispatch: () => {},
26
- getState: () => ({}),
27
- }}
28
- >
29
- <MemoryRouter>
30
- <IntlProvider locale="en">
31
- <Bar
32
- module={{
33
- icon: "test",
34
- label: "A module",
35
- href: "/Foo/modu",
36
- mappedFrom: "/Foo/modu",
37
- }}
38
- pages={[
39
- {
40
- href: "/Foo/modu/1",
41
- mappedFrom: "/Foo/modu/1",
42
- label: "Page 1",
43
- mustTruncate: true,
44
- close: closers[0],
45
- },
46
- {
47
- href: "/Foo/modu/2",
48
- mappedFrom: "/Foo/modu/2",
49
- label: "Page 2",
50
- close: closers[1],
51
- active: true,
52
- },
53
- {
54
- href: "/Foo/modu/3",
55
- mappedFrom: "/Foo/modu/3",
56
- label: "Page 3",
57
- close: closers[2],
58
- },
59
- {
60
- href: "/Foo/modu/4",
61
- mappedFrom: "/Foo/modu/4",
62
- label: "Page 4",
63
- close: closers[3],
64
- },
65
- ]}
66
- />
67
- </IntlProvider>
68
- </MemoryRouter>
69
- </Provider>,
70
- "when mounted",
71
- "to satisfy",
72
- <Provider
73
- store={{
74
- subscribe: () => {},
75
- dispatch: () => {},
76
- getState: () => ({}),
77
- }}
78
- >
79
- <MemoryRouter>
80
- <IntlProvider locale="en">
81
- <TabBar>
82
- <Tab key="/Foo/modu" module icon="test" href="/Foo/modu" mappedFrom="/Foo/modu" label="A module" />
83
- <ScrollableBar>
84
- <Tab
85
- key="/Foo/modu/1"
86
- href="/Foo/modu/1"
87
- mappedFrom="/Foo/modu/1"
88
- label="Page 1"
89
- close={closers[0]}
90
- mustTruncate={true}
91
- hide={false}
92
- />
93
- <Tab
94
- key="/Foo/modu/2"
95
- href="/Foo/modu/2"
96
- mappedFrom="/Foo/modu/2"
97
- label="Page 2"
98
- close={closers[1]}
99
- hide={false}
100
- active
101
- />
102
- <Tab
103
- key="/Foo/modu/3"
104
- href="/Foo/modu/3"
105
- mappedFrom="/Foo/modu/3"
106
- label="Page 3"
107
- close={closers[2]}
108
- hide={false}
109
- />
110
- <Tab
111
- key="/Foo/modu/4"
112
- href="/Foo/modu/4"
113
- mappedFrom="/Foo/modu/4"
114
- label="Page 4"
115
- close={closers[3]}
116
- hide={false}
117
- />
118
- </ScrollableBar>
119
- </TabBar>
120
- </IntlProvider>
121
- </MemoryRouter>
122
- </Provider>,
123
- ));
124
-
125
- it("renders a bar containing only module", () =>
126
- expect(
127
- <Provider
128
- store={{
129
- subscribe: () => {},
130
- dispatch: () => {},
131
- getState: () => ({}),
132
- }}
133
- >
134
- <MemoryRouter>
135
- <IntlProvider locale="en">
136
- <Bar
137
- module={{
138
- icon: "test",
139
- label: "A module",
140
- href: "/Foo/modu",
141
- mappedFrom: "/Foo/modu",
142
- active: true,
143
- }}
144
- pages={[]}
145
- />
146
- </IntlProvider>
147
- </MemoryRouter>
148
- </Provider>,
149
- "when mounted",
150
- "to satisfy",
151
- <Provider
152
- store={{
153
- subscribe: () => {},
154
- dispatch: () => {},
155
- getState: () => ({}),
156
- }}
157
- >
158
- <MemoryRouter>
159
- <IntlProvider locale="en">
160
- <TabBar>
161
- <Tab key="/Foo/modu" module icon="test" href="/Foo/modu" mappedFrom="/Foo/modu" label="A module" active />
162
- <ScrollableBar />
163
- </TabBar>
164
- </IntlProvider>
165
- </MemoryRouter>
166
- </Provider>,
167
- ));
168
-
169
- it("hides tabs and shows dropdown when scrollable bar is too narrow to show them all", () => {
170
- // Needs to be fully rendered to work
171
- const root = document.createElement("div");
172
- document.body.append(root);
173
- const history = createMemoryHistory();
174
- sinon.spy(history, "push");
175
- ReactDOM.render(
176
- <Provider
177
- store={{
178
- subscribe: () => {},
179
- dispatch: () => {},
180
- getState: () => ({}),
181
- }}
182
- >
183
- <Router history={history}>
184
- <StylesProvider generateClassName={generateClassName}>
185
- <IntlProvider locale="en">
186
- <Bar
187
- module={{
188
- icon: "test",
189
- label: "A module",
190
- href: "/Foo/modu",
191
- mappedFrom: "/Foo/modu",
192
- }}
193
- pages={[
194
- {
195
- href: "/Foo/modu/1",
196
- mappedFrom: "/Foo/modu/1",
197
- label: "Page 1",
198
- close: closers[0],
199
- },
200
- {
201
- href: "/Foo/modu/2",
202
- mappedFrom: "/Foo/modu/2",
203
- label: "Page 2",
204
- close: closers[1],
205
- },
206
- {
207
- href: "/Foo/modu/3",
208
- mappedFrom: "/Foo/modu/3",
209
- label: "Page 3",
210
- close: closers[2],
211
- },
212
- {
213
- href: "/Foo/modu/4",
214
- mappedFrom: "/Foo/modu/4",
215
- label: "Page 4",
216
- close: closers[3],
217
- },
218
- ]}
219
- />
220
- </IntlProvider>
221
- </StylesProvider>
222
- </Router>
223
- </Provider>,
224
- root,
225
- );
226
- const bar = root.querySelector("*"); // Get the first child
227
- const barElement = bar.querySelector(getStyledClassSelector(InnerBar));
228
- const tabElements = barElement.querySelectorAll(getStyledClassSelector(PageTab));
229
- act(() => {
230
- // XXX: This is a nasty hack of jsdom, and may break unexpectedly
231
- Object.defineProperty(barElement, "offsetWidth", {
232
- value: 300,
233
- writable: true,
234
- });
235
- tabElements.forEach(tab => {
236
- Object.defineProperty(tab, "offsetWidth", {
237
- value: 130,
238
- });
239
- });
240
- window.dispatchEvent(new Event("resize"));
241
- });
242
- try {
243
- expect(
244
- bar,
245
- "to satisfy",
246
- <Provider
247
- store={{
248
- subscribe: () => {},
249
- dispatch: () => {},
250
- getState: () => ({}),
251
- }}
252
- >
253
- <MemoryRouter>
254
- <StylesProvider generateClassName={generateClassName}>
255
- <IntlProvider locale="en">
256
- <TabBar>
257
- <Tab key="/Foo/modu" module icon="test" href="/Foo/modu" mappedFrom="/Foo/modu" label="A module" />
258
- <ScrollableBar>
259
- <Tab
260
- key="/Foo/modu/1"
261
- href="/Foo/modu/1"
262
- mappedFrom="/Foo/modu/1"
263
- label="Page 1"
264
- close={closers[0]}
265
- hide={false}
266
- />
267
- <Tab
268
- key="/Foo/modu/2"
269
- href="/Foo/modu/2"
270
- mappedFrom="/Foo/modu/2"
271
- label="Page 2"
272
- close={closers[1]}
273
- hide={false}
274
- />
275
- <Tab
276
- key="/Foo/modu/3"
277
- href="/Foo/modu/3"
278
- mappedFrom="/Foo/modu/3"
279
- label="Page 3"
280
- close={closers[2]}
281
- hide={true}
282
- />
283
- <Tab
284
- key="/Foo/modu/4"
285
- href="/Foo/modu/4"
286
- mappedFrom="/Foo/modu/4"
287
- label="Page 4"
288
- close={closers[3]}
289
- hide={true}
290
- />
291
- </ScrollableBar>
292
- <StyledMenu
293
- id="navigationTabs"
294
- menuItems={[
295
- { label: "Page 1", id: "/Foo/modu/1" },
296
- { label: "Page 2", id: "/Foo/modu/2" },
297
- { label: "Page 3", id: "/Foo/modu/3" },
298
- { label: "Page 4", id: "/Foo/modu/4" },
299
- ]}
300
- >
301
- <MenuButton />
302
- </StyledMenu>
303
- </TabBar>
304
- </IntlProvider>
305
- </StylesProvider>
306
- </MemoryRouter>
307
- </Provider>,
308
- );
309
- expect(history.push, "was not called");
310
- act(() => bar.querySelector("#navigationTabsAnchor").click());
311
- expect(bar, "queried for first", "ul", "to have text", "Page 1Page 2Page 3Page 4"); // Menu is showing
312
- act(() => bar.querySelector("#\\/Foo\\/modu\\/3").click());
313
- expect(history.push, "to have calls satisfying", [{ args: ["/Foo/modu/3"] }]);
314
- } finally {
315
- ReactDOM.unmountComponentAtNode(root);
316
- document.body.removeChild(root);
317
- }
318
- });
319
- });
320
-
321
- describe("useTabScroll", () => {
322
- // XXX: BE ADVISED!
323
- // These tests rely on hacking jsdom's representation of layout
324
- // jsdom changes may break these!
325
- const ScrollTest = ({ pages, bar, tabs }) => {
326
- const barRef = useRef(null);
327
- const tabRefs = useRef({});
328
- useEffect(() => {
329
- Object.defineProperty(barRef.current, "offsetWidth", {
330
- value: bar || 0,
331
- writable: true,
332
- });
333
- Object.defineProperty(barRef.current, "scrollLeft", {
334
- value: 0,
335
- writable: true,
336
- });
337
- if (tabs) {
338
- pages.forEach(({ href }, idx) => {
339
- Object.defineProperty(tabRefs.current[href], "offsetWidth", {
340
- value: tabs[idx] || 0,
341
- });
342
- });
343
- }
344
- }, [pages, bar, tabs]);
345
- const { barWidth, tabEdges, lastShownTab, getTabRef, getBarRef } = useTabScroll(
346
- pages,
347
- true, // Debug flag
348
- { barRef, tabRefs },
349
- );
350
- return (
351
- <div id="outerElement">
352
- <InnerBar ref={getBarRef} data-width={barWidth}>
353
- {pages.map(({ href }, idx) => (
354
- <PageTab key={href} ref={getTabRef} data-href={href} data-edge={tabEdges[idx]} />
355
- ))}
356
- </InnerBar>
357
- Last shown tab: {lastShownTab}
358
- </div>
359
- );
360
- };
361
-
362
- let setupTest, root;
363
- beforeEach(() => {
364
- root = document.createElement("div");
365
- document.body.append(root);
366
- setupTest = (pages, widths) => {
367
- ReactDOM.render(
368
- <MemoryRouter>
369
- <ScrollTest pages={pages} {...widths} />
370
- </MemoryRouter>,
371
- root,
372
- );
373
- const element = root.querySelector("div#outerElement");
374
- const barElement = element.querySelector(getStyledClassSelector(InnerBar));
375
- const tabElements = barElement.querySelectorAll(getStyledClassSelector(PageTab));
376
- const setBarWidth = (width = 0) => {
377
- act(() => {
378
- barElement.offsetWidth = width;
379
- window.dispatchEvent(new Event("resize"));
380
- });
381
- };
382
- return { element, barElement, tabElements, setBarWidth };
383
- };
384
- });
385
- afterEach(() => {
386
- ReactDOM.unmountComponentAtNode(root);
387
- document.body.removeChild(root);
388
- });
389
-
390
- describe("test functions", () => {
391
- it("renders a bar with tabs", () => {
392
- const { element } = setupTest([{ href: "foo" }, { href: "bar" }]);
393
- expect(
394
- element,
395
- "to contain",
396
- <InnerBar>
397
- <PageTab data-href="foo" />
398
- <PageTab data-href="bar" />
399
- </InnerBar>,
400
- ).and("to have text", "Last shown tab: 2");
401
- });
402
-
403
- it("can set widths", () => {
404
- const { barElement, tabElements } = setupTest(
405
- [{ href: "foo" }, { href: "bar" }, { href: "bell" }, { href: "lerp" }],
406
- {
407
- bar: 100,
408
- tabs: [20, 25],
409
- },
410
- );
411
- return new Promise(resolve => setTimeout(resolve, 10)).then(() => {
412
- expect(barElement, "to have property", "offsetWidth", 100);
413
- expect(tabElements[0], "to have property", "offsetWidth", 20);
414
- expect(tabElements[1], "to have property", "offsetWidth", 25);
415
- expect(tabElements[2], "to have property", "offsetWidth", 0);
416
- expect(tabElements[3], "to have property", "offsetWidth", 0);
417
- });
418
- });
419
-
420
- it("can reset bar width", () => {
421
- const { barElement, setBarWidth } = setupTest(
422
- [{ href: "foo" }, { href: "bar" }, { href: "bell" }, { href: "lerp" }],
423
- {
424
- bar: 100,
425
- tabs: [50, 50, 50, 50],
426
- },
427
- );
428
- return new Promise(resolve => setTimeout(resolve, 10)).then(() => {
429
- expect(barElement, "to have property", "offsetWidth", 100);
430
- setBarWidth(170);
431
- expect(barElement, "to have property", "offsetWidth", 170);
432
- });
433
- });
434
-
435
- it("fires resize event if bar size reset", () => {
436
- const { setBarWidth } = setupTest([{ href: "foo" }, { href: "bar" }, { href: "bell" }, { href: "lerp" }], {
437
- bar: 100,
438
- tabs: [50, 50, 50, 50],
439
- });
440
- const handler = sinon.spy().named("resizeHandler");
441
- window.addEventListener("resize", handler);
442
- return new Promise(resolve => setTimeout(resolve, 10)).then(() => {
443
- try {
444
- setBarWidth(170);
445
- expect(handler, "was called once");
446
- } finally {
447
- window.removeEventListener("resize", handler);
448
- }
449
- });
450
- });
451
- });
452
-
453
- it("sets its width state", () => {
454
- const { element } = setupTest(
455
- [{ href: "foo" }, { href: "bar" }, { href: "bell" }, { href: "lerp", active: true }],
456
- {
457
- bar: 200,
458
- tabs: [75, 52, 65, 35],
459
- },
460
- );
461
- expect(
462
- element,
463
- "to contain",
464
- <InnerBar data-width="200">
465
- <PageTab data-href="foo" data-edge={75} />
466
- <PageTab data-href="bar" data-edge={75 + 52} />
467
- <PageTab data-href="bell" data-edge={75 + 52 + 65} />
468
- <PageTab data-href="lerp" data-edge={75 + 52 + 65 + 35} />
469
- </InnerBar>,
470
- );
471
- });
472
-
473
- it("scrolls one tab past the active element if possible", () => {
474
- const { barElement } = setupTest(
475
- [{ href: "foo" }, { href: "bar" }, { href: "bell", active: true }, { href: "lerp" }],
476
- {
477
- bar: 150,
478
- tabs: [75, 52, 65, 35],
479
- },
480
- );
481
- return new Promise(resolve => setTimeout(resolve, 10)).then(() => {
482
- expect(barElement.scrollLeft, "to equal", 75 + 52 + 65 + 35 - 150 + 7);
483
- });
484
- });
485
-
486
- it("scrolls to the active element if it is last", () => {
487
- const { barElement } = setupTest(
488
- [{ href: "foo" }, { href: "bar" }, { href: "bell" }, { href: "lerp", active: true }],
489
- {
490
- bar: 150,
491
- tabs: [75, 52, 65, 35],
492
- },
493
- );
494
- return new Promise(resolve => setTimeout(resolve, 10)).then(() => {
495
- expect(barElement.scrollLeft, "to equal", 75 + 52 + 65 + 35 - 150 + 7);
496
- });
497
- });
498
-
499
- it("sets last shown tab if bar wide enough to hold all", () => {
500
- const { element } = setupTest(
501
- [{ href: "foo" }, { href: "bar", active: true }, { href: "bell" }, { href: "lerp" }, { href: "meep" }],
502
- {
503
- bar: 300,
504
- tabs: [50, 50, 50, 50, 50],
505
- },
506
- );
507
- return new Promise(resolve => setTimeout(resolve, 10)).then(() => {
508
- expect(element, "to have text", "Last shown tab: 5");
509
- });
510
- });
511
-
512
- it("sets last shown tab according to how many will fit on screen", () => {
513
- const { element } = setupTest(
514
- [{ href: "foo", active: true }, { href: "bar" }, { href: "bell" }, { href: "lerp" }, { href: "meep" }],
515
- {
516
- bar: 400,
517
- tabs: [120, 120, 120, 120, 120],
518
- },
519
- );
520
- return new Promise(resolve => setTimeout(resolve, 10)).then(() => {
521
- expect(element, "to have text", "Last shown tab: 2");
522
- });
523
- });
524
-
525
- it("sets last shown tab to make sure active tab + next tab are shown", () => {
526
- const { element } = setupTest(
527
- [{ href: "foo" }, { href: "bar" }, { href: "bell", active: true }, { href: "lerp" }, { href: "meep" }],
528
- {
529
- bar: 300,
530
- tabs: [120, 120, 120, 120, 120],
531
- },
532
- );
533
- return new Promise(resolve => setTimeout(resolve, 10)).then(() => {
534
- expect(element, "to have text", "Last shown tab: 3");
535
- });
536
- });
537
-
538
- it("changes last shown tab if bar is resized", () => {
539
- const { element, setBarWidth } = setupTest(
540
- [{ href: "foo", active: true }, { href: "bar" }, { href: "bell" }, { href: "lerp" }, { href: "meep" }],
541
- {
542
- bar: 400,
543
- tabs: [120, 120, 120, 120, 120],
544
- },
545
- );
546
- return new Promise(resolve => setTimeout(resolve, 10)).then(() => {
547
- expect(element, "to have text", "Last shown tab: 2");
548
- setBarWidth(500);
549
- expect(element, "to have text", "Last shown tab: 3");
550
- });
551
- });
552
- });
@@ -1,156 +0,0 @@
1
- import React, { useEffect, useRef, useState } from "react";
2
- import styled, { css } from "styled-components";
3
- import { getThemeProp, ifFlag } from "../../utils";
4
- import { Link } from "react-router-dom";
5
- import Icon from "../Icon";
6
- import useLabelMessage from "../../hooks/useLabelMessage";
7
- import { Placeholder } from "../Text";
8
- import { useIntl } from "react-intl";
9
-
10
- export const PageTab = styled.div`
11
- flex: 0 0 auto;
12
- overflow: hidden;
13
- height: 38px;
14
- border: 1px solid ${getThemeProp(["colors", "borderLight"], "#cccccc")};
15
- border-top-left-radius: 5px;
16
- border-top-right-radius: 5px;
17
- margin-left: -1px;
18
- background-color: white;
19
-
20
- ${ifFlag(
21
- "active",
22
- css`
23
- border-bottom-color: white;
24
- color: ${getThemeProp(["colors", "application", "base"], "#ccc")};
25
- `,
26
- css`
27
- color: ${getThemeProp(["colors", "textMedium"], "#999999")};
28
- `,
29
- )};
30
-
31
- ${ifFlag(
32
- "outsideScope",
33
- css`
34
- background-color: #eeeeee;
35
- `,
36
- )}
37
-
38
- ${ifFlag(
39
- "hide",
40
- css`
41
- visibility: hidden;
42
- `,
43
- )}
44
- `;
45
-
46
- // XXX: The below contains an IE10/IE11 targeting CSS hack
47
-
48
- export const ModuleTab = styled(PageTab)`
49
- flex-grow: 0;
50
- flex-shrink: 0;
51
- margin-left: 0px;
52
- z-index: 1;
53
- @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
54
- flex-grow: 1;
55
- }
56
- `;
57
-
58
- const FilteredLink = ({ outsideScope, mustTruncate, ...props }) => <Link {...props} />;
59
-
60
- export const TabLink = styled(FilteredLink)`
61
- min-width: 100px;
62
- overflow: hidden;
63
- color: inherit;
64
- text-decoration: none;
65
- display: flex;
66
- justify-content: center;
67
- padding: 11px 15px;
68
-
69
- ${ifFlag(
70
- "outsideScope",
71
- css`
72
- cursor: not-allowed;
73
- `,
74
- )};
75
- ${ifFlag(
76
- "mustTruncate",
77
- css`
78
- max-width: 220px;
79
- `,
80
- )};
81
- `;
82
-
83
- export const ModuleIcon = styled(Icon)`
84
- vertical-align: middle;
85
- font-size: 20px;
86
- margin-right: 10px;
87
- margin-top: -3px;
88
- `;
89
-
90
- export const TabText = styled.span`
91
- min-width: 50px;
92
- white-space: nowrap;
93
- overflow: hidden;
94
- text-overflow: ellipsis;
95
- `;
96
-
97
- export const CloseIcon = styled(Icon).attrs(props => ({
98
- id: getThemeProp(["icons", "close"], "close")(props),
99
- }))`
100
- flex: 0 0 auto;
101
- margin-left: 10px;
102
- margin-right: -5px;
103
- font-size: 14px;
104
- color: ${getThemeProp(["colors", "textMedium"], "#999999")};
105
-
106
- &:hover {
107
- color: ${getThemeProp(["colors", "application", "base"], "#ccc")};
108
- }
109
- `;
110
-
111
- const Tab = (
112
- { href, label, mustTruncate, icon, module, active, close = () => {}, outsideScope, scopeNotSupported, hide },
113
- ref,
114
- ) => {
115
- const ThisTab = module ? ModuleTab : PageTab;
116
-
117
- const { formatMessage } = useIntl();
118
- const tabTextRef = useRef(null);
119
- const [aTitle, setTitle] = useState(null);
120
- const buildMessage = message => formatMessage(message, message.values);
121
- const [labelMessage] = useLabelMessage(label, buildMessage);
122
-
123
- useEffect(() => {
124
- if (scopeNotSupported) {
125
- close();
126
- } else if (mustTruncate && tabTextRef.current && tabTextRef.current.offsetWidth < tabTextRef.current.scrollWidth) {
127
- setTitle(labelMessage);
128
- }
129
- }, [scopeNotSupported, tabTextRef, setTitle, labelMessage, mustTruncate, close]);
130
-
131
- return (
132
- <ThisTab ref={ref} active={active} outsideScope={outsideScope} hide={hide || scopeNotSupported} data-href={href}>
133
- <TabLink
134
- to={href}
135
- mustTruncate={mustTruncate}
136
- outsideScope={outsideScope}
137
- onClick={
138
- outsideScope
139
- ? event => {
140
- event.preventDefault();
141
- event.stopPropagation();
142
- }
143
- : () => {}
144
- }
145
- >
146
- {module ? <ModuleIcon id={icon} /> : null}
147
- <TabText ref={tabTextRef} title={aTitle}>
148
- {labelMessage ? labelMessage : <Placeholder />}
149
- </TabText>
150
- {module ? null : <CloseIcon onClick={close} />}
151
- </TabLink>
152
- </ThisTab>
153
- );
154
- };
155
-
156
- export default React.forwardRef(Tab);