stargazer-ui 1.2.0 → 1.2.1

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 (349) hide show
  1. package/.babelrc.json +10 -0
  2. package/.eslintrc.cjs +18 -0
  3. package/.gitattributes +2 -0
  4. package/LICENSE +21 -0
  5. package/dev/index.html +12 -0
  6. package/dev/index.jsx +49 -0
  7. package/dev/index.scss +59 -0
  8. package/dev/pages/ButtonPage.jsx +44 -0
  9. package/dev/pages/CardPage.jsx +81 -0
  10. package/dev/pages/DropdownPage.jsx +31 -0
  11. package/dev/pages/FormPage.jsx +130 -0
  12. package/dev/pages/ListPage.jsx +52 -0
  13. package/dev/pages/ModalPage.jsx +37 -0
  14. package/dev/pages/OverlayPage.jsx +35 -0
  15. package/dev/pages/components.jsx +19 -0
  16. package/{styles → dev}/stargazerui.css +392 -3075
  17. package/dev/stargazerui.css.map +1 -0
  18. package/dev/test.jsx +88 -0
  19. package/package.json +79 -1
  20. package/rollup.config.js +140 -0
  21. package/scripts/writePackageJsons.js +42 -0
  22. package/src/Bar/Bar.tsx +0 -0
  23. package/src/Bar/Bar.type.ts +9 -0
  24. package/src/Bar/index.ts +0 -0
  25. package/src/Button/Button.tsx +17 -0
  26. package/src/Button/Button.types.ts +8 -0
  27. package/src/Button/index.ts +3 -0
  28. package/src/ButtonGroup/ButtonGroup.tsx +14 -0
  29. package/src/ButtonGroup/ButtonGroup.types.ts +8 -0
  30. package/src/ButtonGroup/index.ts +3 -0
  31. package/src/Card/Card.tsx +70 -0
  32. package/src/Card/Card.types.ts +33 -0
  33. package/src/Card/index.ts +3 -0
  34. package/src/CloseButton/CloseButton.tsx +14 -0
  35. package/src/CloseButton/CloseButton.types.ts +6 -0
  36. package/src/CloseButton/index.ts +3 -0
  37. package/src/Dropdown/Dropdown.tsx +358 -0
  38. package/src/Dropdown/Dropdown.types.ts +52 -0
  39. package/src/Dropdown/index.ts +4 -0
  40. package/src/FileUploadButton/FileUploadButton.tsx +27 -0
  41. package/src/FileUploadButton/FileUploadButton.types.ts +9 -0
  42. package/src/FileUploadButton/index.ts +3 -0
  43. package/src/FloatingLabel/FloatingLabel.tsx +22 -0
  44. package/src/FloatingLabel/FloatingLabel.types.ts +11 -0
  45. package/src/FloatingLabel/index.ts +3 -0
  46. package/src/Form/Form.tsx +445 -0
  47. package/src/Form/Form.types.ts +117 -0
  48. package/src/Form/index.ts +4 -0
  49. package/src/InputGroup/InputGroup.tsx +46 -0
  50. package/src/InputGroup/InputGroup.types.ts +21 -0
  51. package/src/InputGroup/index.ts +4 -0
  52. package/src/List/List.tsx +112 -0
  53. package/src/List/List.types.ts +34 -0
  54. package/src/List/index.ts +4 -0
  55. package/src/Modal/Modal.tsx +220 -0
  56. package/src/Modal/Modal.types.ts +49 -0
  57. package/src/Modal/index.ts +4 -0
  58. package/src/Nav/Nav.tsx +43 -0
  59. package/src/Nav/Nav.types.ts +21 -0
  60. package/src/Nav/index.ts +4 -0
  61. package/src/NavBar/Navbar.tsx +57 -0
  62. package/src/NavBar/Navbar.types.ts +24 -0
  63. package/src/NavBar/index.ts +4 -0
  64. package/src/NavDropdown/NavDropdown.tsx +93 -0
  65. package/src/NavDropdown/NavDropdown.types.ts +6 -0
  66. package/src/NavDropdown/index.ts +3 -0
  67. package/src/Overlay/Overlay.tsx +277 -0
  68. package/src/Overlay/Overlay.types.ts +20 -0
  69. package/{Overlay/index.d.ts → src/Overlay/index.ts} +3 -3
  70. package/src/Popout/Popout.tsx +155 -0
  71. package/src/Popout/Popout.types.ts +42 -0
  72. package/src/Popout/index.ts +3 -0
  73. package/src/Spinner/Spinner.tsx +15 -0
  74. package/src/Spinner/Spinner.types.ts +7 -0
  75. package/src/Spinner/index.ts +3 -0
  76. package/src/Table/Table.tsx +16 -0
  77. package/src/Table/Table.types.ts +9 -0
  78. package/src/Table/index.ts +3 -0
  79. package/src/Tabs/Tabs.tsx +215 -0
  80. package/src/Tabs/Tabs.types.ts +49 -0
  81. package/src/Tabs/index.ts +3 -0
  82. package/src/ToggleButton/ToggleButton.tsx +21 -0
  83. package/src/ToggleButton/ToggleButton.types.ts +8 -0
  84. package/src/ToggleButton/index.ts +3 -0
  85. package/{hooks/index.d.ts → src/hooks/index.ts} +6 -5
  86. package/src/hooks/useClassname.ts +5 -0
  87. package/src/hooks/useDraggable.ts +186 -0
  88. package/src/hooks/useKeepElementFocused.ts +37 -0
  89. package/src/hooks/useScreenSize.ts +24 -0
  90. package/src/index.ts +21 -0
  91. package/src/styles/_Card.scss +166 -0
  92. package/src/styles/_CloseButton.scss +51 -0
  93. package/src/styles/_CustomButton.scss +132 -0
  94. package/src/styles/_Dropdown.scss +120 -0
  95. package/src/styles/_FloatingLabel.scss +56 -0
  96. package/src/styles/_Forms.scss +7 -0
  97. package/src/styles/_Grid.scss +178 -0
  98. package/src/styles/_InputGroup.scss +71 -0
  99. package/src/styles/_List.scss +62 -0
  100. package/src/styles/_Modal.scss +234 -0
  101. package/src/styles/_ModalOld.scss +242 -0
  102. package/src/styles/_Nav.scss +36 -0
  103. package/src/styles/_NavBar.scss +116 -0
  104. package/src/styles/_NavDropdown.scss +34 -0
  105. package/src/styles/_OffCanvas.scss +260 -0
  106. package/src/styles/_OverLay.scss +56 -0
  107. package/src/styles/_Popout.scss +75 -0
  108. package/src/styles/_Spinner.scss +19 -0
  109. package/src/styles/_Table.scss +34 -0
  110. package/src/styles/_Tabs.scss +129 -0
  111. package/src/styles/_colors.scss +510 -0
  112. package/src/styles/_components.scss +40 -0
  113. package/src/styles/_functions.scss +134 -0
  114. package/src/styles/_mixins.scss +26 -0
  115. package/src/styles/_reset.scss +231 -0
  116. package/src/styles/_utilities.scss +2480 -0
  117. package/src/styles/_variables.scss +146 -0
  118. package/src/styles/forms/_FormCheck.scss +269 -0
  119. package/src/styles/forms/_FormControl.scss +102 -0
  120. package/src/styles/forms/_FormGroup.scss +21 -0
  121. package/src/styles/forms/_FormLabel.scss +3 -0
  122. package/src/styles/forms/_FormSelect.scss +164 -0
  123. package/src/styles/forms/_FormSlider.scss +116 -0
  124. package/src/styles/forms/_FormText.scss +6 -0
  125. package/{utils/BaseTypes.d.ts → src/utils/BaseTypes.ts} +30 -23
  126. package/src/utils/ContrastingColor.ts +25 -0
  127. package/src/utils/FileImportExport.js +50 -0
  128. package/src/utils/MergeClassnames.ts +5 -0
  129. package/src/utils/MergeRefs.ts +12 -0
  130. package/src/vite-env.d.ts +1 -0
  131. package/tsconfig-build.json +4 -0
  132. package/tsconfig.json +79 -0
  133. package/tsconfig.node.json +10 -0
  134. package/types/BaseTypes.d.ts +19 -0
  135. package/{Button → types/components/Button}/Button.types.d.ts +2 -1
  136. package/types/components/Button/index.d.ts +1 -0
  137. package/{Card → types/components/Card}/Card.types.d.ts +1 -3
  138. package/types/components/Card/index.d.ts +1 -0
  139. package/{CloseButton → types/components/CloseButton}/CloseButton.types.d.ts +1 -1
  140. package/types/components/CloseButton/index.d.ts +1 -0
  141. package/{Dropdown → types/components/Dropdown}/Dropdown.types.d.ts +10 -3
  142. package/types/components/Dropdown/index.d.ts +1 -0
  143. package/{FloatingLabel → types/components/FloatingLabel}/FloatingLabel.types.d.ts +1 -1
  144. package/types/components/FloatingLabel/index.d.ts +1 -0
  145. package/types/components/Form/Form.d.ts +17 -0
  146. package/types/components/Form/Form.types.d.ts +50 -0
  147. package/types/components/Form/index.d.ts +1 -0
  148. package/types/components/InputGroup/InputGroup.d.ts +6 -0
  149. package/types/components/InputGroup/InputGroup.types.d.ts +10 -0
  150. package/types/components/InputGroup/index.d.ts +1 -0
  151. package/{Modal → types/components/Modal}/Modal.d.ts +1 -1
  152. package/{Modal → types/components/Modal}/Modal.types.d.ts +2 -3
  153. package/types/components/Modal/index.d.ts +1 -0
  154. package/{Nav → types/components/Nav}/Nav.types.d.ts +1 -1
  155. package/types/components/Nav/index.d.ts +1 -0
  156. package/{NavBar → types/components/NavBar}/Navbar.d.ts +2 -1
  157. package/{NavBar → types/components/NavBar}/Navbar.types.d.ts +1 -2
  158. package/types/components/NavBar/index.d.ts +1 -0
  159. package/{NavDropdown → types/components/NavDropdown}/NavDropdown.d.ts +2 -2
  160. package/types/components/NavDropdown/index.d.ts +1 -0
  161. package/{Popout → types/components/Popout}/Popout.types.d.ts +1 -1
  162. package/types/components/Popout/index.d.ts +1 -0
  163. package/types/components/Spinner/index.d.ts +1 -0
  164. package/{Table → types/components/Table}/Table.types.d.ts +1 -1
  165. package/types/components/Table/index.d.ts +1 -0
  166. package/{Tabs → types/components/Tabs}/Tabs.types.d.ts +1 -9
  167. package/types/components/Tabs/index.d.ts +1 -0
  168. package/types/components/ToggleButton/ToggleButton.d.ts +9 -0
  169. package/types/components/ToggleButton/ToggleButton.types.d.ts +0 -0
  170. package/types/components/ToggleButton/index.d.ts +1 -0
  171. package/types/components/index.d.ts +16 -0
  172. package/types/index.d.ts +1 -0
  173. package/vite.config.js +57 -0
  174. package/vite.config.js.timestamp-1708777378490-e94428ceb2bf9.mjs +42 -0
  175. package/Bar/Bar.type.d.ts +0 -6
  176. package/Bar/index.js +0 -2
  177. package/Bar/index.js.map +0 -1
  178. package/Bar/package.json +0 -1
  179. package/Button/Button.js +0 -12
  180. package/Button/Button.js.map +0 -1
  181. package/Button/index.d.ts +0 -3
  182. package/Button/index.js +0 -7
  183. package/Button/index.js.map +0 -1
  184. package/Button/package.json +0 -1
  185. package/ButtonGroup/ButtonGroup.d.ts +0 -4
  186. package/ButtonGroup/ButtonGroup.js +0 -10
  187. package/ButtonGroup/ButtonGroup.js.map +0 -1
  188. package/ButtonGroup/ButtonGroup.types.d.ts +0 -7
  189. package/ButtonGroup/index.d.ts +0 -3
  190. package/ButtonGroup/index.js +0 -7
  191. package/ButtonGroup/index.js.map +0 -1
  192. package/ButtonGroup/package.json +0 -1
  193. package/Card/Card.js +0 -41
  194. package/Card/Card.js.map +0 -1
  195. package/Card/index.d.ts +0 -3
  196. package/Card/index.js +0 -7
  197. package/Card/index.js.map +0 -1
  198. package/Card/package.json +0 -1
  199. package/CloseButton/CloseButton.js +0 -11
  200. package/CloseButton/CloseButton.js.map +0 -1
  201. package/CloseButton/index.d.ts +0 -3
  202. package/CloseButton/index.js +0 -7
  203. package/CloseButton/index.js.map +0 -1
  204. package/CloseButton/package.json +0 -1
  205. package/Dropdown/Dropdown.js +0 -292
  206. package/Dropdown/Dropdown.js.map +0 -1
  207. package/Dropdown/index.d.ts +0 -4
  208. package/Dropdown/index.js +0 -8
  209. package/Dropdown/index.js.map +0 -1
  210. package/Dropdown/package.json +0 -1
  211. package/FileUploadButton/FileUploadButton.d.ts +0 -4
  212. package/FileUploadButton/FileUploadButton.js +0 -21
  213. package/FileUploadButton/FileUploadButton.js.map +0 -1
  214. package/FileUploadButton/FileUploadButton.types.d.ts +0 -7
  215. package/FileUploadButton/index.d.ts +0 -3
  216. package/FileUploadButton/index.js +0 -7
  217. package/FileUploadButton/index.js.map +0 -1
  218. package/FileUploadButton/package.json +0 -1
  219. package/FloatingLabel/FloatingLabel.js +0 -17
  220. package/FloatingLabel/FloatingLabel.js.map +0 -1
  221. package/FloatingLabel/index.d.ts +0 -3
  222. package/FloatingLabel/index.js +0 -7
  223. package/FloatingLabel/index.js.map +0 -1
  224. package/FloatingLabel/package.json +0 -1
  225. package/Form/Form.d.ts +0 -38
  226. package/Form/Form.js +0 -308
  227. package/Form/Form.js.map +0 -1
  228. package/Form/Form.types.d.ts +0 -105
  229. package/Form/index.d.ts +0 -4
  230. package/Form/index.js +0 -8
  231. package/Form/index.js.map +0 -1
  232. package/Form/package.json +0 -1
  233. package/InputGroup/InputGroup.d.ts +0 -7
  234. package/InputGroup/InputGroup.js +0 -31
  235. package/InputGroup/InputGroup.js.map +0 -1
  236. package/InputGroup/InputGroup.types.d.ts +0 -16
  237. package/InputGroup/index.d.ts +0 -4
  238. package/InputGroup/index.js +0 -7
  239. package/InputGroup/index.js.map +0 -1
  240. package/InputGroup/package.json +0 -1
  241. package/List/List.d.ts +0 -14
  242. package/List/List.js +0 -76
  243. package/List/List.js.map +0 -1
  244. package/List/List.types.d.ts +0 -28
  245. package/List/index.d.ts +0 -3
  246. package/List/index.js +0 -7
  247. package/List/index.js.map +0 -1
  248. package/List/package.json +0 -1
  249. package/Modal/Modal.js +0 -160
  250. package/Modal/Modal.js.map +0 -1
  251. package/Modal/index.d.ts +0 -3
  252. package/Modal/index.js +0 -7
  253. package/Modal/index.js.map +0 -1
  254. package/Modal/package.json +0 -1
  255. package/Nav/Nav.js +0 -28
  256. package/Nav/Nav.js.map +0 -1
  257. package/Nav/index.d.ts +0 -4
  258. package/Nav/index.js +0 -7
  259. package/Nav/index.js.map +0 -1
  260. package/Nav/package.json +0 -1
  261. package/NavBar/Navbar.js +0 -36
  262. package/NavBar/Navbar.js.map +0 -1
  263. package/NavBar/index.d.ts +0 -4
  264. package/NavBar/index.js +0 -8
  265. package/NavBar/index.js.map +0 -1
  266. package/NavBar/package.json +0 -1
  267. package/NavDropdown/NavDropdown.js +0 -77
  268. package/NavDropdown/NavDropdown.js.map +0 -1
  269. package/NavDropdown/index.d.ts +0 -3
  270. package/NavDropdown/index.js +0 -7
  271. package/NavDropdown/index.js.map +0 -1
  272. package/NavDropdown/package.json +0 -1
  273. package/Overlay/Overlay.d.ts +0 -4
  274. package/Overlay/Overlay.js +0 -228
  275. package/Overlay/Overlay.js.map +0 -1
  276. package/Overlay/Overlay.types.d.ts +0 -18
  277. package/Overlay/index.js +0 -7
  278. package/Overlay/index.js.map +0 -1
  279. package/Overlay/package.json +0 -1
  280. package/Popout/Popout.js +0 -110
  281. package/Popout/Popout.js.map +0 -1
  282. package/Popout/index.d.ts +0 -3
  283. package/Popout/index.js +0 -7
  284. package/Popout/index.js.map +0 -1
  285. package/Popout/package.json +0 -1
  286. package/Spinner/Spinner.js +0 -12
  287. package/Spinner/Spinner.js.map +0 -1
  288. package/Spinner/index.d.ts +0 -3
  289. package/Spinner/index.js +0 -7
  290. package/Spinner/index.js.map +0 -1
  291. package/Spinner/package.json +0 -1
  292. package/Table/Table.js +0 -11
  293. package/Table/Table.js.map +0 -1
  294. package/Table/index.d.ts +0 -3
  295. package/Table/index.js +0 -7
  296. package/Table/index.js.map +0 -1
  297. package/Table/package.json +0 -1
  298. package/Tabs/Tabs.js +0 -158
  299. package/Tabs/Tabs.js.map +0 -1
  300. package/Tabs/index.d.ts +0 -3
  301. package/Tabs/index.js +0 -7
  302. package/Tabs/index.js.map +0 -1
  303. package/Tabs/package.json +0 -1
  304. package/ToggleButton/ToggleButton.d.ts +0 -4
  305. package/ToggleButton/ToggleButton.js +0 -17
  306. package/ToggleButton/ToggleButton.js.map +0 -1
  307. package/ToggleButton/ToggleButton.types.d.ts +0 -7
  308. package/ToggleButton/index.d.ts +0 -3
  309. package/ToggleButton/index.js +0 -7
  310. package/ToggleButton/index.js.map +0 -1
  311. package/ToggleButton/package.json +0 -1
  312. package/hooks/index.js +0 -6
  313. package/hooks/index.js.map +0 -1
  314. package/hooks/package.json +0 -1
  315. package/hooks/useClassname.d.ts +0 -2
  316. package/hooks/useClassname.js +0 -7
  317. package/hooks/useClassname.js.map +0 -1
  318. package/hooks/useDraggable.d.ts +0 -23
  319. package/hooks/useDraggable.js +0 -147
  320. package/hooks/useDraggable.js.map +0 -1
  321. package/hooks/useKeepElementFocused.d.ts +0 -2
  322. package/hooks/useKeepElementFocused.js +0 -37
  323. package/hooks/useKeepElementFocused.js.map +0 -1
  324. package/hooks/useScreenSize.d.ts +0 -5
  325. package/hooks/useScreenSize.js +0 -21
  326. package/hooks/useScreenSize.js.map +0 -1
  327. package/index.d.ts +0 -18
  328. package/index.js +0 -19
  329. package/index.js.map +0 -1
  330. package/styles/stargazerui.css.map +0 -1
  331. package/utils/ContrastingColor.d.ts +0 -1
  332. package/utils/MergeClassnames.d.ts +0 -2
  333. package/utils/MergeClassnames.js +0 -7
  334. package/utils/MergeClassnames.js.map +0 -1
  335. package/utils/MergeRefs.d.ts +0 -2
  336. package/utils/MergeRefs.js +0 -16
  337. package/utils/MergeRefs.js.map +0 -1
  338. /package/{Button → types/components/Button}/Button.d.ts +0 -0
  339. /package/{Card → types/components/Card}/Card.d.ts +0 -0
  340. /package/{CloseButton → types/components/CloseButton}/CloseButton.d.ts +0 -0
  341. /package/{Dropdown → types/components/Dropdown}/Dropdown.d.ts +0 -0
  342. /package/{FloatingLabel → types/components/FloatingLabel}/FloatingLabel.d.ts +0 -0
  343. /package/{Nav → types/components/Nav}/Nav.d.ts +0 -0
  344. /package/{NavDropdown → types/components/NavDropdown}/NavDropdown.types.d.ts +0 -0
  345. /package/{Popout → types/components/Popout}/Popout.d.ts +0 -0
  346. /package/{Spinner → types/components/Spinner}/Spinner.d.ts +0 -0
  347. /package/{Spinner → types/components/Spinner}/Spinner.types.d.ts +0 -0
  348. /package/{Table → types/components/Table}/Table.d.ts +0 -0
  349. /package/{Tabs → types/components/Tabs}/Tabs.d.ts +0 -0
@@ -0,0 +1,6 @@
1
+ import { DropdownType } from "../Dropdown/Dropdown.types"
2
+
3
+ export type NavDropdownType = {
4
+ toggleProps?: any,
5
+ menuProps?:any
6
+ } & DropdownType
@@ -0,0 +1,3 @@
1
+ import NavDropdown from "./NavDropdown"
2
+ export default NavDropdown
3
+ export type { NavDropdownType } from "./NavDropdown.types"
@@ -0,0 +1,277 @@
1
+ import React, { useEffect, useRef, useState, cloneElement, forwardRef, ReactNode, useLayoutEffect } from "react";
2
+ import { createPortal } from "react-dom";
3
+ import { OverlayType, PositionObject } from "./Overlay.types";
4
+
5
+ import mergeRefs from "../utils/MergeRefs";
6
+
7
+ const setPosition = (referenceElement:any, overlayElement:any, position:string, arrowElement: any, isArrow: boolean=false, boundaryCorrection: PositionObject = {top:0, left:0, bottom: 0, right: 0}) => {
8
+ const refCurrent = referenceElement.current as HTMLElement
9
+ const overlayCurrent = overlayElement.current as HTMLElement
10
+ const arrowCurrent = arrowElement.current as HTMLElement
11
+
12
+ const refTop = refCurrent.getBoundingClientRect().top
13
+ const refHeight = refCurrent.offsetHeight
14
+ const refLeft = refCurrent.getBoundingClientRect().left
15
+ const refWidth = refCurrent.offsetWidth
16
+
17
+ const overlayHeight = overlayCurrent.clientHeight
18
+ const overlayWidth = overlayCurrent.clientWidth
19
+
20
+ const arrowHeight = arrowCurrent.clientHeight
21
+ const arrowWidth = arrowCurrent.clientWidth
22
+
23
+ const arrowOffsetHeight = isArrow ? 0 : arrowHeight - 1
24
+ const arrowOffsetWidth = isArrow ? 0 : arrowWidth - 1
25
+
26
+ const correctPosition = (position:string, offset:number, boundary:number) => {
27
+ const positionKey = position as keyof typeof tempPos
28
+ if(overlayCurrent.getBoundingClientRect()[positionKey]<= boundary) {
29
+ return offset
30
+ }
31
+ else {
32
+ return tempPos[positionKey]
33
+ }
34
+ }
35
+
36
+ let tempPos: PositionObject
37
+ switch(position) {
38
+ case "top":
39
+ tempPos = {
40
+ top: refTop - overlayHeight - arrowOffsetHeight,
41
+ left: refLeft + refWidth/2 - overlayWidth/2
42
+ }
43
+ //tempPos.right = correctPosition("right", 12, 0)
44
+ //tempPos.left = correctPosition("left", 0, 0)
45
+ return tempPos
46
+ case "right":
47
+ tempPos = {
48
+ top: refTop + refHeight/2 - overlayHeight/2,
49
+ left: refLeft + refWidth + arrowOffsetWidth
50
+ }
51
+ //tempPos.bottom = correctPosition("bottom", window.scrollY + window.innerHeight, 0)
52
+ //tempPos.top = correctPosition("top", window.scrollY, 48)
53
+ return tempPos
54
+ case "bottom":
55
+ tempPos = {
56
+ top: refTop + refHeight + arrowOffsetHeight,
57
+ left: refLeft + refWidth/2 - overlayWidth/2
58
+ }
59
+ //tempPos.right = correctPosition("right", 12, 0)
60
+ //tempPos.left = correctPosition("left", 0, 0)
61
+ return tempPos
62
+ case "left":
63
+ tempPos = {
64
+ top: refTop + refHeight/2 - overlayHeight/2,
65
+ left: refLeft - overlayWidth - arrowOffsetWidth
66
+ }
67
+ //tempPos.bottom = correctPosition("bottom", window.scrollY + window.innerHeight, 0)
68
+ //tempPos.top = correctPosition("top", window.scrollY, 48)
69
+ return tempPos
70
+ default:
71
+ //this is just top
72
+ return { top: refTop - overlayHeight - arrowHeight, left: refLeft + refWidth/2 - overlayWidth/2 }
73
+ }
74
+ }
75
+
76
+ const updateAutoPosition = (autoPositionRef:any, positionRef:any, overlayRef:any, arrowRef:any) => {
77
+ let topDistance = positionRef.current.getBoundingClientRect().top
78
+ let bottomDistance = window.innerHeight - positionRef.current.getBoundingClientRect().bottom
79
+ let leftDistance = positionRef.current.getBoundingClientRect().left
80
+ let rightDistance = window.innerWidth - positionRef.current.getBoundingClientRect().right
81
+
82
+ let totalOverlayWidth = overlayRef.current.clientWidth + arrowRef.current.clientWidth + 48
83
+ let totalOverlayHeight = overlayRef.current.clientHeight + arrowRef.current.clientHeight + 48
84
+ //console.log(autoPositionRef.current, positionRef.current, overlayRef.current, arrowRef.current)
85
+
86
+ if(topDistance >= totalOverlayHeight) {
87
+ return "top"
88
+ } else if(topDistance >= totalOverlayHeight/2) {
89
+ return rightDistance >= totalOverlayWidth ? "right" : "left"
90
+ } else if(bottomDistance >= totalOverlayHeight) {
91
+ return "bottom"
92
+ } else {
93
+ return autoPositionRef.current
94
+ }
95
+ }
96
+
97
+ const Overlay = forwardRef<HTMLDivElement, OverlayType>( ({children, overlay, tooltip, show=false, onToggle, position="auto", trigger="click", defaultShow=false}, ref) => {
98
+ if(Array.isArray(children)) {
99
+ throw new Error(
100
+ "Overlay can only wrap a single element, either introduce a wrapper or remove all but one trigger element!"
101
+ )
102
+ }
103
+
104
+ const positionRef = useRef<typeof children | null>(null)
105
+ const overlayRef = useRef<HTMLDivElement | null>(null)
106
+ const arrowRef = useRef<HTMLDivElement>(null)
107
+ const [arrowPosition, setArrowPosition] = useState<PositionObject>({top:0, left:0})
108
+ const [overlayPosition, setOverlayPosition] = useState<PositionObject>({top:0, left:0})
109
+ const [internalShow, setInternalShow] = useState(defaultShow)
110
+ const internalShowRef = useRef(internalShow)
111
+ const setInternalShowRef = (updatedValue: boolean) => {
112
+ internalShowRef.current = updatedValue
113
+ setInternalShow(updatedValue)
114
+ }
115
+ if(show && show != internalShow) {
116
+ console.log("show")
117
+ setInternalShowRef(show)
118
+ }
119
+
120
+ //const positionsList = ["top", "right", "bottom", "left"]
121
+ const [autoPosition, setAutoPosition] = useState(position === "auto" ? "top" : position)
122
+ const autoPositionRef = useRef(autoPosition)
123
+ const setAutoPositionRef = (updatedValue: any) => {
124
+ autoPositionRef.current = updatedValue
125
+ setAutoPosition(updatedValue)
126
+ }
127
+
128
+ const [isHovering, setIsHovering] = useState(false)
129
+ const [isFocused, setIsFocused] = useState(false)
130
+ const [firstClick, setFirstClick] = useState(true)
131
+ const triggerArray = Array.isArray(trigger) ? trigger : [trigger]
132
+
133
+ const positionSetter = (positionRef:any , overlayRef: any, arrowRef: any) => {
134
+ setOverlayPosition( setPosition(positionRef, overlayRef, autoPositionRef.current, arrowRef) )
135
+ setArrowPosition( setPosition(positionRef, arrowRef, autoPositionRef.current, arrowRef, true) )
136
+ }
137
+ const handleScroll = () => {
138
+ if(internalShowRef.current) {
139
+ positionSetter(positionRef, overlayRef, arrowRef)
140
+ }
141
+ if(internalShowRef.current && position === "auto") {
142
+ let updatedPosition = updateAutoPosition(autoPositionRef, positionRef, overlayRef, arrowRef)
143
+ setAutoPositionRef(updatedPosition)
144
+ }
145
+ }
146
+ const resizeHandler = () => {
147
+ if(internalShowRef.current) {
148
+ positionSetter(positionRef, overlayRef, arrowRef)
149
+ }
150
+ if(!internalShowRef.current && position === "auto") {
151
+ //setAutoPosition(detectAutoPostition(overlayRef, autoPositionRef))
152
+ }
153
+ }
154
+
155
+ /* Event handler funtions */
156
+ const onClick = (event: MouseEvent) => {
157
+ //console.log("click")
158
+ if(isFocused && firstClick) {
159
+ //this is needed in case both "focus" and "click" are triggers, otherwise there's weird behaviour
160
+ setFirstClick(false)
161
+ return
162
+ }
163
+ setInternalShowRef(!internalShow)
164
+ if(onToggle) {
165
+ onToggle(!internalShow)
166
+ }
167
+ }
168
+ const onHover = (event: MouseEvent) => {
169
+ setInternalShowRef(true)
170
+ if(!isHovering) {
171
+ setIsHovering(true)
172
+ if(onToggle) {
173
+ onToggle(true)
174
+ }
175
+ }
176
+ }
177
+ const onFocus = (event: MouseEvent) => {
178
+ //console.log("focus")
179
+ setInternalShowRef(true)
180
+ setIsFocused(true)
181
+ if(onToggle) {
182
+ onToggle(true)
183
+ }
184
+ }
185
+ const onBlur = (event: MouseEvent) => {
186
+ //console.log("blur")
187
+ if(isHovering) {
188
+ setIsHovering(false)
189
+ } else if(isFocused) {
190
+ setIsFocused(false)
191
+ setFirstClick(true)
192
+ }
193
+ setInternalShowRef(false)
194
+ if(onToggle) {
195
+ onToggle(false)
196
+ }
197
+ }
198
+ useLayoutEffect(() => {
199
+ if(overlayRef.current && arrowRef.current) {
200
+ positionSetter(positionRef, overlayRef, arrowRef)
201
+ }
202
+ }, [])
203
+
204
+ useEffect(() => {
205
+ if(overlayRef.current && arrowRef.current) {
206
+ positionSetter(positionRef, overlayRef, arrowRef)
207
+ }
208
+ //setInternalShowRef(show)
209
+ },[internalShow, overlayRef, positionRef, autoPosition])
210
+
211
+
212
+ useEffect(() => {
213
+ window.addEventListener("scroll", handleScroll, true)
214
+ window.addEventListener("resize", resizeHandler, true)
215
+ return function cleanup() {
216
+ window.removeEventListener("scroll", handleScroll, true)
217
+ window.removeEventListener("resize", resizeHandler, true)
218
+ }
219
+ }, [])
220
+
221
+ const checkRefPositionStyle = (positionRef: any) => {
222
+ let elementComputedPositionStyle = getComputedStyle(positionRef.current)["position"]
223
+ if(elementComputedPositionStyle === "fixed") {
224
+ return "fixed"
225
+ } else if(elementComputedPositionStyle === "sticky") {
226
+ return "sticky"
227
+ } else {
228
+ return "absolute"
229
+ }
230
+ }
231
+ return (
232
+ <>
233
+ {
234
+ cloneElement(children as any, {
235
+ ref: positionRef,
236
+ onClick: triggerArray.find(trigger => trigger === "click") ? onClick : null,
237
+ onMouseOver: triggerArray.find(trigger => trigger === "hover") ? onHover : null,
238
+ onMouseLeave: triggerArray.find(trigger => trigger === "hover") ? onBlur : null,
239
+ onFocus: triggerArray.find(trigger => trigger === "focus") ? onFocus : null,
240
+ onBlur: triggerArray.find(trigger => trigger === "focus") ? onBlur : null,
241
+ })
242
+ }
243
+ {internalShow ? createPortal(
244
+ overlay ?
245
+ <>
246
+ <div className="sg-overlay-wrapper"
247
+ ref={mergeRefs([ref,overlayRef])}
248
+ style={{ position:checkRefPositionStyle(positionRef), top:overlayPosition!.top, left:overlayPosition!.left }}
249
+ >{overlay}</div>
250
+ <div
251
+ ref={arrowRef} aria-hidden
252
+ className={`sg-overlay-arrow${autoPosition ? " overlay-position-"+autoPosition : ""}`}
253
+ style={{position:checkRefPositionStyle(positionRef), top:arrowPosition!.top, left:arrowPosition!.left,}}>
254
+ </div>
255
+ </>
256
+ :
257
+ tooltip ?
258
+ <>
259
+ <div className="sg-overlay-wrapper sg-tooltip-wrapper"
260
+ ref={mergeRefs([ref,overlayRef])}
261
+ style={{ position:checkRefPositionStyle(positionRef), top:overlayPosition!.top, left:overlayPosition!.left }}
262
+ >{tooltip}</div>
263
+ <div
264
+ ref={arrowRef} aria-hidden
265
+ className={`sg-overlay-arrow sg-tooltip-arrow${autoPosition ? " overlay-position-"+autoPosition : ""}`}
266
+ style={{position:checkRefPositionStyle(positionRef), top:arrowPosition!.top, left:arrowPosition!.left,}}>
267
+ </div>
268
+ </>
269
+ :
270
+ null
271
+ , document.body) : null}
272
+ </>
273
+ )
274
+ })
275
+ Overlay.displayName = "Overlay"
276
+
277
+ export default Overlay
@@ -0,0 +1,20 @@
1
+ import { ReactNode } from "react"
2
+ import { BaseDivType } from "../utils/BaseTypes"
3
+
4
+ export type OverlayType = {
5
+ children: ReactNode,
6
+ overlay?: React.JSX.Element,
7
+ tooltip?: React.JSX.Element,
8
+ show?: boolean,
9
+ onToggle?: Function,
10
+ position?: string,
11
+ trigger?: string | string[],
12
+ defaultShow?: boolean
13
+ } & BaseDivType
14
+
15
+ export type PositionObject = {
16
+ top?: number,
17
+ bottom?: number,
18
+ left?: number,
19
+ right?:number
20
+ }
@@ -1,3 +1,3 @@
1
- import Overlay from "./Overlay";
2
- export default Overlay;
3
- export type { OverlayType, PositionObject } from "./Overlay.types";
1
+ import Overlay from "./Overlay";
2
+ export default Overlay
3
+ export type { OverlayType, PositionObject } from "./Overlay.types"
@@ -0,0 +1,155 @@
1
+ import { createPortal } from "react-dom";
2
+ import React, { forwardRef, useEffect, useRef, useState } from "react";
3
+
4
+ import mergeRefs from "../utils/MergeRefs";
5
+
6
+ import { PopoutType, PopoutBodyType, PopoutFooterType, PopoutHeaderType, PopoutTextType, PopoutTitleType } from "./Popout.types";
7
+ /*
8
+ export const useEventListener = (eventType: keyof HTMLElementEventMap, callback: EventListenerOrEventListenerObject, options: boolean | AddEventListenerOptions | undefined, customOptions: {element: HTMLElement}) => {
9
+ const element = customOptions ? customOptions.element : document.body
10
+ useEffect(() => {
11
+ if(element) {
12
+ element.addEventListener(eventType, callback, options)
13
+ return function cleanup() {
14
+ element.removeEventListener(eventType, callback, options)
15
+ }
16
+ }
17
+ }, [callback, element])
18
+ }
19
+ */
20
+
21
+ const Popout = forwardRef<HTMLDialogElement, PopoutType>(({children, initialPosition={top:0, left:0}, id, resize=false, move=false, className, style, ...restProps}, ref) => {
22
+ const [coordinates, setCoordinates] = useState<{ top?: number, bottom?: number, right?: number, left?: number, offSetTop:number, offSetLeft:number }>({offSetTop:0, offSetLeft:0, ...initialPosition})
23
+ const resizeComputed = resize ? "true":"false"
24
+ const moveComputed = move ? "true":"false"
25
+
26
+ const passedRef = useRef(ref)
27
+ const popupRef = useRef<HTMLDialogElement>(null)
28
+ const [ isMouseDown, setIsMouseDown ] = useState<boolean>(false)
29
+ const isMouseDownRef = useRef(isMouseDown)
30
+ useEffect(() => {
31
+ isMouseDownRef.current = isMouseDown
32
+ }, [isMouseDown])
33
+
34
+ const onMouseDown = (event: React.PointerEvent<HTMLDialogElement>) => {
35
+ const eventTarget = event.target as HTMLElement
36
+ if(move && eventTarget.className.includes("sg-popout-title") || eventTarget.className.includes("sg-popout-header")) {
37
+ const { top, left} = popupRef.current!.getBoundingClientRect();
38
+ setCoordinates(prev => ({
39
+ ...prev,
40
+ offSetTop:event.clientY - top,
41
+ offSetLeft:event.clientX - left
42
+ }))
43
+ popupRef.current!.style.setProperty("user-select", "none")
44
+ popupRef.current!.setPointerCapture(event.pointerId)//event.pointerId)//"moveable-popup-"+id);
45
+ setIsMouseDown(true)
46
+ }
47
+ }
48
+ const onMouseUp = () => {
49
+ if(move) {
50
+ popupRef.current!.style.removeProperty("user-select")
51
+ setIsMouseDown(false)
52
+ }
53
+ }
54
+ const onMouseMove = (event: React.PointerEvent<HTMLDialogElement>) => {
55
+ if( move && isMouseDownRef.current && popupRef.current ) {
56
+ const isTopOver = event.clientY - coordinates.offSetTop < 0
57
+ const isBottomOver = window.innerHeight - (event.clientY - coordinates.offSetTop + popupRef.current.offsetHeight) < 0
58
+ const isLeftOver = event.clientX - coordinates.offSetLeft < 0
59
+ const isRightOver = window.innerWidth - (event.clientX - coordinates.offSetLeft + popupRef.current.offsetWidth) < 0
60
+
61
+ let topCoordinate = isTopOver ? 0 : event.clientY - coordinates.offSetTop
62
+ topCoordinate = isBottomOver ? window.innerHeight - popupRef.current.offsetHeight : topCoordinate
63
+
64
+ let leftCoordinate = isLeftOver ? 0 : event.clientX - coordinates.offSetLeft
65
+ leftCoordinate = isRightOver ? window.innerWidth - popupRef.current.offsetWidth : leftCoordinate
66
+
67
+ //console.log(event.clientX - coordinates.offSetLeft, event.clientY - coordinates.offSetTop)
68
+ setCoordinates(prev => ({
69
+ ...prev,
70
+ top:topCoordinate,
71
+ left:leftCoordinate
72
+ }))
73
+ }
74
+ }
75
+
76
+ useEffect(() => {
77
+ document.body.addEventListener("pointerup", () => onMouseUp(), true)
78
+ return function cleanup() {
79
+ document.body.removeEventListener("pointerup", () => onMouseUp(), true)
80
+ }
81
+ }, [])
82
+ return (
83
+ createPortal(
84
+ <dialog data-resize={resizeComputed} data-move={moveComputed} data-passedref={passedRef}
85
+ ref={mergeRefs([ref,popupRef])} id={id} className={`sg-moveable-popout${className ? " "+className : ""}`}
86
+ style={{...style, top:coordinates.top, left:coordinates.left, bottom:coordinates.bottom, right:coordinates.right}}
87
+ onPointerDown={onMouseDown} onPointerMove={(event) => onMouseMove(event)} {...restProps}
88
+ >
89
+ {children}
90
+ </dialog>
91
+ , document.body
92
+ )
93
+ )
94
+ })
95
+ Popout.displayName = "Popout"
96
+
97
+ const Header = forwardRef<HTMLDivElement | HTMLSpanElement | HTMLHeadingElement, PopoutHeaderType>(
98
+ ({ children, className, as = "div", ...restProps}, ref) =>
99
+ {
100
+ let validAs = ["div", "span", "h1", "h2", "h3", "h4", "h5", "h6"]
101
+ let Component = validAs.find(valid => valid === as) ? as : "div"
102
+ return (
103
+ <Component ref={ref} className={`sg-popout-header ${className}`} {...restProps}>
104
+ {children}
105
+ </Component>
106
+ )
107
+ })
108
+ Header.displayName = "PopoutHeader"
109
+
110
+ const Title = forwardRef<HTMLHeadingElement, PopoutTitleType>( ({as="h4", className, children, ...restProps}, ref) => {
111
+ let validAs = ["h1", "h2", "h3", "h4", "h5", "h6"]
112
+ let Component = validAs.find(valid => valid === as) ? as : "h5"
113
+ return (
114
+ <Component ref={ref} className={`sg-popout-title ${className}`} {...restProps}>
115
+ {children}
116
+ </Component>
117
+ )
118
+ })
119
+ Title.displayName = "PopoutTitle"
120
+
121
+ const Body = forwardRef<HTMLDivElement, PopoutBodyType>( ({children, className, ...restProps}, ref) => {
122
+ return (
123
+ <div ref={ref} className={`sg-popout-body ${className}`} {...restProps}>
124
+ {children}
125
+ </div>
126
+ )
127
+ })
128
+ Body.displayName = "PopoutBody"
129
+
130
+ const Text = forwardRef<HTMLParagraphElement, PopoutTextType>( ({children, className, ...restProps}, ref) => {
131
+ return (
132
+ <p ref={ref} className={`sg-popout-text ${className}`} {...restProps}>
133
+ {children}
134
+ </p>
135
+ )
136
+ })
137
+ Text.displayName = "PopoutText"
138
+
139
+ const Footer = forwardRef<HTMLDivElement, PopoutFooterType>( ({children, className, ...restProps}, ref) => {
140
+ return (
141
+ <div ref={ref} className={`sg-popout-footer ${className}`} {...restProps}>
142
+ {children}
143
+ </div>
144
+ )
145
+ })
146
+ Footer.displayName = "PopoutFooter"
147
+
148
+ export default Object.assign(Popout, {
149
+ Header: Header,
150
+ Title: Title,
151
+ Body: Body,
152
+ Text: Text,
153
+ Footer: Footer
154
+ })
155
+
@@ -0,0 +1,42 @@
1
+ import { ReactNode } from "react"
2
+ import { BaseDialogType, BaseDivType, BaseHeadingType, BaseParagraphType, BaseSpanType } from "../utils/BaseTypes"
3
+
4
+ export type PopoutType = {
5
+ children: ReactNode,
6
+ initialPosition?: {
7
+ top?: number,
8
+ bottom?: number,
9
+ right?: number,
10
+ left?: number
11
+ },
12
+ id?: string,
13
+ resize?: boolean,
14
+ move?: boolean,
15
+ } & BaseDialogType
16
+
17
+ export type PopoutHeaderType = {
18
+ children: ReactNode,
19
+ className?: string,
20
+ as?: React.ElementType
21
+ } & (BaseDivType | BaseHeadingType | BaseSpanType)
22
+
23
+ export type PopoutTitleType = {
24
+ children: ReactNode,
25
+ className?: string,
26
+ as?: React.ElementType
27
+ } & BaseHeadingType
28
+
29
+ export type PopoutBodyType = {
30
+ children: ReactNode,
31
+ className?: string,
32
+ } & BaseDivType
33
+
34
+ export type PopoutTextType = {
35
+ children: ReactNode,
36
+ className?: string,
37
+ } & BaseParagraphType
38
+
39
+ export type PopoutFooterType = {
40
+ children: ReactNode,
41
+ className?: string,
42
+ } & BaseDivType
@@ -0,0 +1,3 @@
1
+ import Popout from "./Popout"
2
+ export default Popout
3
+ export type {PopoutBodyType, PopoutFooterType, PopoutHeaderType, PopoutTextType, PopoutTitleType, PopoutType} from "./Popout.types"
@@ -0,0 +1,15 @@
1
+ import React, { forwardRef } from "react";
2
+
3
+ import { SpinnerType } from "./Spinner.types";
4
+
5
+ const Spinner = forwardRef<HTMLDivElement, SpinnerType>( ({size="1em", color="white", label, className, controlId, ...restProps}, ref) => {
6
+ return (
7
+ <>
8
+ <div aria-labelledby={controlId} role="status" ref={ref} className={`sg-spinner${className ? " "+className : ""}`} style={{width:size, height:size, borderColor:color}} {...restProps}></div>
9
+ <label id={controlId} className="sg-visually-hidden">{label}</label>
10
+ </>
11
+ )
12
+ })
13
+ Spinner.displayName = "Spinner"
14
+
15
+ export default Spinner
@@ -0,0 +1,7 @@
1
+ export type SpinnerType = {
2
+ label: string,
3
+ size?: string,
4
+ color?: string,
5
+ className?: string,
6
+ controlId?: string,
7
+ }
@@ -0,0 +1,3 @@
1
+ import Spinner from "./Spinner"
2
+ export default Spinner
3
+ export type { SpinnerType } from "./Spinner.types"
@@ -0,0 +1,16 @@
1
+ import React, { forwardRef } from "react";
2
+
3
+ import { TableType } from "./Table.types";
4
+
5
+
6
+ const Table = forwardRef<HTMLTableElement, TableType>( ({children, size="lg", className, ...restProps}, ref) => {
7
+ let classesComputed = `sg-table${className ? " "+className:""}${size === "sm" ? " "+"sg-table-sm":""}`
8
+ return (
9
+ <table ref={ref} className={classesComputed} {...restProps}>
10
+ {children}
11
+ </table>
12
+ )
13
+ })
14
+ Table.displayName = "Table"
15
+
16
+ export default Table
@@ -0,0 +1,9 @@
1
+ import { ReactNode } from "react";
2
+
3
+ import { BaseTableType } from "../utils/BaseTypes";
4
+
5
+ export type TableType = {
6
+ children: ReactNode,
7
+ size?: string,
8
+ className?: string,
9
+ } & BaseTableType
@@ -0,0 +1,3 @@
1
+ import Table from "./Table"
2
+ export default Table
3
+ export type { TableType } from "./Table.types"