@luscii-healthtech/web-ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. package/README.md +181 -0
  2. package/dist/components/Acknowledgement/Acknowledgement.d.ts +22 -0
  3. package/dist/components/Avatar/Avatar.d.ts +29 -0
  4. package/dist/components/Badge/Badge.d.ts +7 -0
  5. package/dist/components/Button/Button.d.ts +5 -0
  6. package/dist/components/Button/Button.types.d.ts +32 -0
  7. package/dist/components/Button/ButtonIcon.d.ts +7 -0
  8. package/dist/components/ButtonV2/ButtonV2.d.ts +13 -0
  9. package/dist/components/ButtonV2/PrimaryButton.d.ts +12 -0
  10. package/dist/components/ButtonV2/SecondaryButton.d.ts +8 -0
  11. package/dist/components/ButtonV2/TertiaryButton.d.ts +8 -0
  12. package/dist/components/Carousel/Carousel.d.ts +8 -0
  13. package/dist/components/Carousel/GliderContainer.d.ts +7 -0
  14. package/dist/components/CenteredHero/CenteredHero.d.ts +22 -0
  15. package/dist/components/Checkbox/Checkbox.d.ts +17 -0
  16. package/dist/components/ConfirmationDialog/ConfirmationDialog.d.ts +33 -0
  17. package/dist/components/Datepicker/Datepicker.d.ts +24 -0
  18. package/dist/components/Dropdown/Dropdown.d.ts +47 -0
  19. package/dist/components/EmptyListMessage/EmptyListMessage.d.ts +14 -0
  20. package/dist/components/ErrorBlock/ErrorBlock.d.ts +13 -0
  21. package/dist/components/Icons/AddIcon.d.ts +3 -0
  22. package/dist/components/Icons/AlertsIcon.d.ts +6 -0
  23. package/dist/components/Icons/BellIcon.d.ts +6 -0
  24. package/dist/components/Icons/ChartIcon.d.ts +3 -0
  25. package/dist/components/Icons/ChatBox.d.ts +5 -0
  26. package/dist/components/Icons/CheckIcon.d.ts +2 -0
  27. package/dist/components/Icons/ChevronIcon.d.ts +8 -0
  28. package/dist/components/Icons/CrossIcon.d.ts +7 -0
  29. package/dist/components/Icons/DeleteIcon.d.ts +6 -0
  30. package/dist/components/Icons/DownArrowIcon.d.ts +6 -0
  31. package/dist/components/Icons/DragIcon.d.ts +3 -0
  32. package/dist/components/Icons/EditIcon.d.ts +6 -0
  33. package/dist/components/Icons/EmptyStateDashboardIcon.d.ts +2 -0
  34. package/dist/components/Icons/ExclamationMarkIcon.d.ts +6 -0
  35. package/dist/components/Icons/EyeIcon.d.ts +3 -0
  36. package/dist/components/Icons/GearIcon.d.ts +3 -0
  37. package/dist/components/Icons/GroupIcon.d.ts +3 -0
  38. package/dist/components/Icons/HeartIcon.d.ts +6 -0
  39. package/dist/components/Icons/LeftArrowIcon.d.ts +6 -0
  40. package/dist/components/Icons/LightBulbIcon.d.ts +6 -0
  41. package/dist/components/Icons/LockIcon.d.ts +6 -0
  42. package/dist/components/Icons/MessagesIcon.d.ts +6 -0
  43. package/dist/components/Icons/NotesIcon.d.ts +6 -0
  44. package/dist/components/Icons/PinIcon.d.ts +6 -0
  45. package/dist/components/Icons/PrintIcon.d.ts +3 -0
  46. package/dist/components/Icons/RightArrowIcon.d.ts +6 -0
  47. package/dist/components/Icons/SmallCircleIcon.d.ts +6 -0
  48. package/dist/components/Icons/SmallDiamondIcon.d.ts +6 -0
  49. package/dist/components/Icons/SmallSquareIcon.d.ts +6 -0
  50. package/dist/components/Icons/SpaceRocketIcon.d.ts +6 -0
  51. package/dist/components/Icons/types/IconProps.type.d.ts +3 -0
  52. package/dist/components/InfoBlock/InfoBlock.d.ts +14 -0
  53. package/dist/components/InfoField/InfoField.d.ts +18 -0
  54. package/dist/components/Input/Input.d.ts +44 -0
  55. package/dist/components/Line/Line.d.ts +14 -0
  56. package/dist/components/ListItem/ListItem.d.ts +9 -0
  57. package/dist/components/ListTable/ListTable.d.ts +35 -0
  58. package/dist/components/ListTable/ListTableCell.d.ts +10 -0
  59. package/dist/components/ListTable/ListTableHeader.d.ts +7 -0
  60. package/dist/components/ListTable/ListTableRow.d.ts +9 -0
  61. package/dist/components/LoadingIndicator/LoadingIndicator.d.ts +11 -0
  62. package/dist/components/Menu/Menu.d.ts +14 -0
  63. package/dist/components/Modal/Modal.d.ts +31 -0
  64. package/dist/components/Modal/ModalWithButtons.d.ts +9 -0
  65. package/dist/components/MultiSelect/MultiSelect.d.ts +25 -0
  66. package/dist/components/MultiSelect/MultiSelectUtils.d.ts +1 -0
  67. package/dist/components/NavMenu/NavLayout.d.ts +20 -0
  68. package/dist/components/NavMenu/NavMenu.d.ts +1 -0
  69. package/dist/components/NavMenu/NavMenuContent.d.ts +7 -0
  70. package/dist/components/NavMenu/NavMenuItem.d.ts +15 -0
  71. package/dist/components/NotificationBanner/NotificationBanner.d.ts +22 -0
  72. package/dist/components/Page/CRUDPage.d.ts +43 -0
  73. package/dist/components/Page/Page.d.ts +58 -0
  74. package/dist/components/PaginationMenu/PaginationMenu.d.ts +20 -0
  75. package/dist/components/PaginationMenu/PaginationMenuLarge.d.ts +13 -0
  76. package/dist/components/PaginationMenu/PaginationMenuSmall.d.ts +8 -0
  77. package/dist/components/PreviewPhone/PreviewPhone.d.ts +7 -0
  78. package/dist/components/PreviewPhone/useWindowDimensions.d.ts +4 -0
  79. package/dist/components/Radio/Radio.d.ts +18 -0
  80. package/dist/components/RadioGroup/RadioGroup.d.ts +31 -0
  81. package/dist/components/Section/Section.d.ts +15 -0
  82. package/dist/components/Select/LegacySelect.d.ts +32 -0
  83. package/dist/components/Select/Select.d.ts +6 -0
  84. package/dist/components/Select/options.transformer.d.ts +14 -0
  85. package/dist/components/Select/select.utils.d.ts +7 -0
  86. package/dist/components/SettingsMenuButton/SettingsMenuButton.d.ts +16 -0
  87. package/dist/components/Spinner/Spinner.d.ts +6 -0
  88. package/dist/components/Steps/Step.d.ts +10 -0
  89. package/dist/components/Steps/Steps.d.ts +11 -0
  90. package/dist/components/Switcher/Switcher.d.ts +26 -0
  91. package/dist/components/Switcher/SwitcherItem.d.ts +24 -0
  92. package/dist/components/TabLinks/TabLinks.d.ts +14 -0
  93. package/dist/components/Tabbar/Tabbar.d.ts +10 -0
  94. package/dist/components/Tabbar/TabbarItem.d.ts +15 -0
  95. package/dist/components/Tag/Tag.d.ts +17 -0
  96. package/dist/components/Tag/TagGroup.d.ts +13 -0
  97. package/dist/components/Text/LegacyText.d.ts +37 -0
  98. package/dist/components/Text/Text.d.ts +27 -0
  99. package/dist/components/TextEditor/TextEditor.d.ts +14 -0
  100. package/dist/components/TextEditorV2/TextEditorV2.d.ts +6 -0
  101. package/dist/components/TextLink/TextLink.d.ts +11 -0
  102. package/dist/components/TextListItem/TextListItem.d.ts +12 -0
  103. package/dist/components/Textarea/Textarea.d.ts +22 -0
  104. package/dist/components/Title/LegacyTitle.d.ts +22 -0
  105. package/dist/components/Title/Title.d.ts +14 -0
  106. package/dist/components/ViewItem/ViewItem.d.ts +16 -0
  107. package/dist/index.d.ts +8 -0
  108. package/dist/index.js +8 -0
  109. package/dist/types/general.types.d.ts +7 -0
  110. package/dist/utils/useOutsideClick.d.ts +2 -0
  111. package/dist/web-ui.cjs.development.js +23 -0
  112. package/dist/web-ui.cjs.development.js.map +1 -0
  113. package/dist/web-ui.cjs.production.min.js +2 -0
  114. package/dist/web-ui.cjs.production.min.js.map +1 -0
  115. package/dist/web-ui.esm.js +17 -0
  116. package/dist/web-ui.esm.js.map +1 -0
  117. package/package.json +122 -0
  118. package/src/assets/add.svg +5 -0
  119. package/src/assets/add_hover.svg +4 -0
  120. package/src/assets/big-menu-icon-hover.svg +6 -0
  121. package/src/assets/big-menu-icon.svg +6 -0
  122. package/src/assets/check-cross-icon.svg +7 -0
  123. package/src/assets/check-icon-primary.svg +5 -0
  124. package/src/assets/check-icon.svg +3 -0
  125. package/src/assets/chevron-double.svg +3 -0
  126. package/src/assets/close.svg +3 -0
  127. package/src/assets/color-variant-cross.svg +3 -0
  128. package/src/assets/cross-dark.svg +3 -0
  129. package/src/assets/delete.svg +4 -0
  130. package/src/assets/delete_hover.svg +4 -0
  131. package/src/assets/edit.svg +6 -0
  132. package/src/assets/edit_hover.svg +6 -0
  133. package/src/assets/error-icon.svg +7 -0
  134. package/src/assets/grid-view-icon-active.svg +6 -0
  135. package/src/assets/grid-view-icon.svg +6 -0
  136. package/src/assets/groups.svg +3 -0
  137. package/src/assets/hamburger.svg +5 -0
  138. package/src/assets/happy-star.svg +9 -0
  139. package/src/assets/hcps.svg +3 -0
  140. package/src/assets/info-icon.svg +6 -0
  141. package/src/assets/left-arrow-blue.svg +3 -0
  142. package/src/assets/left-arrow-grey.svg +3 -0
  143. package/src/assets/list-view-icon-active.svg +3 -0
  144. package/src/assets/list-view-icon.svg +3 -0
  145. package/src/assets/loading.svg +16 -0
  146. package/src/assets/modal-close-icon-active.svg +9 -0
  147. package/src/assets/modal-close-icon.svg +9 -0
  148. package/src/assets/no-open-alerts.svg +19 -0
  149. package/src/assets/patients.svg +3 -0
  150. package/src/assets/phone-mockup.svg +9 -0
  151. package/src/assets/programs.svg +3 -0
  152. package/src/assets/right-arrow-blue.svg +3 -0
  153. package/src/assets/right-arrow-grey.svg +3 -0
  154. package/src/assets/search-cancel.svg +3 -0
  155. package/src/assets/search-not-found.svg +70 -0
  156. package/src/assets/search.svg +3 -0
  157. package/src/assets/spinner-gray.svg +6 -0
  158. package/src/assets/spinner.svg +6 -0
  159. package/src/assets/starIcon.svg +3 -0
  160. package/src/assets/success-icon.svg +7 -0
  161. package/src/components/Acknowledgement/Acknowledgement.js +61 -0
  162. package/src/components/Acknowledgement/Acknowledgement.scss +49 -0
  163. package/src/components/Avatar/Avatar.js +81 -0
  164. package/src/components/Avatar/Avatar.scss +153 -0
  165. package/src/components/Badge/Badge.tsx +23 -0
  166. package/src/components/Button/Button.examples.md +46 -0
  167. package/src/components/Button/Button.tsx +200 -0
  168. package/src/components/Button/Button.types.ts +41 -0
  169. package/src/components/Button/ButtonIcon.tsx +42 -0
  170. package/src/components/ButtonV2/ButtonV2.tsx +91 -0
  171. package/src/components/ButtonV2/PrimaryButton.tsx +43 -0
  172. package/src/components/ButtonV2/SecondaryButton.tsx +31 -0
  173. package/src/components/ButtonV2/TertiaryButton.tsx +31 -0
  174. package/src/components/Carousel/Carousel.tsx +52 -0
  175. package/src/components/Carousel/GliderContainer.scss +13 -0
  176. package/src/components/Carousel/GliderContainer.tsx +22 -0
  177. package/src/components/CenteredHero/CenteredHero.js +50 -0
  178. package/src/components/Checkbox/Checkbox.scss +115 -0
  179. package/src/components/Checkbox/Checkbox.tsx +114 -0
  180. package/src/components/ConfirmationDialog/ConfirmationDialog.scss +15 -0
  181. package/src/components/ConfirmationDialog/ConfirmationDialog.tsx +84 -0
  182. package/src/components/Datepicker/Datepicker.js +96 -0
  183. package/src/components/Datepicker/Datepicker.scss +331 -0
  184. package/src/components/Dropdown/Dropdown.js +364 -0
  185. package/src/components/Dropdown/Dropdown.scss +83 -0
  186. package/src/components/EmptyListMessage/EmptyListMessage.tsx +34 -0
  187. package/src/components/ErrorBlock/ErrorBlock.js +24 -0
  188. package/src/components/ErrorBlock/ErrorBlock.scss +20 -0
  189. package/src/components/Icons/AddIcon.tsx +27 -0
  190. package/src/components/Icons/AlertsIcon.tsx +26 -0
  191. package/src/components/Icons/BellIcon.tsx +26 -0
  192. package/src/components/Icons/ChartIcon.tsx +20 -0
  193. package/src/components/Icons/ChatBox.tsx +23 -0
  194. package/src/components/Icons/CheckIcon.tsx +23 -0
  195. package/src/components/Icons/ChevronIcon.tsx +30 -0
  196. package/src/components/Icons/CrossIcon.tsx +26 -0
  197. package/src/components/Icons/DeleteIcon.tsx +23 -0
  198. package/src/components/Icons/DownArrowIcon.tsx +17 -0
  199. package/src/components/Icons/DragIcon.tsx +23 -0
  200. package/src/components/Icons/EditIcon.tsx +23 -0
  201. package/src/components/Icons/EmptyStateDashboardIcon.tsx +130 -0
  202. package/src/components/Icons/ExclamationMarkIcon.tsx +23 -0
  203. package/src/components/Icons/EyeIcon.tsx +21 -0
  204. package/src/components/Icons/GearIcon.tsx +21 -0
  205. package/src/components/Icons/GroupIcon.tsx +21 -0
  206. package/src/components/Icons/HeartIcon.tsx +23 -0
  207. package/src/components/Icons/LeftArrowIcon.tsx +23 -0
  208. package/src/components/Icons/LightBulbIcon.tsx +28 -0
  209. package/src/components/Icons/LockIcon.tsx +23 -0
  210. package/src/components/Icons/MessagesIcon.tsx +23 -0
  211. package/src/components/Icons/NotesIcon.tsx +23 -0
  212. package/src/components/Icons/PinIcon.tsx +23 -0
  213. package/src/components/Icons/PrintIcon.tsx +15 -0
  214. package/src/components/Icons/RightArrowIcon.tsx +23 -0
  215. package/src/components/Icons/SmallCircleIcon.tsx +21 -0
  216. package/src/components/Icons/SmallDiamondIcon.tsx +31 -0
  217. package/src/components/Icons/SmallSquareIcon.tsx +21 -0
  218. package/src/components/Icons/SpaceRocketIcon.tsx +23 -0
  219. package/src/components/Icons/types/IconProps.type.ts +3 -0
  220. package/src/components/InfoBlock/InfoBlock.js +24 -0
  221. package/src/components/InfoBlock/InfoBlock.scss +20 -0
  222. package/src/components/InfoField/InfoField.tsx +86 -0
  223. package/src/components/Input/Input.examples.md +94 -0
  224. package/src/components/Input/Input.js +141 -0
  225. package/src/components/Line/Line.js +38 -0
  226. package/src/components/ListItem/ListItem.scss +20 -0
  227. package/src/components/ListItem/ListItem.tsx +26 -0
  228. package/src/components/ListTable/ListTable.tsx +157 -0
  229. package/src/components/ListTable/ListTableCell.tsx +67 -0
  230. package/src/components/ListTable/ListTableHeader.tsx +33 -0
  231. package/src/components/ListTable/ListTableRow.tsx +46 -0
  232. package/src/components/LoadingIndicator/LoadingIndicator.scss +50 -0
  233. package/src/components/LoadingIndicator/LoadingIndicator.tsx +44 -0
  234. package/src/components/Menu/Menu.js +74 -0
  235. package/src/components/Menu/Menu.scss +27 -0
  236. package/src/components/Modal/Modal.scss +117 -0
  237. package/src/components/Modal/Modal.tsx +104 -0
  238. package/src/components/Modal/ModalWithButtons.tsx +34 -0
  239. package/src/components/MultiSelect/MultiSelect.js +117 -0
  240. package/src/components/MultiSelect/MultiSelect.scss +29 -0
  241. package/src/components/MultiSelect/MultiSelectUtils.js +23 -0
  242. package/src/components/NavMenu/NavLayout.tsx +40 -0
  243. package/src/components/NavMenu/NavMenu.js +35 -0
  244. package/src/components/NavMenu/NavMenuContent.tsx +23 -0
  245. package/src/components/NavMenu/NavMenuItem.tsx +96 -0
  246. package/src/components/NotificationBanner/NotificationBanner.tsx +57 -0
  247. package/src/components/Page/CRUDPage.js +123 -0
  248. package/src/components/Page/CRUDPage.scss +32 -0
  249. package/src/components/Page/Page.js +102 -0
  250. package/src/components/Page/Page.scss +59 -0
  251. package/src/components/PaginationMenu/PaginationMenu.js +31 -0
  252. package/src/components/PaginationMenu/PaginationMenuLarge.tsx +94 -0
  253. package/src/components/PaginationMenu/PaginationMenuSmall.tsx +40 -0
  254. package/src/components/PreviewPhone/PreviewPhone.tsx +53 -0
  255. package/src/components/PreviewPhone/useWindowDimensions.js +26 -0
  256. package/src/components/Radio/Radio.js +99 -0
  257. package/src/components/Radio/Radio.scss +58 -0
  258. package/src/components/RadioGroup/RadioGroup.js +63 -0
  259. package/src/components/RadioGroup/RadioGroup.scss +37 -0
  260. package/src/components/Section/Section.scss +74 -0
  261. package/src/components/Section/Section.tsx +67 -0
  262. package/src/components/Select/LegacySelect.js +114 -0
  263. package/src/components/Select/Select.examples.md +161 -0
  264. package/src/components/Select/Select.tsx +136 -0
  265. package/src/components/Select/options.transformer.ts +36 -0
  266. package/src/components/Select/select.utils.spec.ts +63 -0
  267. package/src/components/Select/select.utils.ts +45 -0
  268. package/src/components/SettingsMenuButton/SettingsMenuButton.tsx +111 -0
  269. package/src/components/Spinner/Spinner.tsx +23 -0
  270. package/src/components/Steps/Step.tsx +22 -0
  271. package/src/components/Steps/Steps.tsx +24 -0
  272. package/src/components/Switcher/Switcher.js +58 -0
  273. package/src/components/Switcher/SwitcherItem.js +61 -0
  274. package/src/components/Switcher/SwitcherItem.scss +67 -0
  275. package/src/components/TabLinks/TabLinks.tsx +63 -0
  276. package/src/components/Tabbar/Tabbar.tsx +29 -0
  277. package/src/components/Tabbar/TabbarItem.tsx +53 -0
  278. package/src/components/Tag/Tag.tsx +39 -0
  279. package/src/components/Tag/TagGroup.tsx +25 -0
  280. package/src/components/Text/LegacyText.js +78 -0
  281. package/src/components/Text/Text.scss +67 -0
  282. package/src/components/Text/Text.tsx +81 -0
  283. package/src/components/TextEditor/TextEditor.js +61 -0
  284. package/src/components/TextEditor/TextEditor.scss +14 -0
  285. package/src/components/TextEditorV2/TextEditorV2.js +58 -0
  286. package/src/components/TextEditorV2/TextEditorV2.scss +110 -0
  287. package/src/components/TextLink/TextLink.tsx +42 -0
  288. package/src/components/TextListItem/TextListItem.js +31 -0
  289. package/src/components/TextListItem/TextListItem.scss +10 -0
  290. package/src/components/Textarea/Textarea.js +108 -0
  291. package/src/components/Textarea/Textarea.scss +56 -0
  292. package/src/components/Title/LegacyTitle.js +64 -0
  293. package/src/components/Title/Title.scss +65 -0
  294. package/src/components/Title/Title.tsx +57 -0
  295. package/src/components/ViewItem/ViewItem.tsx +73 -0
  296. package/src/index.tsx +14 -0
  297. package/src/styles/_colors.scss +59 -0
  298. package/src/styles/_layout.scss +64 -0
  299. package/src/styles/_shadows.scss +19 -0
  300. package/src/styles/_typography.scss +8 -0
  301. package/src/styles/_utils.scss +45 -0
  302. package/src/styles/fonts/avenir/3A0AF8_0_0.eot +0 -0
  303. package/src/styles/fonts/avenir/3A0AF8_0_0.ttf +0 -0
  304. package/src/styles/fonts/avenir/3A0AF8_0_0.woff +0 -0
  305. package/src/styles/fonts/avenir/3A0AF8_0_0.woff2 +0 -0
  306. package/src/styles/fonts/avenir/3A0AF8_1_0.eot +0 -0
  307. package/src/styles/fonts/avenir/3A0AF8_1_0.ttf +0 -0
  308. package/src/styles/fonts/avenir/3A0AF8_1_0.woff +0 -0
  309. package/src/styles/fonts/avenir/3A0AF8_1_0.woff2 +0 -0
  310. package/src/types/general.types.ts +11 -0
  311. package/src/utils/useOutsideClick.js +19 -0
@@ -0,0 +1,117 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import PropTypes from "prop-types";
3
+
4
+ import Checkbox from "../Checkbox/Checkbox";
5
+ import { TEXT_TYPE_OPTIONS } from "../Text/LegacyText";
6
+
7
+ import { handleImplicitSelect } from "./MultiSelectUtils";
8
+
9
+ import "./MultiSelect.scss";
10
+
11
+ export function MultiSelect({
12
+ checkboxList,
13
+ radioLabel,
14
+ onChange,
15
+ validationError,
16
+ name,
17
+ implicitSelect,
18
+ radioOnDemand,
19
+ }) {
20
+ const [list, setList] = useState(checkboxList);
21
+
22
+ useEffect(() => {
23
+ onChange({
24
+ target: {
25
+ name,
26
+ value: list,
27
+ },
28
+ });
29
+ }, [list]);
30
+
31
+ function handleChange(event, indexSelected) {
32
+ let newList = [...list];
33
+
34
+ const isChecked = event.target.checked;
35
+ const updateCheckbox = { ...list[indexSelected], isChecked: isChecked, isOn: false };
36
+ newList.splice(indexSelected, 1, updateCheckbox);
37
+
38
+ if (implicitSelect) {
39
+ newList = handleImplicitSelect(implicitSelect, event, newList, "isChecked");
40
+ }
41
+ setList(newList);
42
+ }
43
+
44
+ function handleRadioChange(event, indexSelected) {
45
+ let newList = [...list];
46
+
47
+ const isChecked = event.target.checked;
48
+ const updateCheckbox = { ...list[indexSelected], isOn: isChecked };
49
+ newList.splice(indexSelected, 1, updateCheckbox);
50
+
51
+ if (implicitSelect) {
52
+ newList = handleImplicitSelect(implicitSelect, event, newList, "isOn");
53
+ }
54
+
55
+ setList(newList);
56
+ }
57
+
58
+ return (
59
+ <ul>
60
+ {list.map((checkbox, index) => {
61
+ const text = [checkbox.name];
62
+
63
+ if (checkbox.description && checkbox.description !== checkbox.name) {
64
+ text.push(checkbox.description);
65
+ }
66
+
67
+ return (
68
+ <div className="cweb-multiselect" key={checkbox.identifier}>
69
+ <Checkbox
70
+ text={text.join(" - ")}
71
+ name={checkbox.identifier}
72
+ isChecked={checkbox.isChecked || false}
73
+ onChange={(event) => handleChange(event, index)}
74
+ className="cweb-multiselect-checkbox"
75
+ textType={TEXT_TYPE_OPTIONS.SMALL_DARK}
76
+ error={validationError}
77
+ key={checkbox.identifier}
78
+ />
79
+
80
+ {radioOnDemand && (
81
+ <div className="cweb-switch-wrapper">
82
+ <p className="cweb-switch-title">{radioLabel}</p>
83
+ <Checkbox
84
+ type="switch"
85
+ name={`${checkbox.identifier}-toggle`}
86
+ isChecked={checkbox.isOn}
87
+ onChange={(event) => handleRadioChange(event, index)}
88
+ textType={TEXT_TYPE_OPTIONS.SMALL_DARK}
89
+ error={validationError}
90
+ className="cweb-multiselect-switch"
91
+ isDisabled={!checkbox.isChecked}
92
+ key={checkbox.identifier}
93
+ />
94
+ </div>
95
+ )}
96
+ </div>
97
+ );
98
+ })}
99
+ </ul>
100
+ );
101
+ }
102
+
103
+ MultiSelect.propTypes = {
104
+ name: PropTypes.string,
105
+ checkboxList: PropTypes.arrayOf(
106
+ PropTypes.shape({
107
+ isChecked: PropTypes.bool,
108
+ name: PropTypes.string.isRequired,
109
+ description: PropTypes.string,
110
+ identifier: PropTypes.string.isRequired,
111
+ })
112
+ ),
113
+ onChange: PropTypes.func,
114
+ validationError: PropTypes.string,
115
+ implicitSelect: PropTypes.object,
116
+ radioOnDemand: PropTypes.bool,
117
+ };
@@ -0,0 +1,29 @@
1
+ @import "../../styles/colors";
2
+
3
+ .cweb-multiselect {
4
+ display: flex;
5
+ .cweb-multiselect-checkbox {
6
+ margin-bottom: 0px;
7
+ margin-top: 0.5rem;
8
+ width: 100%;
9
+ text-transform: capitalize;
10
+ }
11
+
12
+ .cweb-switch-wrapper {
13
+ display: flex;
14
+ .cweb-multiselect-switch {
15
+ width: 50px;
16
+ .cweb-checkbox.type-switch.is-checked {
17
+ .cweb-checkbox-icon-container {
18
+ background-color: $color-branding-support-1;
19
+ }
20
+ }
21
+ }
22
+ .cweb-switch-title {
23
+ width: 100px;
24
+ color: $color-text-lighter;
25
+ font-size: 16px;
26
+ line-height: 1.8em;
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,23 @@
1
+ export function handleImplicitSelect(implicitSelected, event, list, property) {
2
+ /*For certain values, if one checkbox is selected
3
+ other checkboxes have to be selected/unselected automatically */
4
+ const newList = [...list];
5
+ const selectCheckboxName = event.target.name;
6
+ const isChecked = event.target.checked;
7
+ const implicitSelectedValues = implicitSelected[selectCheckboxName];
8
+
9
+ if (implicitSelectedValues) {
10
+ implicitSelectedValues.forEach((value) => {
11
+ const selectedIndex = newList.findIndex((checkbox) => value === checkbox.identifier);
12
+ let upadteCheckbox;
13
+ if (property === "isChecked") {
14
+ //if normal checkbox is false the switcher must be set to false as well
15
+ upadteCheckbox = { ...newList[selectedIndex], isChecked: isChecked, isOn: false };
16
+ } else {
17
+ upadteCheckbox = { ...newList[selectedIndex], [property]: isChecked };
18
+ }
19
+ newList.splice(selectedIndex, 1, upadteCheckbox);
20
+ });
21
+ }
22
+ return newList;
23
+ }
@@ -0,0 +1,40 @@
1
+ import React from "react";
2
+ import classNames from "classnames";
3
+
4
+ export interface NavMenuLayoutProps {
5
+ menu: JSX.Element;
6
+ children: JSX.Element | JSX.Element[]; //rendered as the page
7
+ patientSidebar?: JSX.Element; //if passed will show the patients sidebar
8
+ isNavDisabled?: boolean; //don't show any navigation, for instance when constrained to a single patient
9
+ disableScrolling?: boolean;
10
+ }
11
+
12
+ /**
13
+ *
14
+ * @param props {NavMenuLayoutProps} - explaining specifically the `disableScrolling` prop:
15
+ *
16
+ * The patient overview page has some challenges we want to overcome in regards to the multiple scrollable
17
+ * content (the charts and the action bar with alerts, etc).
18
+ *
19
+ * In order to have the setup working on the patient overview page and the rest of the application, we have to
20
+ * progamatically disable/enable if that location will have a normal scrolling mechanism with specific margin/padding,
21
+ * or we will need to let the components take care of that.
22
+ */
23
+ export const NavLayout = (props: NavMenuLayoutProps): JSX.Element => {
24
+ return (
25
+ <div className={"flex flex-col mb-3 lg:mb-0 lg:flex-row h-full w-full"}>
26
+ {!props.isNavDisabled && (
27
+ <>
28
+ {props.menu}
29
+ {props.patientSidebar && props.patientSidebar}
30
+ </>
31
+ )}
32
+ <div
33
+ data-test-id="page-main-content"
34
+ className={classNames(["w-full", { "max-h-screen overflow-y-auto px-4 lg:px-8": !props.disableScrolling }])}
35
+ >
36
+ {props.children}
37
+ </div>
38
+ </div>
39
+ );
40
+ };
@@ -0,0 +1,35 @@
1
+ import * as React from "react";
2
+ import { useState } from "react";
3
+
4
+ import Button from "../Button/Button";
5
+
6
+ import { NavMenuContent } from "./NavMenuContent";
7
+
8
+ export function NavMenu(props) {
9
+ const [isOpen, setIsOpen] = useState(false);
10
+
11
+ const handleToggleOpen = () => {
12
+ setIsOpen(!isOpen);
13
+ };
14
+
15
+ return (
16
+ <>
17
+ <div className={"hidden h-screen lg:flex"}>
18
+ <NavMenuContent items={props.items} />
19
+ </div>
20
+ <div className={"lg:hidden relative bg-nav-header w-screen flex items-center p-2 shadow-lg"}>
21
+ <Button
22
+ hasIcon={true}
23
+ role="secondaryDark"
24
+ iconName={isOpen ? "close" : "hamburger"}
25
+ onClick={handleToggleOpen}
26
+ />
27
+ </div>
28
+ {isOpen && (
29
+ <div className="absolute z-20">
30
+ <NavMenuContent items={props.items} />
31
+ </div>
32
+ )}
33
+ </>
34
+ );
35
+ }
@@ -0,0 +1,23 @@
1
+ import * as React from "react";
2
+
3
+ import { NavMenuItem, NavMenuItemProps } from "./NavMenuItem";
4
+
5
+ interface NavMenuContentProps {
6
+ items: Array<NavMenuItemProps>;
7
+ }
8
+
9
+ export const NavMenuContent = (props: NavMenuContentProps): JSX.Element => {
10
+ return (
11
+ <div className={"flex flex-col bg-nav-menu w-46 pl-1 py-2 lg:relative shadow-lg"}>
12
+ {props.items.map((item, index) => {
13
+ if (item.type === "separator") {
14
+ return <div key={`${item.type}-${index}`} className={"border-b ml-3 border-slate-600"} />;
15
+ } else if (item.type === "spacer") {
16
+ return <div key={`${item.type}-${index}`} className={"mt-auto"} />;
17
+ } else {
18
+ return <NavMenuItem {...item} key={item.title} />;
19
+ }
20
+ })}
21
+ </div>
22
+ );
23
+ };
@@ -0,0 +1,96 @@
1
+ import * as React from "react";
2
+ import { useState } from "react";
3
+ import { navigate } from "@reach/router";
4
+ import classNames from "classnames";
5
+
6
+ import { TextColor, Text } from "../Text/Text";
7
+
8
+ export interface NavMenuItemProps {
9
+ href?: string;
10
+ linkTo?: string;
11
+ title: string;
12
+ isSelected: boolean;
13
+ img: string;
14
+ imgOnHover: string;
15
+ dataTestId: string;
16
+ gtmEvent?: string;
17
+ isExternal?: boolean;
18
+ type?: "separator" | "spacer" | "base" | void;
19
+ track?: (event: string) => void;
20
+ }
21
+
22
+ export const NavMenuItem = (props: NavMenuItemProps): JSX.Element => {
23
+ const [currentImg, setCurrentImg] = useState(props.isSelected ? props.imgOnHover : props.img);
24
+ const [textColor, setTextColor] = useState<TextColor>(props.isSelected ? "white" : "gray-200");
25
+
26
+ const classes = classNames(
27
+ [
28
+ "flex",
29
+ "flex-row",
30
+ "items-center",
31
+ "w-auto",
32
+ "rounded",
33
+ "px-2",
34
+ "py-1",
35
+ "my-2",
36
+ "mx-2",
37
+ "hover:bg-gray-600",
38
+ "transition",
39
+ "ease-in",
40
+ "duration-150",
41
+ "lg:last:pb-2",
42
+ "focus:outline-primary",
43
+ ],
44
+ {
45
+ "bg-nav-menu": !props.isSelected,
46
+ "bg-gray-600": props.isSelected,
47
+ }
48
+ );
49
+
50
+ const handleOnMouseOver = () => {
51
+ if (!props.isSelected) {
52
+ setCurrentImg(props.imgOnHover);
53
+ setTextColor("white");
54
+ }
55
+ };
56
+
57
+ const handleOnMouseOut = () => {
58
+ if (!props.isSelected) {
59
+ setCurrentImg(props.img);
60
+ setTextColor("gray-200");
61
+ }
62
+ };
63
+
64
+ return (
65
+ <a
66
+ href={props.href ?? props.linkTo ?? "#"}
67
+ data-test-id={props.dataTestId}
68
+ className={classes}
69
+ onMouseOver={handleOnMouseOver}
70
+ onMouseOut={handleOnMouseOut}
71
+ onClick={handleMenuClick}
72
+ >
73
+ <img src={currentImg} className={"mr-4 ml-0"} />
74
+ <Text type={"strong"} text={props.title} color={textColor} />
75
+ </a>
76
+ );
77
+
78
+ function handleMenuClick(event: React.MouseEvent<HTMLElement>) {
79
+ if (event.metaKey || event.ctrlKey) {
80
+ // if ctrl or meta key are held on click, allow default behavior of opening link in new tab
81
+ return;
82
+ }
83
+
84
+ event.preventDefault();
85
+
86
+ props.track && props.gtmEvent && props.track(props.gtmEvent);
87
+
88
+ if (props.isExternal) {
89
+ window.open(props.href, "_blank");
90
+ } else if (props.href) {
91
+ window.location.assign(props.href);
92
+ } else if (props.linkTo) {
93
+ navigate(props.linkTo);
94
+ }
95
+ }
96
+ };
@@ -0,0 +1,57 @@
1
+ import React from "react";
2
+ import classNames from "classnames";
3
+
4
+ import { Text } from "../Text/Text";
5
+ import { TextLink } from "../TextLink/TextLink";
6
+
7
+ export type NotificationBannerColor = "base" | "blue" | "red" | "green" | "amber";
8
+
9
+ export interface NotificationBannerLinkProps {
10
+ text: string;
11
+ enabled: boolean;
12
+ handleClick?: () => void;
13
+ }
14
+
15
+ interface NotificationBannerProps {
16
+ text: string;
17
+ color?: NotificationBannerColor;
18
+ icon?: JSX.Element;
19
+ linkProps?: NotificationBannerLinkProps;
20
+ className?: string;
21
+ }
22
+
23
+ export const NotificationBanner = (props: NotificationBannerProps): JSX.Element => {
24
+ const classes = classNames(
25
+ "w-full px-6 py-2 flex flex-row items-center border border-solid rounded",
26
+ props.className,
27
+ {
28
+ "bg-slate-100 border-slate-700": props.color === "base",
29
+ "bg-blue-100 border-blue-700": props.color === "blue",
30
+ "bg-red-100 border-red-700": props.color === "red",
31
+ "bg-green-100 border-green-700": props.color === "green",
32
+ "bg-yellow-100 border-yellow-700": props.color === "amber",
33
+ }
34
+ );
35
+
36
+ return (
37
+ <div className={classes}>
38
+ {props.icon}
39
+ <Text className="first:ml-0 ml-4" text={props.text} color={props.color} />
40
+ {props.linkProps && (
41
+ <TextLink
42
+ className="ml-4"
43
+ text={props.linkProps.text}
44
+ enabled={props.linkProps.enabled}
45
+ rel="noopener"
46
+ target="_blank"
47
+ onClick={props.linkProps.handleClick}
48
+ />
49
+ )}
50
+ </div>
51
+ );
52
+ };
53
+
54
+ NotificationBanner.defaultProps = {
55
+ color: "base",
56
+ onButtonClick: undefined,
57
+ };
@@ -0,0 +1,123 @@
1
+ import React from "react";
2
+ import PropTypes from "prop-types";
3
+ import classNames from "classnames";
4
+
5
+ import LoadingIndicator from "../LoadingIndicator/LoadingIndicator";
6
+ import LegacyTitle, { TITLE_TYPE_OPTIONS } from "../Title/LegacyTitle";
7
+ import Button, { BUTTON_ROLES } from "../Button/Button";
8
+ import Line from "../Line/Line";
9
+ import { NavLayout } from "../NavMenu/NavLayout";
10
+ import { Steps } from "../Steps/Steps";
11
+
12
+ import "./CRUDPage.scss";
13
+
14
+ function CRUDPage({
15
+ dataTestId = "page",
16
+ title,
17
+ stepTitles,
18
+ currentStep = 1,
19
+ submitButtonProps,
20
+ deleteButtonProps,
21
+ cancelButtonProps,
22
+ icon,
23
+ className,
24
+ children,
25
+ isLoading,
26
+ isSubmitting,
27
+ navMenuComponent,
28
+ localization,
29
+ }) {
30
+ const mergedClasses = classNames("cweb-crud-page max-w-3xl", className);
31
+ const containerClassnames = classNames("cweb-crud-page-container mb-20");
32
+
33
+ const submitButton = submitButtonProps && (
34
+ <Button
35
+ data-test-id="submit-button"
36
+ key="submit-button"
37
+ /* eslint-disable-next-line */
38
+ onClick={submitButtonProps.handler}
39
+ role={BUTTON_ROLES.PRIMARY}
40
+ text={submitButtonProps.name}
41
+ isPending={isSubmitting}
42
+ />
43
+ );
44
+ const deleteButton = deleteButtonProps && (
45
+ <Button
46
+ data-test-id="delete-button"
47
+ key="delete-button"
48
+ /* eslint-disable-next-line */
49
+ onClick={deleteButtonProps.handler}
50
+ role={BUTTON_ROLES.NEGATIVE}
51
+ text={deleteButtonProps.name}
52
+ />
53
+ );
54
+ const cancelButton = cancelButtonProps && (
55
+ <Button
56
+ data-test-id="cancel-button"
57
+ key="cancel-button"
58
+ /* eslint-disable-next-line */
59
+ onClick={cancelButtonProps.handler}
60
+ role={BUTTON_ROLES.SECONDARY}
61
+ text={cancelButtonProps.name}
62
+ />
63
+ );
64
+
65
+ const renderHeader = () => {
66
+ return (
67
+ <div className="flex flex-row justify-start align-center">
68
+ <img id="title-icon" src={icon} className="mr-4 w-11 h-11" alt={"title icon"} />
69
+ <LegacyTitle id="title-text" text={title} type={TITLE_TYPE_OPTIONS.BOLD} />
70
+ </div>
71
+ );
72
+ };
73
+
74
+ return (
75
+ <div className={containerClassnames}>
76
+ <NavLayout menu={navMenuComponent}>
77
+ <>
78
+ {isLoading && (
79
+ <div className={classNames(mergedClasses, "cweb-crud-page-loading-container")}>
80
+ <div className="flex flex-row justify-start align-center">{renderHeader()}</div>
81
+ <LoadingIndicator className="crud-page-loader" asModal={false} />
82
+ </div>
83
+ )}
84
+
85
+ {!isLoading && (
86
+ <div className={mergedClasses} data-test-id={dataTestId}>
87
+ <div className="flex flex-row justify-start align-center">{renderHeader()}</div>
88
+
89
+ <div className={"cweb-crud-page-form-container"}>
90
+ {stepTitles && stepTitles.length > 0 && (
91
+ <Steps orderedStepTitles={stepTitles} currentStep={currentStep} className={"mb-4"} localization={localization}/>
92
+ )}
93
+ {children}
94
+ <Line
95
+ left={[cancelButton, deleteButton]}
96
+ right={[submitButton]}
97
+ className={"cweb-crud-page-button-line"}
98
+ />
99
+ </div>
100
+ </div>
101
+ )}
102
+ </>
103
+ </NavLayout>
104
+ </div>
105
+ );
106
+ }
107
+
108
+ CRUDPage.propTypes = {
109
+ isLoading: PropTypes.bool,
110
+ title: PropTypes.string.isRequired,
111
+ stepTitles: PropTypes.array,
112
+ currentStep: PropTypes.number,
113
+ submitButtonProps: PropTypes.shape({ name: PropTypes.string, handler: PropTypes.func }),
114
+ deleteButtonProps: PropTypes.shape({ name: PropTypes.string, handler: PropTypes.func }),
115
+ cancelButtonProps: PropTypes.shape({ name: PropTypes.string, handler: PropTypes.func }),
116
+ className: PropTypes.string,
117
+ icon: PropTypes.string,
118
+ isSubmitting: PropTypes.bool,
119
+ navMenuComponent: PropTypes.elementType,
120
+ localization: PropTypes.object,
121
+ };
122
+
123
+ export default CRUDPage;
@@ -0,0 +1,32 @@
1
+ @import "../../styles/colors";
2
+
3
+ .cweb-crud-page {
4
+ width: 100%;
5
+ margin: 36px auto 0;
6
+
7
+ &-form-container {
8
+ background-color: #fff;
9
+ border-radius: 8px;
10
+ padding: 24px;
11
+ margin-top: 16px;
12
+ }
13
+
14
+ &-button-line {
15
+ border-top: 1px solid $color-divider;
16
+ padding-top: 16px;
17
+ margin-top: 16px;
18
+ }
19
+
20
+ &-loading-container {
21
+ height: 90vh; /* puting this in 100vh causes an overflow bug */
22
+ overflow-y: hidden;
23
+ position: relative;
24
+
25
+ .crud-page-loader {
26
+ position: absolute;
27
+ top: 50%;
28
+ left: 50%;
29
+ transform: translate(-50%, -50%);
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,102 @@
1
+ import React from "react";
2
+ import PropTypes from "prop-types";
3
+ import classNames from "classnames";
4
+
5
+ //import Breadcrumbs from "../Breadcrumbs/Breadcrumbs";
6
+ import LoadingIndicator from "../LoadingIndicator/LoadingIndicator";
7
+ //import { SmartNavMenu } from "../../components/NavMenu/SmartNavMenu";
8
+ import { NavLayout } from "../NavMenu/NavLayout";
9
+ import { Title } from "../Title/Title";
10
+ //import { shouldPageShowFeedbackBlock } from "../../common/utils/locationUtils";
11
+ //import { FeedbackBlock } from "../FeedbackBlock/FeedbackBlock";
12
+ //import { ERROR_PAGE_ID } from "../../components/ErrorPages/ErrorPage";
13
+
14
+ import "./Page.scss";
15
+
16
+ //TODO this page needs to be refactored
17
+
18
+ /**
19
+ * Renders page's content, if `isLoading` is false otherwise shows loading indicator.
20
+ *
21
+ * `breadcrumbs`, `title` and `content` can be lazy properties, that is parameterless functions which return actual value.
22
+ * `children` property has priority over `content` property.
23
+ *
24
+ * @typedef {{ name?: string, icon?: string|Object, link?: string}} Breadcrumb
25
+ *
26
+ */
27
+ function Page({
28
+ dataTestId = "page",
29
+ breadcrumbs,
30
+ title,
31
+ accessories,
32
+ accessoryPosition = "right",
33
+ className,
34
+ children,
35
+ content,
36
+ isLoading = false,
37
+ isPolling = false,
38
+ spinnerColor = "blue",
39
+ navLayoutProps = {},
40
+ showFeedbackBlock = false,
41
+ feedbackBlock = <></>,
42
+ navMenu,
43
+ id,
44
+ }) {
45
+ const mergedPageClasses = classNames("cweb-page", className);
46
+ const containerClassnames = classNames("cweb-page-container");
47
+
48
+ if (isLoading) {
49
+ return (
50
+ <div className={mergedPageClasses}>
51
+ <LoadingIndicator asModal={false} />
52
+ </div>
53
+ );
54
+ }
55
+
56
+ const maybeTitle = title instanceof Function ? title() : title;
57
+
58
+ const accessoryClasses = classNames("cweb-page-header mb-4", {
59
+ [`accessory-${accessoryPosition}`]: true,
60
+ });
61
+
62
+ const accessoriesContent = accessories instanceof Function ? accessories() : accessories;
63
+ const childrenOrContentProp = children || (content instanceof Function ? content() : content);
64
+
65
+ return (
66
+ <div id={id} className={containerClassnames}>
67
+ <NavLayout menu={navMenu} {...navLayoutProps}>
68
+ <div className={mergedPageClasses} data-test-id={dataTestId}>
69
+ <div className={accessoryClasses}>
70
+ <Title data-test-id={`${dataTestId}-title`} text={maybeTitle} />
71
+ {isPolling && <LoadingIndicator asSpinner={true} className={"page-spinner"} spinnerColor={spinnerColor} />}
72
+ {accessoriesContent}
73
+ </div>
74
+ {childrenOrContentProp}
75
+ </div>
76
+
77
+ {!isLoading && feedbackBlock}
78
+ </NavLayout>
79
+ </div>
80
+ );
81
+ }
82
+
83
+ const breadcrumbItemShape = PropTypes.shape({
84
+ name: PropTypes.string,
85
+ icon: PropTypes.string,
86
+ link: PropTypes.string,
87
+ });
88
+
89
+ Page.propTypes = {
90
+ breadcrumbs: PropTypes.oneOfType([PropTypes.arrayOf(breadcrumbItemShape), PropTypes.func]),
91
+ isLoading: PropTypes.bool,
92
+ isFetching: PropTypes.bool,
93
+ spinnerColor: PropTypes.oneOf(["blue", "gray"]),
94
+ title: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
95
+ accessories: PropTypes.oneOfType([PropTypes.element, PropTypes.func]),
96
+ accessoryPosition: PropTypes.oneOf(["right", "bottom", "left"]),
97
+ content: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.element), PropTypes.element, PropTypes.func]),
98
+ id: PropTypes.string,
99
+ navLayoutProps: PropTypes.object,
100
+ };
101
+
102
+ export default Page;