@onewelcome/react-lib-components 0.1.0-alpha

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 (248) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +71 -0
  3. package/dist/BaseModal/BaseModal.d.ts +16 -0
  4. package/dist/BaseModal/BaseModalActions/BaseModalActions.d.ts +5 -0
  5. package/dist/BaseModal/BaseModalContent/BaseModalContent.d.ts +8 -0
  6. package/dist/BaseModal/BaseModalContext.d.ts +2 -0
  7. package/dist/BaseModal/BaseModalHeader/BaseModalHeader.d.ts +8 -0
  8. package/dist/Breadcrumbs/Breadcrumbs.d.ts +9 -0
  9. package/dist/Button/BaseButton.d.ts +8 -0
  10. package/dist/Button/Button.d.ts +10 -0
  11. package/dist/Button/IconButton.d.ts +10 -0
  12. package/dist/ContextMenu/ContextMenu.d.ts +18 -0
  13. package/dist/ContextMenu/ContextMenuItem.d.ts +6 -0
  14. package/dist/Dialog/Dialog.d.ts +18 -0
  15. package/dist/Dialog/DialogActions/DialogActions.d.ts +6 -0
  16. package/dist/Dialog/DialogTitle/DialogTitle.d.ts +6 -0
  17. package/dist/Form/Checkbox/Checkbox.d.ts +13 -0
  18. package/dist/Form/Fieldset/Fieldset.d.ts +13 -0
  19. package/dist/Form/Form.d.ts +5 -0
  20. package/dist/Form/FormControl/FormControl.d.ts +8 -0
  21. package/dist/Form/FormGroup/FormGroup.d.ts +18 -0
  22. package/dist/Form/FormHelperText/FormHelperText.d.ts +7 -0
  23. package/dist/Form/FormSelectorWrapper/FormSelectorWrapper.d.ts +18 -0
  24. package/dist/Form/Input/Input.d.ts +12 -0
  25. package/dist/Form/Label/Label.d.ts +6 -0
  26. package/dist/Form/Radio/Radio.d.ts +11 -0
  27. package/dist/Form/Select/Option.d.ts +12 -0
  28. package/dist/Form/Select/Select.d.ts +15 -0
  29. package/dist/Form/Textarea/Textarea.d.ts +7 -0
  30. package/dist/Form/Toggle/Toggle.d.ts +6 -0
  31. package/dist/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.d.ts +8 -0
  32. package/dist/Form/Wrapper/InputWrapper/InputWrapper.d.ts +17 -0
  33. package/dist/Form/Wrapper/RadioWrapper/RadioWrapper.d.ts +10 -0
  34. package/dist/Form/Wrapper/SelectWrapper/SelectWrapper.d.ts +12 -0
  35. package/dist/Form/Wrapper/TextareaWrapper/TextareaWrapper.d.ts +14 -0
  36. package/dist/Form/Wrapper/Wrapper/Wrapper.d.ts +28 -0
  37. package/dist/Form/form.interfaces.d.ts +12 -0
  38. package/dist/Icon/Icon.d.ts +75 -0
  39. package/dist/Link/Link.d.ts +15 -0
  40. package/dist/Modal/Modal.d.ts +1 -0
  41. package/dist/Modal/ModalActions/ModalActions.d.ts +1 -0
  42. package/dist/Modal/ModalContent/ModalContent.d.ts +1 -0
  43. package/dist/Modal/ModalHeader/ModalHeader.d.ts +1 -0
  44. package/dist/Popover/Popover.d.ts +11 -0
  45. package/dist/Snackbar/SnackbarContainer/SnackbarContainer.d.ts +12 -0
  46. package/dist/Snackbar/SnackbarItem/SnackbarItem.d.ts +13 -0
  47. package/dist/Snackbar/SnackbarProvider/SnackbarProvider.d.ts +18 -0
  48. package/dist/Snackbar/SnackbarProvider/SnackbarStateProvider.d.ts +14 -0
  49. package/dist/Snackbar/interfaces.d.ts +10 -0
  50. package/dist/Snackbar/useSnackbar.d.ts +1 -0
  51. package/dist/Tiles/Tile.d.ts +16 -0
  52. package/dist/Tiles/Tiles.d.ts +6 -0
  53. package/dist/Tooltip/Tooltip.d.ts +11 -0
  54. package/dist/Typography/Typography.d.ts +12 -0
  55. package/dist/Wizard/BaseWizardSteps/BaseWizardSteps.d.ts +13 -0
  56. package/dist/Wizard/Wizard.d.ts +12 -0
  57. package/dist/Wizard/WizardActions/WizardActions.d.ts +12 -0
  58. package/dist/Wizard/WizardStateProvider.d.ts +12 -0
  59. package/dist/Wizard/WizardSteps/WizardSteps.d.ts +5 -0
  60. package/dist/Wizard/wizardStateReducer.d.ts +26 -0
  61. package/dist/_BaseStyling_/BaseStyling.d.ts +47 -0
  62. package/dist/hooks/useAnimation.d.ts +6 -0
  63. package/dist/hooks/useBodyClick.d.ts +1 -0
  64. package/dist/hooks/useFormSelector.d.ts +13 -0
  65. package/dist/hooks/usePosition.d.ts +36 -0
  66. package/dist/hooks/useScroll.d.ts +2 -0
  67. package/dist/hooks/useSpacing.d.ts +18 -0
  68. package/dist/hooks/useWrapper.d.ts +11 -0
  69. package/dist/index.d.ts +43 -0
  70. package/dist/index.js +8 -0
  71. package/dist/interfaces.d.ts +13 -0
  72. package/dist/react-lib-components.cjs.development.js +3282 -0
  73. package/dist/react-lib-components.cjs.development.js.map +1 -0
  74. package/dist/react-lib-components.cjs.production.min.js +2 -0
  75. package/dist/react-lib-components.cjs.production.min.js.map +1 -0
  76. package/dist/react-lib-components.esm.js +3235 -0
  77. package/dist/react-lib-components.esm.js.map +1 -0
  78. package/dist/util/helper.d.ts +1 -0
  79. package/package.json +88 -0
  80. package/src/BaseModal/BaseModal.module.scss +58 -0
  81. package/src/BaseModal/BaseModal.test.tsx +59 -0
  82. package/src/BaseModal/BaseModal.tsx +113 -0
  83. package/src/BaseModal/BaseModalActions/BaseModalActions.module.scss +9 -0
  84. package/src/BaseModal/BaseModalActions/BaseModalActions.test.tsx +17 -0
  85. package/src/BaseModal/BaseModalActions/BaseModalActions.tsx +14 -0
  86. package/src/BaseModal/BaseModalContent/BaseModalContent.module.scss +6 -0
  87. package/src/BaseModal/BaseModalContent/BaseModalContent.test.tsx +29 -0
  88. package/src/BaseModal/BaseModalContent/BaseModalContent.tsx +35 -0
  89. package/src/BaseModal/BaseModalContext.ts +2 -0
  90. package/src/BaseModal/BaseModalHeader/BaseModalHeader.module.scss +17 -0
  91. package/src/BaseModal/BaseModalHeader/BaseModalHeader.test.tsx +30 -0
  92. package/src/BaseModal/BaseModalHeader/BaseModalHeader.tsx +28 -0
  93. package/src/Breadcrumbs/Breadcrumbs.module.scss +14 -0
  94. package/src/Breadcrumbs/Breadcrumbs.test.tsx +42 -0
  95. package/src/Breadcrumbs/Breadcrumbs.tsx +48 -0
  96. package/src/Button/BaseButton.module.scss +20 -0
  97. package/src/Button/BaseButton.test.tsx +59 -0
  98. package/src/Button/BaseButton.tsx +31 -0
  99. package/src/Button/Button.module.scss +336 -0
  100. package/src/Button/Button.test.tsx +76 -0
  101. package/src/Button/Button.tsx +44 -0
  102. package/src/Button/IconButton.module.scss +161 -0
  103. package/src/Button/IconButton.test.tsx +47 -0
  104. package/src/Button/IconButton.tsx +29 -0
  105. package/src/ContextMenu/ContextMenu.module.scss +20 -0
  106. package/src/ContextMenu/ContextMenu.test.tsx +93 -0
  107. package/src/ContextMenu/ContextMenu.tsx +91 -0
  108. package/src/ContextMenu/ContextMenuItem.module.scss +31 -0
  109. package/src/ContextMenu/ContextMenuItem.tsx +15 -0
  110. package/src/Dialog/Dialog.module.scss +16 -0
  111. package/src/Dialog/Dialog.test.tsx +79 -0
  112. package/src/Dialog/Dialog.tsx +96 -0
  113. package/src/Dialog/DialogActions/DialogActions.module.scss +11 -0
  114. package/src/Dialog/DialogActions/DialogActions.test.tsx +25 -0
  115. package/src/Dialog/DialogActions/DialogActions.tsx +21 -0
  116. package/src/Dialog/DialogTitle/DialogTitle.module.scss +7 -0
  117. package/src/Dialog/DialogTitle/DialogTitle.test.tsx +18 -0
  118. package/src/Dialog/DialogTitle/DialogTitle.tsx +18 -0
  119. package/src/Form/Checkbox/Checkbox.module.scss +65 -0
  120. package/src/Form/Checkbox/Checkbox.test.tsx +119 -0
  121. package/src/Form/Checkbox/Checkbox.tsx +145 -0
  122. package/src/Form/Fieldset/Fieldset.module.scss +19 -0
  123. package/src/Form/Fieldset/Fieldset.test.tsx +85 -0
  124. package/src/Form/Fieldset/Fieldset.tsx +55 -0
  125. package/src/Form/Form.module.scss +3 -0
  126. package/src/Form/Form.test.tsx +47 -0
  127. package/src/Form/Form.tsx +14 -0
  128. package/src/Form/FormControl/FormControl.module.scss +67 -0
  129. package/src/Form/FormControl/FormControl.test.tsx +56 -0
  130. package/src/Form/FormControl/FormControl.tsx +47 -0
  131. package/src/Form/FormGroup/FormGroup.module.scss +29 -0
  132. package/src/Form/FormGroup/FormGroup.test.tsx +61 -0
  133. package/src/Form/FormGroup/FormGroup.tsx +78 -0
  134. package/src/Form/FormHelperText/FormHelperText.module.scss +8 -0
  135. package/src/Form/FormHelperText/FormHelperText.test.tsx +42 -0
  136. package/src/Form/FormHelperText/FormHelperText.tsx +22 -0
  137. package/src/Form/FormSelectorWrapper/FormSelectorWrapper.module.scss +33 -0
  138. package/src/Form/FormSelectorWrapper/FormSelectorWrapper.tsx +65 -0
  139. package/src/Form/Input/Input.module.scss +65 -0
  140. package/src/Form/Input/Input.test.tsx +135 -0
  141. package/src/Form/Input/Input.tsx +72 -0
  142. package/src/Form/Label/Label.module.scss +5 -0
  143. package/src/Form/Label/Label.test.tsx +26 -0
  144. package/src/Form/Label/Label.tsx +19 -0
  145. package/src/Form/Radio/Radio.module.scss +100 -0
  146. package/src/Form/Radio/Radio.test.tsx +88 -0
  147. package/src/Form/Radio/Radio.tsx +98 -0
  148. package/src/Form/Select/Option.test.tsx +15 -0
  149. package/src/Form/Select/Option.tsx +57 -0
  150. package/src/Form/Select/Select.module.scss +189 -0
  151. package/src/Form/Select/Select.test.tsx +96 -0
  152. package/src/Form/Select/Select.tsx +217 -0
  153. package/src/Form/Textarea/Textarea.module.scss +53 -0
  154. package/src/Form/Textarea/Textarea.test.tsx +76 -0
  155. package/src/Form/Textarea/Textarea.tsx +33 -0
  156. package/src/Form/Toggle/Toggle.module.scss +58 -0
  157. package/src/Form/Toggle/Toggle.test.tsx +29 -0
  158. package/src/Form/Toggle/Toggle.tsx +20 -0
  159. package/src/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.module.scss +12 -0
  160. package/src/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.test.tsx +99 -0
  161. package/src/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.tsx +62 -0
  162. package/src/Form/Wrapper/InputWrapper/InputWrapper.module.scss +24 -0
  163. package/src/Form/Wrapper/InputWrapper/InputWrapper.test.tsx +93 -0
  164. package/src/Form/Wrapper/InputWrapper/InputWrapper.tsx +92 -0
  165. package/src/Form/Wrapper/RadioWrapper/RadioWrapper.module.scss +12 -0
  166. package/src/Form/Wrapper/RadioWrapper/RadioWrapper.test.tsx +101 -0
  167. package/src/Form/Wrapper/RadioWrapper/RadioWrapper.tsx +74 -0
  168. package/src/Form/Wrapper/SelectWrapper/SelectWrapper.module.scss +14 -0
  169. package/src/Form/Wrapper/SelectWrapper/SelectWrapper.test.tsx +101 -0
  170. package/src/Form/Wrapper/SelectWrapper/SelectWrapper.tsx +59 -0
  171. package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.module.scss +65 -0
  172. package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.test.tsx +125 -0
  173. package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.tsx +105 -0
  174. package/src/Form/Wrapper/Wrapper/Wrapper.module.scss +35 -0
  175. package/src/Form/Wrapper/Wrapper/Wrapper.test.tsx +17 -0
  176. package/src/Form/Wrapper/Wrapper/Wrapper.tsx +101 -0
  177. package/src/Form/form.interfaces.ts +14 -0
  178. package/src/Icon/Icon.module.scss +278 -0
  179. package/src/Icon/Icon.test.tsx +39 -0
  180. package/src/Icon/Icon.tsx +94 -0
  181. package/src/Link/Link.module.scss +46 -0
  182. package/src/Link/Link.test.tsx +122 -0
  183. package/src/Link/Link.tsx +80 -0
  184. package/src/Link/types.d.ts +9 -0
  185. package/src/Modal/Modal.test.tsx +16 -0
  186. package/src/Modal/Modal.tsx +1 -0
  187. package/src/Modal/ModalActions/ModalActions.tsx +4 -0
  188. package/src/Modal/ModalContent/ModalContent.tsx +4 -0
  189. package/src/Modal/ModalHeader/ModalHeader.tsx +4 -0
  190. package/src/Popover/Popover.module.scss +18 -0
  191. package/src/Popover/Popover.test.tsx +84 -0
  192. package/src/Popover/Popover.tsx +46 -0
  193. package/src/Snackbar/SnackbarContainer/SnackbarContainer.module.scss +35 -0
  194. package/src/Snackbar/SnackbarContainer/SnackbarContainer.test.tsx +37 -0
  195. package/src/Snackbar/SnackbarContainer/SnackbarContainer.tsx +28 -0
  196. package/src/Snackbar/SnackbarItem/SnackbarItem.module.scss +135 -0
  197. package/src/Snackbar/SnackbarItem/SnackbarItem.test.tsx +47 -0
  198. package/src/Snackbar/SnackbarItem/SnackbarItem.tsx +105 -0
  199. package/src/Snackbar/SnackbarProvider/SnackbarProvider.test.tsx +179 -0
  200. package/src/Snackbar/SnackbarProvider/SnackbarProvider.tsx +127 -0
  201. package/src/Snackbar/SnackbarProvider/SnackbarStateProvider.tsx +25 -0
  202. package/src/Snackbar/interfaces.ts +11 -0
  203. package/src/Snackbar/useSnackbar.ts +4 -0
  204. package/src/Tiles/Tile.module.scss +72 -0
  205. package/src/Tiles/Tile.test.tsx +129 -0
  206. package/src/Tiles/Tile.tsx +48 -0
  207. package/src/Tiles/Tiles.module.scss +11 -0
  208. package/src/Tiles/Tiles.test.tsx +118 -0
  209. package/src/Tiles/Tiles.tsx +48 -0
  210. package/src/Tooltip/Tooltip.module.scss +42 -0
  211. package/src/Tooltip/Tooltip.test.tsx +72 -0
  212. package/src/Tooltip/Tooltip.tsx +130 -0
  213. package/src/Typography/Typography.module.scss +46 -0
  214. package/src/Typography/Typography.test.tsx +114 -0
  215. package/src/Typography/Typography.tsx +84 -0
  216. package/src/Wizard/BaseWizardSteps/BaseWizardSteps.module.scss +192 -0
  217. package/src/Wizard/BaseWizardSteps/BaseWizardSteps.test.tsx +75 -0
  218. package/src/Wizard/BaseWizardSteps/BaseWizardSteps.tsx +86 -0
  219. package/src/Wizard/Wizard.test.tsx +198 -0
  220. package/src/Wizard/Wizard.tsx +49 -0
  221. package/src/Wizard/WizardActions/WizardActions.test.tsx +168 -0
  222. package/src/Wizard/WizardActions/WizardActions.tsx +100 -0
  223. package/src/Wizard/WizardStateProvider.tsx +26 -0
  224. package/src/Wizard/WizardSteps/WizardSteps.test.tsx +110 -0
  225. package/src/Wizard/WizardSteps/WizardSteps.tsx +30 -0
  226. package/src/Wizard/wizardStateReducer.ts +51 -0
  227. package/src/_BaseStyling_/BaseStyling.test.tsx +39 -0
  228. package/src/_BaseStyling_/BaseStyling.tsx +115 -0
  229. package/src/hooks/useAnimation.test.tsx +45 -0
  230. package/src/hooks/useAnimation.ts +20 -0
  231. package/src/hooks/useBodyClick.test.tsx +39 -0
  232. package/src/hooks/useBodyClick.ts +20 -0
  233. package/src/hooks/useFormSelector.test.ts +40 -0
  234. package/src/hooks/useFormSelector.ts +47 -0
  235. package/src/hooks/usePosition.test.tsx +494 -0
  236. package/src/hooks/usePosition.ts +347 -0
  237. package/src/hooks/useScroll.test.tsx +20 -0
  238. package/src/hooks/useScroll.ts +16 -0
  239. package/src/hooks/useSpacing.test.ts +70 -0
  240. package/src/hooks/useSpacing.ts +42 -0
  241. package/src/hooks/useWrapper.test.ts +49 -0
  242. package/src/hooks/useWrapper.ts +35 -0
  243. package/src/index.ts +52 -0
  244. package/src/interfaces.ts +15 -0
  245. package/src/readyclasses.module.scss +77 -0
  246. package/src/types.d.ts +4 -0
  247. package/src/util/helper.test.tsx +15 -0
  248. package/src/util/helper.tsx +80 -0
@@ -0,0 +1,347 @@
1
+ import React, { useState } from 'react';
2
+
3
+ export interface ConfigObject {
4
+ relativeElement: RefElement;
5
+ elementToBePositioned: RefElement;
6
+ transformOrigin?: Placement;
7
+ placement?: Placement;
8
+ offset?: Offset;
9
+ }
10
+
11
+ export type HorizontalPlacment = 'left' | 'center' | 'centerh' | 'right';
12
+ export type VerticalPlacement = 'top' | 'center' | 'centerv' | 'bottom';
13
+
14
+ type Axis = 'vertical' | 'horizontal';
15
+ type RefElement = React.RefObject<HTMLOrSVGElement> | undefined;
16
+
17
+ interface DomRectObject {
18
+ top: number;
19
+ right: number;
20
+ bottom: number;
21
+ left: number;
22
+ center: number;
23
+ centerh: number;
24
+ centerv: number;
25
+ width: number;
26
+ height: number;
27
+ x: number;
28
+ y: number;
29
+ }
30
+
31
+ export interface Placement {
32
+ horizontal: HorizontalPlacment;
33
+ vertical: VerticalPlacement;
34
+ }
35
+
36
+ export interface Offset {
37
+ top: number;
38
+ right: number;
39
+ bottom: number;
40
+ left: number;
41
+ }
42
+
43
+ export interface Position {
44
+ top: PositionType;
45
+ right: PositionType;
46
+ bottom: PositionType;
47
+ left: PositionType;
48
+ }
49
+
50
+ interface Dimensions {
51
+ height: number;
52
+ width: number;
53
+ }
54
+
55
+ type PositionType = number | 'initial';
56
+
57
+ const defaultConfigObject: ConfigObject = {
58
+ relativeElement: undefined,
59
+ elementToBePositioned: undefined,
60
+ transformOrigin: {
61
+ horizontal: 'left',
62
+ vertical: 'top',
63
+ },
64
+ placement: {
65
+ horizontal: 'left',
66
+ vertical: 'top',
67
+ },
68
+ offset: {
69
+ top: 0,
70
+ right: 0,
71
+ bottom: 0,
72
+ left: 0,
73
+ },
74
+ };
75
+
76
+ export const usePosition = (providedConfigObject: ConfigObject = defaultConfigObject) => {
77
+ const configObject = { ...defaultConfigObject, ...providedConfigObject };
78
+
79
+ if (configObject.transformOrigin === undefined) {
80
+ configObject.transformOrigin = defaultConfigObject.transformOrigin;
81
+ }
82
+
83
+ if (configObject.placement === undefined) {
84
+ configObject.placement = defaultConfigObject.placement;
85
+ }
86
+
87
+ if (configObject.offset === undefined) {
88
+ configObject.offset = defaultConfigObject.offset;
89
+ }
90
+
91
+ const [position, setPosition] = useState<Position>({
92
+ left: 0,
93
+ top: 0,
94
+ right: 'initial',
95
+ bottom: 'initial',
96
+ });
97
+
98
+ const _fixPossibleViewportOverflow = (
99
+ value: number,
100
+ transformOrigin: Placement,
101
+ requestedReturnValue: Axis,
102
+ elDimensions: Dimensions
103
+ ) => {
104
+ let returnValue = value;
105
+
106
+ if (
107
+ (transformOrigin[requestedReturnValue] === 'left' && returnValue < 0) ||
108
+ (transformOrigin[requestedReturnValue] === 'top' && returnValue < 0) ||
109
+ (transformOrigin[requestedReturnValue] === 'center' && returnValue < 0) ||
110
+ (transformOrigin[requestedReturnValue] === 'bottom' && returnValue < 0)
111
+ ) {
112
+ returnValue = 0;
113
+ }
114
+
115
+ if (
116
+ (transformOrigin[requestedReturnValue] === 'left' &&
117
+ returnValue > window.innerWidth - elDimensions.width) ||
118
+ (transformOrigin[requestedReturnValue] === 'center' &&
119
+ requestedReturnValue === 'horizontal' &&
120
+ returnValue > window.innerWidth - elDimensions.width)
121
+ ) {
122
+ returnValue = window.innerWidth - elDimensions.width;
123
+ }
124
+
125
+ if (
126
+ (transformOrigin[requestedReturnValue] === 'top' &&
127
+ returnValue > window.innerHeight - elDimensions.height) ||
128
+ (transformOrigin[requestedReturnValue] === 'center' &&
129
+ requestedReturnValue === 'vertical' &&
130
+ returnValue > window.innerHeight - elDimensions.height)
131
+ ) {
132
+ returnValue = window.innerHeight - elDimensions.height;
133
+ }
134
+
135
+ if (
136
+ transformOrigin[requestedReturnValue] === 'right' &&
137
+ returnValue > window.innerWidth - elDimensions.width
138
+ ) {
139
+ returnValue = window.innerWidth - elDimensions.width;
140
+ }
141
+
142
+ if (
143
+ transformOrigin[requestedReturnValue] === 'bottom' &&
144
+ returnValue > window.innerHeight - elDimensions.height
145
+ ) {
146
+ returnValue = window.innerHeight - elDimensions.height;
147
+ }
148
+
149
+ return returnValue;
150
+ };
151
+
152
+ const _applyOffsetToPlacementValue = (
153
+ value: number,
154
+ requestedReturnValue: Axis,
155
+ transformOrigin: Placement
156
+ ) => {
157
+ let returnValue = value;
158
+ if (
159
+ (requestedReturnValue === 'horizontal' && configObject.offset?.left !== 0) ||
160
+ (requestedReturnValue === 'horizontal' && configObject.offset?.right !== 0)
161
+ ) {
162
+ if (
163
+ transformOrigin[requestedReturnValue] === 'left' ||
164
+ transformOrigin[requestedReturnValue] === 'center'
165
+ ) {
166
+ returnValue += configObject.offset?.left!;
167
+ returnValue -= configObject.offset?.right!;
168
+ }
169
+
170
+ if (transformOrigin[requestedReturnValue] === 'right') {
171
+ returnValue -= configObject.offset?.left!;
172
+ returnValue += configObject.offset?.right!;
173
+ }
174
+ }
175
+
176
+ if (
177
+ (requestedReturnValue === 'vertical' && configObject.offset?.top !== 0) ||
178
+ (requestedReturnValue === 'vertical' && configObject.offset?.bottom !== 0)
179
+ ) {
180
+ if (
181
+ transformOrigin[requestedReturnValue] === 'top' ||
182
+ transformOrigin[requestedReturnValue] === 'center'
183
+ ) {
184
+ returnValue += configObject.offset?.top!;
185
+ returnValue -= configObject.offset?.bottom!;
186
+ }
187
+
188
+ if (transformOrigin[requestedReturnValue] === 'bottom') {
189
+ returnValue -= configObject.offset?.top!;
190
+ returnValue += configObject.offset?.bottom!;
191
+ }
192
+ }
193
+
194
+ return returnValue;
195
+ };
196
+
197
+ const _calculateInitialPlacementValue = (
198
+ transformOrigin: Placement,
199
+ requestedReturnValue: Axis,
200
+ relEl: DomRectObject,
201
+ placementOriginDefinition: HorizontalPlacment | VerticalPlacement,
202
+ elDimensions: Dimensions
203
+ ) => {
204
+ let value = 0;
205
+
206
+ if (
207
+ transformOrigin[requestedReturnValue] === 'left' ||
208
+ transformOrigin[requestedReturnValue] === 'top'
209
+ ) {
210
+ value = relEl[placementOriginDefinition];
211
+ } else if (transformOrigin[requestedReturnValue] === 'center') {
212
+ value =
213
+ relEl[placementOriginDefinition] -
214
+ elDimensions[requestedReturnValue === 'horizontal' ? 'width' : 'height'] / 2;
215
+ } else if (
216
+ transformOrigin[requestedReturnValue] === 'right' ||
217
+ transformOrigin[requestedReturnValue] === 'bottom'
218
+ ) {
219
+ value =
220
+ window[requestedReturnValue === 'horizontal' ? 'innerWidth' : 'innerHeight'] -
221
+ relEl[placementOriginDefinition];
222
+ }
223
+
224
+ return value;
225
+ };
226
+
227
+ /**
228
+ *
229
+ * @param requestedReturnValue whether the requested return value is for the horizontal or vertical axis
230
+ * @returns either the horizontally centered placement definition (centerh) or the vertically centered one (centerv)
231
+ */
232
+ const _determineCenteredPlacementOrigin = (requestedReturnValue: Axis) => {
233
+ if (requestedReturnValue === 'horizontal') {
234
+ return 'centerh';
235
+ } else if (requestedReturnValue === 'vertical') {
236
+ return 'centerv';
237
+ }
238
+ throw new Error(
239
+ `the requested return value isn\'t "vertical" or "horizontal" ${requestedReturnValue} was given.`
240
+ );
241
+ };
242
+
243
+ const _calculatePlacementValue = (
244
+ transformOrigin: Placement,
245
+ placement: HorizontalPlacment | VerticalPlacement,
246
+ requestedReturnValue: Axis,
247
+ relEl: DomRectObject,
248
+ elDimensions: Dimensions
249
+ ): number => {
250
+ const placementOriginDefinition =
251
+ placement === 'center' ? _determineCenteredPlacementOrigin(requestedReturnValue) : placement;
252
+
253
+ const value = _calculateInitialPlacementValue(
254
+ transformOrigin,
255
+ requestedReturnValue,
256
+ relEl,
257
+ placementOriginDefinition,
258
+ elDimensions
259
+ );
260
+
261
+ const valueWithOffset = _applyOffsetToPlacementValue(
262
+ value,
263
+ requestedReturnValue,
264
+ transformOrigin
265
+ );
266
+
267
+ const valueCorrectionForViewportOverflow = _fixPossibleViewportOverflow(
268
+ valueWithOffset,
269
+ transformOrigin,
270
+ requestedReturnValue,
271
+ elDimensions
272
+ );
273
+
274
+ return valueCorrectionForViewportOverflow;
275
+ };
276
+
277
+ const _calculatePlacement = (relEl: DomRectObject, elDimensions: Dimensions, axis: Axis) => {
278
+ const placementValue = _calculatePlacementValue(
279
+ configObject.transformOrigin!,
280
+ configObject.placement![axis]!,
281
+ axis,
282
+ relEl,
283
+ elDimensions
284
+ );
285
+
286
+ let direction = 'left';
287
+ let oppositeDirection = 'right';
288
+
289
+ if (axis === 'horizontal' && configObject.transformOrigin?.horizontal === 'right') {
290
+ direction = 'right';
291
+ oppositeDirection = 'left';
292
+ } else if (axis === 'horizontal') {
293
+ direction = 'left';
294
+ oppositeDirection = 'right';
295
+ }
296
+
297
+ if (axis === 'vertical' && configObject.transformOrigin?.vertical === 'bottom') {
298
+ direction = 'bottom';
299
+ oppositeDirection = 'top';
300
+ } else if (axis === 'vertical') {
301
+ direction = 'top';
302
+ oppositeDirection = 'bottom';
303
+ }
304
+
305
+ setPosition((prevState) => ({
306
+ ...prevState,
307
+ [direction]: placementValue,
308
+ [oppositeDirection]: 'initial',
309
+ }));
310
+ };
311
+
312
+ const calculatePosition = () => {
313
+ if (!configObject.relativeElement?.current) return;
314
+ const relativeElRect = (configObject.relativeElement!
315
+ .current as HTMLElement)!.getBoundingClientRect();
316
+ const elementToBePositionedDimensions: Dimensions = {
317
+ height: (configObject.elementToBePositioned!.current as HTMLElement).offsetHeight,
318
+ width: (configObject.elementToBePositioned!.current as HTMLElement).offsetWidth,
319
+ };
320
+
321
+ /** We want to add a center (horizontal and vertical) property to the DOMRect object. Since it's a special object we can't modify so we clone it and add it. */
322
+ const clonedRelEl = {
323
+ top: relativeElRect.top,
324
+ right: relativeElRect.right,
325
+ bottom: relativeElRect.bottom,
326
+ center: 0,
327
+ centerv: relativeElRect.top + relativeElRect.height / 2,
328
+ centerh: relativeElRect.left + relativeElRect.width / 2,
329
+ left: relativeElRect.left,
330
+ width: relativeElRect.width,
331
+ height: relativeElRect.height,
332
+ x: relativeElRect.x,
333
+ y: relativeElRect.y,
334
+ };
335
+
336
+ _calculatePlacement(clonedRelEl, elementToBePositionedDimensions, 'horizontal');
337
+ _calculatePlacement(clonedRelEl, elementToBePositionedDimensions, 'vertical');
338
+ };
339
+
340
+ return {
341
+ top: position.top,
342
+ bottom: position.bottom,
343
+ left: position.left,
344
+ right: position.right,
345
+ calculatePosition,
346
+ };
347
+ };
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { fireEvent, render } from '@testing-library/react';
3
+ import { useScroll } from './useScroll';
4
+
5
+ describe('function should be executed', () => {
6
+ it('should execute', () => {
7
+ const scrollHandler = jest.fn();
8
+
9
+ const Component = () => {
10
+ useScroll(scrollHandler);
11
+ return <div>Test</div>;
12
+ };
13
+
14
+ render(<Component />);
15
+
16
+ expect(scrollHandler).not.toBeCalled();
17
+ fireEvent.scroll(window, { target: { scrollY: 100 } });
18
+ expect(scrollHandler).toBeCalledTimes(1);
19
+ });
20
+ });
@@ -0,0 +1,16 @@
1
+ import React, { useLayoutEffect } from 'react';
2
+
3
+ export const useScroll = (
4
+ callbackFunction: (event: Event) => unknown,
5
+ dependingStateVariable: React.ComponentState[] = []
6
+ ) => {
7
+ const scrollListener = (event: Event) => callbackFunction(event);
8
+
9
+ useLayoutEffect(() => {
10
+ window.addEventListener('scroll', scrollListener);
11
+
12
+ return () => {
13
+ window.removeEventListener('scroll', scrollListener);
14
+ };
15
+ }, [...dependingStateVariable]);
16
+ };
@@ -0,0 +1,70 @@
1
+ import { useSpacing } from './useSpacing';
2
+
3
+ describe('useSpacing should set propert padding and margin css properties', () => {
4
+ it('should set padding and margin for 4 values definition', () => {
5
+ const styles = useSpacing({ padding: '0 0.5 1 2', margin: '0 0.5 1 2' });
6
+ expect(styles).toHaveProperty('padding', '0rem 0.125rem 0.25rem 0.5rem');
7
+ expect(styles).toHaveProperty('margin', '0rem 0.125rem 0.25rem 0.5rem');
8
+ });
9
+
10
+ it('should set padding and margin for 3 values definition', () => {
11
+ const styles = useSpacing({ padding: '3 4 5', margin: '3 4 5' });
12
+ expect(styles).toHaveProperty('padding', '0.75rem 1rem 1.25rem');
13
+ expect(styles).toHaveProperty('margin', '0.75rem 1rem 1.25rem');
14
+ });
15
+
16
+ it('should set padding and margin for 2 values definition', () => {
17
+ const styles = useSpacing({ padding: '6 7', margin: '6 7' });
18
+ expect(styles).toHaveProperty('padding', '1.5rem 1.75rem');
19
+ expect(styles).toHaveProperty('margin', '1.5rem 1.75rem');
20
+ });
21
+
22
+ it('should set padding and margin for 1 value definition', () => {
23
+ const styles = useSpacing({ padding: 8, margin: '8' });
24
+ expect(styles).toHaveProperty('padding', '2rem');
25
+ expect(styles).toHaveProperty('margin', '2rem');
26
+ });
27
+
28
+ it('should set paddingLeft, paddingRight, paddingTop, paddingBottom, marginLeft, marginRight, marginTop, marginBottom css values when all provided', async () => {
29
+ const styles = useSpacing({
30
+ paddingLeft: '1',
31
+ paddingRight: 1,
32
+ paddingTop: '2',
33
+ paddingBottom: 0.5,
34
+ marginLeft: 3,
35
+ marginRight: 4,
36
+ marginTop: 5,
37
+ marginBottom: 6,
38
+ });
39
+ expect(styles).toHaveProperty('paddingLeft', '0.25rem');
40
+ expect(styles).toHaveProperty('paddingRight', '0.25rem');
41
+ expect(styles).toHaveProperty('paddingTop', '0.5rem');
42
+ expect(styles).toHaveProperty('paddingBottom', '0.125rem');
43
+ expect(styles).toHaveProperty('marginLeft', '0.75rem');
44
+ expect(styles).toHaveProperty('marginRight', '1rem');
45
+ expect(styles).toHaveProperty('marginTop', '1.25rem');
46
+ expect(styles).toHaveProperty('marginBottom', '1.5rem');
47
+ expect(styles?.padding).toBeUndefined();
48
+ expect(styles?.margin).toBeUndefined();
49
+ });
50
+ });
51
+
52
+ describe('useSpacing should add/repalce properties in passed style object', () => {
53
+ it('should add properties to style object', () => {
54
+ const styles = useSpacing({ padding: 8, margin: '8' }, { backgroundColor: 'red' });
55
+ expect(styles).toStrictEqual({ padding: '2rem', margin: '2rem', backgroundColor: 'red' });
56
+ });
57
+
58
+ it('should add and replace properties to style object', () => {
59
+ const styles = useSpacing(
60
+ { padding: 8, margin: '8' },
61
+ { padding: '2px', paddingTop: 2, backgroundColor: 'red' }
62
+ );
63
+ expect(styles).toStrictEqual({
64
+ padding: '2rem',
65
+ margin: '2rem',
66
+ paddingTop: 2,
67
+ backgroundColor: 'red',
68
+ });
69
+ });
70
+ });
@@ -0,0 +1,42 @@
1
+ import { CSSProperties } from 'react';
2
+
3
+ type SpacingMultiplier = 0 | 0.5 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
4
+ type SpacingMultiplierStringOrNumber = `${SpacingMultiplier}` | SpacingMultiplier;
5
+ type MultiValueSpacingMultiplier =
6
+ | `${SpacingMultiplier} ${SpacingMultiplier} ${SpacingMultiplier} ${SpacingMultiplier}`
7
+ | `${SpacingMultiplier} ${SpacingMultiplier} ${SpacingMultiplier}`
8
+ | `${SpacingMultiplier} ${SpacingMultiplier}`
9
+ | SpacingMultiplierStringOrNumber;
10
+
11
+ export interface Spacing {
12
+ padding?: MultiValueSpacingMultiplier;
13
+ paddingTop?: SpacingMultiplierStringOrNumber;
14
+ paddingBottom?: SpacingMultiplierStringOrNumber;
15
+ paddingLeft?: SpacingMultiplierStringOrNumber;
16
+ paddingRight?: SpacingMultiplierStringOrNumber;
17
+ margin?: MultiValueSpacingMultiplier;
18
+ marginTop?: SpacingMultiplierStringOrNumber;
19
+ marginBottom?: SpacingMultiplierStringOrNumber;
20
+ marginLeft?: SpacingMultiplierStringOrNumber;
21
+ marginRight?: SpacingMultiplierStringOrNumber;
22
+ }
23
+
24
+ const defaultFactor = 0.25;
25
+ const defaultUnit = 'rem';
26
+ const spacingNumberRegex = /(\d+\.?\d*)+/g;
27
+
28
+ export const useSpacing = (
29
+ spacingProps?: Spacing,
30
+ style?: CSSProperties
31
+ ): CSSProperties | undefined => {
32
+ if (spacingProps) {
33
+ return Object.entries(spacingProps).reduce<CSSProperties>((prev, [spacing, multiplier]) => {
34
+ const matches = String(multiplier).matchAll(spacingNumberRegex);
35
+ const cssSpacingValue = Array.from(matches)
36
+ .map(([multiplierValue]) => `${Number(multiplierValue) * defaultFactor}${defaultUnit}`)
37
+ .join(' ');
38
+ return { ...prev, [spacing]: cssSpacingValue };
39
+ }, style ?? {});
40
+ }
41
+ return style;
42
+ };
@@ -0,0 +1,49 @@
1
+ import { renderHook, act } from '@testing-library/react-hooks';
2
+ import { useWrapper } from './useWrapper';
3
+
4
+ describe('it should give the correct results based on no value, no placeholder and default text input', () => {
5
+ it('should execute correctly', () => {
6
+ const { result } = renderHook(() => useWrapper('', undefined, 'text'));
7
+
8
+ expect(result.current.helperId).toHaveLength(20);
9
+ expect(result.current.errorId).toHaveLength(20);
10
+ expect(result.current.labelId).toHaveLength(20);
11
+ expect(result.current.floatingLabelActive).toBe(false);
12
+
13
+ act(() => {
14
+ result.current.setFloatingLabelActive(true);
15
+ });
16
+
17
+ expect(result.current.floatingLabelActive).toBe(true);
18
+
19
+ act(() => {
20
+ result.current.setFloatingLabelActive(false);
21
+ });
22
+
23
+ expect(result.current.floatingLabelActive).toBe(false);
24
+
25
+ act(() => {
26
+ result.current.setHasFocus(true);
27
+ });
28
+
29
+ expect(result.current.floatingLabelActive).toBe(true);
30
+ });
31
+ });
32
+
33
+ describe('it should have floating label active because of the value', () => {
34
+ it('should have active floating label state', () => {
35
+ const { result } = renderHook(() => useWrapper('value', undefined, 'text'));
36
+
37
+ expect(result.current.floatingLabelActive).toBe(true);
38
+ });
39
+ it('should have floating label active because input type is datetime-local', () => {
40
+ const { result } = renderHook(() => useWrapper('', undefined, 'datetime-local'));
41
+
42
+ expect(result.current.floatingLabelActive).toBe(true);
43
+ });
44
+ it('should have floating label active because of placeholder', () => {
45
+ const { result } = renderHook(() => useWrapper('', 'placeholder', 'text'));
46
+
47
+ expect(result.current.floatingLabelActive).toBe(true);
48
+ });
49
+ });
@@ -0,0 +1,35 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { generateID } from '../util/helper';
3
+ import { Type as InputTypes } from '../Form/Input/Input';
4
+
5
+ export const useWrapper = (value?: string, placeholder?: string, type?: InputTypes) => {
6
+ const [helperId] = useState(generateID(20));
7
+ const [errorId] = useState(generateID(20));
8
+ const [labelId] = useState(generateID(20));
9
+ const [floatingLabelActive, setFloatingLabelActive] = useState(false);
10
+ const [hasFocus, setHasFocus] = useState(false);
11
+
12
+ useEffect(() => {
13
+ if (value?.length || placeholder || type === 'datetime-local' || type === 'time') {
14
+ setFloatingLabelActive(true);
15
+ }
16
+ }, []);
17
+
18
+ useEffect(() => {
19
+ if (value?.length || hasFocus) {
20
+ setFloatingLabelActive(true);
21
+ } else if (!placeholder && !hasFocus && type !== 'datetime-local' && type !== 'time') {
22
+ setFloatingLabelActive(false);
23
+ }
24
+ }, [value, placeholder, type, hasFocus]);
25
+
26
+ return {
27
+ helperId,
28
+ errorId,
29
+ labelId,
30
+ floatingLabelActive,
31
+ setFloatingLabelActive,
32
+ hasFocus,
33
+ setHasFocus,
34
+ };
35
+ };
package/src/index.ts ADDED
@@ -0,0 +1,52 @@
1
+ /** Components */
2
+ export { BaseStyling } from './_BaseStyling_/BaseStyling';
3
+ export { Typography } from './Typography/Typography';
4
+ export { Button } from './Button/Button';
5
+ export { Link } from './Link/Link';
6
+ export { IconButton } from './Button/IconButton';
7
+
8
+ export { Icon, Icons } from './Icon/Icon';
9
+
10
+ export { Dialog } from './Dialog/Dialog';
11
+ export { Modal } from './Modal/Modal';
12
+ export { ModalActions } from './Modal/ModalActions/ModalActions';
13
+ export { ModalContent } from './Modal/ModalContent/ModalContent';
14
+ export { ModalHeader } from './Modal/ModalHeader/ModalHeader';
15
+ export { Tooltip } from './Tooltip/Tooltip';
16
+ export { Tiles } from './Tiles/Tiles';
17
+ export { Tile } from './Tiles/Tile';
18
+ export { ContextMenu } from './ContextMenu/ContextMenu';
19
+ export { ContextMenuItem } from './ContextMenu/ContextMenuItem';
20
+ export { Breadcrumbs } from './Breadcrumbs/Breadcrumbs';
21
+
22
+ export { SnackbarProvider } from './Snackbar/SnackbarProvider/SnackbarProvider';
23
+ export { useSnackbar } from './Snackbar/useSnackbar';
24
+
25
+ /** Form components */
26
+ export { Form } from './Form/Form';
27
+ export { Fieldset } from './Form/Fieldset/Fieldset';
28
+ export { FormControl } from './Form/FormControl/FormControl';
29
+ export { FormGroup } from './Form/FormGroup/FormGroup';
30
+ export { FormHelperText } from './Form/FormHelperText/FormHelperText';
31
+ export { Label } from './Form/Label/Label';
32
+ export { Select } from './Form/Select/Select';
33
+ export { Option } from './Form/Select/Option';
34
+ export { Textarea } from './Form/Textarea/Textarea';
35
+ export { CheckboxWrapper } from './Form/Wrapper/CheckboxWrapper/CheckboxWrapper';
36
+ export { InputWrapper } from './Form/Wrapper/InputWrapper/InputWrapper';
37
+ export { RadioWrapper } from './Form/Wrapper/RadioWrapper/RadioWrapper';
38
+ export { SelectWrapper } from './Form/Wrapper/SelectWrapper/SelectWrapper';
39
+ export { TextareaWrapper } from './Form/Wrapper/TextareaWrapper/TextareaWrapper';
40
+ export { Input } from './Form/Input/Input';
41
+ export { Radio } from './Form/Radio/Radio';
42
+ export { Checkbox } from './Form/Checkbox/Checkbox';
43
+
44
+ /** Wizard */
45
+ export {
46
+ BaseWizardSteps,
47
+ Props as BaseWizardStepsProps,
48
+ Step as WizardStep,
49
+ } from './Wizard/BaseWizardSteps/BaseWizardSteps';
50
+ export { WizardActions } from './Wizard/WizardActions/WizardActions';
51
+ export { WizardSteps } from './Wizard/WizardSteps/WizardSteps';
52
+ export { Wizard, Props as WizardProps } from './Wizard/Wizard';
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+
3
+ /**
4
+ * By default typescript does not allow data-* attributes on HTMLAttributes interface. We extend the default React.HTMLAttributes interface here and add the dataAttribute possibility into it.
5
+ * An example of this can be found in Checkbox.tsx. We assign wrapperProps to the HTMLAttributes interface below, and are now able to add a test-id inside of Checkbox.test.tsx on line 77.
6
+ */
7
+ type DataAttributeKey = `data-${string}`;
8
+
9
+ export interface HTMLProps<T> extends React.HTMLProps<T> {
10
+ [dataAttribute: DataAttributeKey]: any;
11
+ }
12
+
13
+ export interface HTMLAttributes<T> extends React.HTMLAttributes<T> {
14
+ [dataAttribute: DataAttributeKey]: any;
15
+ }