@react-ui-org/react-ui 0.52.1 → 0.54.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (261) hide show
  1. package/README.md +10 -7
  2. package/dist/react-ui.css +5 -3
  3. package/dist/react-ui.development.css +11302 -0
  4. package/dist/react-ui.development.js +1588 -0
  5. package/dist/react-ui.js +1 -1
  6. package/package.json +66 -77
  7. package/src/{lib/components → components}/Alert/Alert.jsx +1 -1
  8. package/src/{lib/components/Alert/README.mdx → components/Alert/README.md} +84 -100
  9. package/src/{lib/components → components}/Badge/Badge.jsx +1 -1
  10. package/src/{lib/components → components}/Badge/Badge.scss +1 -1
  11. package/src/components/Badge/README.md +103 -0
  12. package/src/{lib/components → components}/Button/Button.jsx +1 -1
  13. package/src/components/Button/README.md +580 -0
  14. package/src/{lib/components → components}/ButtonGroup/ButtonGroup.jsx +11 -9
  15. package/src/{lib/components/ButtonGroup/README.mdx → components/ButtonGroup/README.md} +128 -134
  16. package/src/{lib/components → components}/Card/Card.jsx +1 -1
  17. package/src/components/Card/README.md +314 -0
  18. package/src/{lib/components/CheckboxField/README.mdx → components/CheckboxField/README.md} +96 -108
  19. package/src/{lib/components/FileInputField/README.mdx → components/FileInputField/README.md} +83 -95
  20. package/src/{lib/components → components}/FormLayout/FormLayout.jsx +4 -4
  21. package/src/components/FormLayout/README.md +462 -0
  22. package/src/{lib/components → components}/Grid/Grid.jsx +2 -2
  23. package/src/components/Grid/README.md +281 -0
  24. package/src/{lib/components → components}/InputGroup/InputGroup.jsx +28 -19
  25. package/src/{lib/components → components}/InputGroup/InputGroup.scss +4 -5
  26. package/src/{lib/components/InputGroup/README.mdx → components/InputGroup/README.md} +162 -165
  27. package/src/{lib/components → components}/Modal/Modal.jsx +6 -6
  28. package/src/components/Modal/README.md +1090 -0
  29. package/src/components/Modal/_hooks/useModalScrollPrevention.js +37 -0
  30. package/src/{lib/components/Paper/README.mdx → components/Paper/README.md} +18 -30
  31. package/src/{lib/components/Popover/README.mdx → components/Popover/README.md} +102 -132
  32. package/src/{lib/components/Radio/README.mdx → components/Radio/README.md} +122 -134
  33. package/src/{lib/components → components}/Radio/Radio.jsx +11 -12
  34. package/src/{lib/components → components}/Radio/Radio.scss +0 -5
  35. package/src/components/ScrollView/README.md +503 -0
  36. package/src/{lib/components → components}/ScrollView/ScrollView.jsx +12 -3
  37. package/src/components/SelectField/README.md +681 -0
  38. package/src/components/Table/README.md +259 -0
  39. package/src/{lib/components → components}/Table/Table.jsx +4 -1
  40. package/src/{lib/components → components}/Table/_components/TableHeaderCell/TableHeaderCell.jsx +1 -1
  41. package/src/{lib/components/Tabs/README.mdx → components/Tabs/README.md} +117 -134
  42. package/src/{lib/components → components}/Tabs/TabsItem.jsx +3 -3
  43. package/src/components/Text/README.md +220 -0
  44. package/src/components/TextArea/README.md +359 -0
  45. package/src/{lib/components/TextField/README.mdx → components/TextField/README.md} +336 -342
  46. package/src/{lib/components/TextLink/README.mdx → components/TextLink/README.md} +19 -31
  47. package/src/{lib/components/Toggle/README.mdx → components/Toggle/README.md} +98 -110
  48. package/src/components/Toolbar/README.md +359 -0
  49. package/src/{lib/components → components}/Toolbar/_helpers/getAlignClassName.js +12 -4
  50. package/src/components/_helpers/getRootPriorityClassName.js +15 -0
  51. package/src/{lib/index.js → index.js} +6 -0
  52. package/src/{lib/provider → provider}/RUIProvider.jsx +17 -11
  53. package/src/{lib/styles → styles}/tools/_caret.scss +1 -1
  54. package/src/{lib/styles → styles}/tools/form-fields/_box-field-elements.scss +1 -1
  55. package/src/{lib/styles → styles}/tools/form-fields/_inline-field-elements.scss +2 -2
  56. package/src/{lib/theme.scss → theme.scss} +4 -3
  57. package/CONTRIBUTING.md +0 -137
  58. package/dist/lib.development.js +0 -3179
  59. package/dist/lib.js +0 -1
  60. package/public/racom.svg +0 -11
  61. package/src/lib/components/Badge/README.mdx +0 -126
  62. package/src/lib/components/Button/README.mdx +0 -581
  63. package/src/lib/components/Card/README.mdx +0 -326
  64. package/src/lib/components/FormLayout/README.mdx +0 -501
  65. package/src/lib/components/Grid/README.mdx +0 -299
  66. package/src/lib/components/Modal/README.mdx +0 -1360
  67. package/src/lib/components/Modal/_hooks/useModalScrollPrevention.js +0 -35
  68. package/src/lib/components/ScrollView/README.mdx +0 -521
  69. package/src/lib/components/SelectField/README.mdx +0 -693
  70. package/src/lib/components/Table/README.mdx +0 -275
  71. package/src/lib/components/Text/README.mdx +0 -241
  72. package/src/lib/components/TextArea/README.mdx +0 -366
  73. package/src/lib/components/Toolbar/README.mdx +0 -386
  74. package/src/{lib/components → components}/Alert/Alert.scss +0 -0
  75. package/src/{lib/components → components}/Alert/_settings.scss +0 -0
  76. package/src/{lib/components → components}/Alert/_theme.scss +0 -0
  77. package/src/{lib/components → components}/Alert/_tools.scss +0 -0
  78. package/src/{lib/components → components}/Alert/index.js +0 -0
  79. package/src/{lib/components → components}/Badge/index.js +0 -0
  80. package/src/{lib/components → components}/Button/Button.scss +0 -0
  81. package/src/{lib/components → components}/Button/_base.scss +0 -0
  82. package/src/{lib/components → components}/Button/_priorities.scss +0 -0
  83. package/src/{lib/components → components}/Button/_settings.scss +0 -0
  84. package/src/{lib/components → components}/Button/_theme.scss +0 -0
  85. package/src/{lib/components → components}/Button/_tools.scss +0 -0
  86. package/src/{lib/components → components}/Button/helpers/getRootLabelVisibilityClassName.js +0 -0
  87. package/src/{lib/components/_helpers → components/Button/helpers}/getRootPriorityClassName.js +0 -0
  88. package/src/{lib/components → components}/Button/index.js +0 -0
  89. package/src/{lib/components → components}/ButtonGroup/ButtonGroup.scss +0 -0
  90. package/src/{lib/components → components}/ButtonGroup/ButtonGroupContext.js +0 -0
  91. package/src/{lib/components → components}/ButtonGroup/_theme.scss +0 -0
  92. package/src/{lib/components → components}/ButtonGroup/index.js +0 -0
  93. package/src/{lib/components → components}/Card/Card.scss +0 -0
  94. package/src/{lib/components → components}/Card/CardBody.jsx +0 -0
  95. package/src/{lib/components → components}/Card/CardFooter.jsx +0 -0
  96. package/src/{lib/components → components}/Card/_theme.scss +0 -0
  97. package/src/{lib/components → components}/Card/_tools.scss +0 -0
  98. package/src/{lib/components → components}/Card/index.js +0 -0
  99. package/src/{lib/components → components}/CheckboxField/CheckboxField.jsx +0 -0
  100. package/src/{lib/components → components}/CheckboxField/CheckboxField.scss +0 -0
  101. package/src/{lib/components → components}/CheckboxField/index.js +0 -0
  102. package/src/{lib/components → components}/FileInputField/FileInputField.jsx +0 -0
  103. package/src/{lib/components → components}/FileInputField/FileInputField.scss +0 -0
  104. package/src/{lib/components → components}/FileInputField/index.js +0 -0
  105. package/src/{lib/components → components}/FormLayout/FormLayout.scss +0 -0
  106. package/src/{lib/components → components}/FormLayout/FormLayoutContext.js +0 -0
  107. package/src/{lib/components → components}/FormLayout/FormLayoutCustomField.jsx +4 -4
  108. package/src/{lib/components → components}/FormLayout/FormLayoutCustomField.scss +0 -0
  109. package/src/{lib/components → components}/FormLayout/_theme.scss +0 -0
  110. package/src/{lib/components → components}/FormLayout/index.js +0 -0
  111. package/src/{lib/components → components}/Grid/Grid.scss +0 -0
  112. package/src/{lib/components → components}/Grid/GridSpan.jsx +0 -0
  113. package/src/{lib/components → components}/Grid/_helpers/generateResponsiveCustomProperties.js +0 -0
  114. package/src/{lib/components → components}/Grid/_settings.scss +0 -0
  115. package/src/{lib/components → components}/Grid/_tools.scss +0 -0
  116. package/src/{lib/components → components}/Grid/index.js +0 -0
  117. package/src/{lib/components → components}/InputGroup/InputGroupContext.js +0 -0
  118. package/src/{lib/components → components}/InputGroup/_theme.scss +0 -0
  119. package/src/{lib/components → components}/InputGroup/index.js +0 -0
  120. package/src/{lib/components → components}/Modal/Modal.scss +0 -0
  121. package/src/{lib/components → components}/Modal/ModalBody.jsx +0 -0
  122. package/src/{lib/components → components}/Modal/ModalBody.scss +0 -0
  123. package/src/{lib/components → components}/Modal/ModalCloseButton.jsx +1 -1
  124. package/src/{lib/components → components}/Modal/ModalCloseButton.scss +0 -0
  125. package/src/{lib/components → components}/Modal/ModalContent.jsx +0 -0
  126. package/src/{lib/components → components}/Modal/ModalContent.scss +0 -0
  127. package/src/{lib/components → components}/Modal/ModalFooter.jsx +0 -0
  128. package/src/{lib/components → components}/Modal/ModalFooter.scss +0 -0
  129. package/src/{lib/components → components}/Modal/ModalHeader.jsx +0 -0
  130. package/src/{lib/components → components}/Modal/ModalHeader.scss +0 -0
  131. package/src/{lib/components → components}/Modal/ModalTitle.jsx +0 -0
  132. package/src/{lib/components → components}/Modal/ModalTitle.scss +0 -0
  133. package/src/{lib/components → components}/Modal/_helpers/getJustifyClassName.js +0 -0
  134. package/src/{lib/components → components}/Modal/_helpers/getPositionClassName.js +0 -0
  135. package/src/{lib/components → components}/Modal/_helpers/getScrollingClassName.js +0 -0
  136. package/src/{lib/components → components}/Modal/_helpers/getSizeClassName.js +0 -0
  137. package/src/{lib/components → components}/Modal/_hooks/useModalFocus.js +0 -0
  138. package/src/{lib/components → components}/Modal/_settings.scss +0 -0
  139. package/src/{lib/components → components}/Modal/_theme.scss +0 -0
  140. package/src/{lib/components → components}/Modal/index.js +0 -0
  141. package/src/{lib/components → components}/Paper/Paper.jsx +0 -0
  142. package/src/{lib/components → components}/Paper/Paper.scss +0 -0
  143. package/src/{lib/components → components}/Paper/_theme.scss +0 -0
  144. package/src/{lib/components → components}/Paper/index.js +0 -0
  145. package/src/{lib/components → components}/Popover/Popover.jsx +0 -0
  146. package/src/{lib/components → components}/Popover/Popover.scss +0 -0
  147. package/src/{lib/components → components}/Popover/PopoverWrapper.jsx +0 -0
  148. package/src/{lib/components → components}/Popover/PopoverWrapper.scss +0 -0
  149. package/src/{lib/components → components}/Popover/_helpers/getRootAlignmentClassName.js +0 -0
  150. package/src/{lib/components → components}/Popover/_helpers/getRootSideClassName.js +0 -0
  151. package/src/{lib/components → components}/Popover/_theme.scss +0 -0
  152. package/src/{lib/components → components}/Popover/index.js +0 -0
  153. package/src/{lib/components → components}/Radio/index.js +0 -0
  154. package/src/{lib/components → components}/ScrollView/ScrollView.scss +0 -0
  155. package/src/{lib/components → components}/ScrollView/_helpers/getElementsPositionDifference.js +0 -0
  156. package/src/{lib/components → components}/ScrollView/_hooks/useLoadResizeHook.js +0 -0
  157. package/src/{lib/components → components}/ScrollView/_hooks/useScrollPositionHook.js +0 -0
  158. package/src/{lib/components → components}/ScrollView/index.js +0 -0
  159. package/src/{lib/components → components}/SelectField/SelectField.jsx +0 -0
  160. package/src/{lib/components → components}/SelectField/SelectField.scss +0 -0
  161. package/src/{lib/components → components}/SelectField/_components/Option/Option.jsx +0 -0
  162. package/src/{lib/components → components}/SelectField/_components/Option/index.js +0 -0
  163. package/src/{lib/components → components}/SelectField/index.js +0 -0
  164. package/src/{lib/components → components}/Table/Table.scss +0 -0
  165. package/src/{lib/components → components}/Table/_components/TableBodyCell/TableBodyCell.jsx +0 -0
  166. package/src/{lib/components → components}/Table/_components/TableBodyCell/index.js +0 -0
  167. package/src/{lib/components → components}/Table/_components/TableCell.scss +0 -0
  168. package/src/{lib/components → components}/Table/_components/TableHeaderCell/index.js +0 -0
  169. package/src/{lib/components → components}/Table/_settings.scss +0 -0
  170. package/src/{lib/components → components}/Table/index.js +0 -0
  171. package/src/{lib/components → components}/Tabs/Tabs.jsx +0 -0
  172. package/src/{lib/components → components}/Tabs/Tabs.scss +0 -0
  173. package/src/{lib/components → components}/Tabs/TabsItem.scss +0 -0
  174. package/src/{lib/components → components}/Tabs/_theme.scss +0 -0
  175. package/src/{lib/components → components}/Tabs/index.js +0 -0
  176. package/src/{lib/components → components}/Text/Text.jsx +0 -0
  177. package/src/{lib/components → components}/Text/Text.scss +0 -0
  178. package/src/{lib/components → components}/Text/_helpers/getRootClampClassName.js +0 -0
  179. package/src/{lib/components → components}/Text/_helpers/getRootHyphensClassName.js +0 -0
  180. package/src/{lib/components → components}/Text/_helpers/getRootWordWrappingClassName.js +0 -0
  181. package/src/{lib/components → components}/Text/index.js +0 -0
  182. package/src/{lib/components → components}/TextArea/TextArea.jsx +0 -0
  183. package/src/{lib/components → components}/TextArea/TextArea.scss +0 -0
  184. package/src/{lib/components → components}/TextArea/index.js +0 -0
  185. package/src/{lib/components → components}/TextField/TextField.jsx +0 -0
  186. package/src/{lib/components → components}/TextField/TextField.scss +0 -0
  187. package/src/{lib/components → components}/TextField/index.js +0 -0
  188. package/src/{lib/components → components}/TextLink/TextLink.jsx +1 -1
  189. /package/src/{lib/components → components}/TextLink/TextLink.scss +0 -0
  190. /package/src/{lib/components → components}/TextLink/_theme.scss +0 -0
  191. /package/src/{lib/components → components}/TextLink/index.js +0 -0
  192. /package/src/{lib/components → components}/Toggle/Toggle.jsx +0 -0
  193. /package/src/{lib/components → components}/Toggle/Toggle.scss +0 -0
  194. /package/src/{lib/components → components}/Toggle/index.js +0 -0
  195. /package/src/{lib/components → components}/Toolbar/Toolbar.jsx +0 -0
  196. /package/src/{lib/components → components}/Toolbar/Toolbar.scss +0 -0
  197. /package/src/{lib/components → components}/Toolbar/ToolbarGroup.jsx +0 -0
  198. /package/src/{lib/components → components}/Toolbar/ToolbarItem.jsx +0 -0
  199. /package/src/{lib/components → components}/Toolbar/_helpers/getJustifyClassName.js +0 -0
  200. /package/src/{lib/components → components}/Toolbar/_theme.scss +0 -0
  201. /package/src/{lib/components → components}/Toolbar/index.js +0 -0
  202. /package/src/{lib/components → components}/_helpers/getRootColorClassName.js +0 -0
  203. /package/src/{lib/components → components}/_helpers/getRootSizeClassName.js +0 -0
  204. /package/src/{lib/components → components}/_helpers/getRootValidationStateClassName.js +0 -0
  205. /package/src/{lib/components → components}/_helpers/isChildrenEmpty.js +0 -0
  206. /package/src/{lib/components → components}/_helpers/resolveContextOrProp.js +0 -0
  207. /package/src/{lib/components → components}/_helpers/transferProps.js +0 -0
  208. /package/src/{lib/foundation.scss → foundation.scss} +0 -0
  209. /package/src/{lib/helpers.scss → helpers.scss} +0 -0
  210. /package/src/{lib/provider → provider}/RUIContext.jsx +0 -0
  211. /package/src/{lib/provider → provider}/index.js +0 -0
  212. /package/src/{lib/provider → provider}/withGlobalProps.jsx +0 -0
  213. /package/src/{lib/styles → styles}/_utilities.scss +0 -0
  214. /package/src/{lib/styles → styles}/elements/_code.scss +0 -0
  215. /package/src/{lib/styles → styles}/elements/_links.scss +0 -0
  216. /package/src/{lib/styles → styles}/elements/_lists.scss +0 -0
  217. /package/src/{lib/styles → styles}/elements/_page.scss +0 -0
  218. /package/src/{lib/styles → styles}/elements/_rulers.scss +0 -0
  219. /package/src/{lib/styles → styles}/elements/_small.scss +0 -0
  220. /package/src/{lib/styles → styles}/generic/_box-sizing.scss +0 -0
  221. /package/src/{lib/styles → styles}/generic/_focus.scss +0 -0
  222. /package/src/{lib/styles → styles}/generic/_forms.scss +0 -0
  223. /package/src/{lib/styles → styles}/generic/_reset.scss +0 -0
  224. /package/src/{lib/styles → styles}/generic/_shared.scss +0 -0
  225. /package/src/{lib/styles → styles}/helpers/_animation.scss +0 -0
  226. /package/src/{lib/styles → styles}/settings/_animations.scss +0 -0
  227. /package/src/{lib/styles → styles}/settings/_breakpoints.scss +0 -0
  228. /package/src/{lib/styles → styles}/settings/_escaped-characters.scss +0 -0
  229. /package/src/{lib/styles → styles}/settings/_form-fields.scss +0 -0
  230. /package/src/{lib/styles → styles}/settings/_forms.scss +0 -0
  231. /package/src/{lib/styles → styles}/settings/_utilities.scss +0 -0
  232. /package/src/{lib/styles → styles}/settings/_z-indexes.scss +0 -0
  233. /package/src/{lib/styles → styles}/theme/_accessibility.scss +0 -0
  234. /package/src/{lib/styles → styles}/theme/_borders.scss +0 -0
  235. /package/src/{lib/styles → styles}/theme/_code.scss +0 -0
  236. /package/src/{lib/styles → styles}/theme/_form-fields.scss +0 -0
  237. /package/src/{lib/styles → styles}/theme/_links.scss +0 -0
  238. /package/src/{lib/styles → styles}/theme/_lists.scss +0 -0
  239. /package/src/{lib/styles → styles}/theme/_page.scss +0 -0
  240. /package/src/{lib/styles → styles}/theme/_spacing.scss +0 -0
  241. /package/src/{lib/styles → styles}/theme/_typography.scss +0 -0
  242. /package/src/{lib/styles → styles}/theme-constants/_breakpoints.scss +0 -0
  243. /package/src/{lib/styles → styles}/theme-constants/_colors.scss +0 -0
  244. /package/src/{lib/styles → styles}/theme-constants/_svg.scss +0 -0
  245. /package/src/{lib/styles → styles}/tools/_accessibility.scss +0 -0
  246. /package/src/{lib/styles → styles}/tools/_breakpoint.scss +0 -0
  247. /package/src/{lib/styles → styles}/tools/_colors.scss +0 -0
  248. /package/src/{lib/styles → styles}/tools/_reset.scss +0 -0
  249. /package/src/{lib/styles → styles}/tools/_scrollbar.scss +0 -0
  250. /package/src/{lib/styles → styles}/tools/_spacing.scss +0 -0
  251. /package/src/{lib/styles → styles}/tools/_string.scss +0 -0
  252. /package/src/{lib/styles → styles}/tools/_svg.scss +0 -0
  253. /package/src/{lib/styles → styles}/tools/_transition.scss +0 -0
  254. /package/src/{lib/styles → styles}/tools/_utilities.scss +0 -0
  255. /package/src/{lib/styles → styles}/tools/form-fields/_box-field-layout.scss +0 -0
  256. /package/src/{lib/styles → styles}/tools/form-fields/_box-field-sizes.scss +0 -0
  257. /package/src/{lib/styles → styles}/tools/form-fields/_foundation.scss +0 -0
  258. /package/src/{lib/styles → styles}/tools/form-fields/_inline-field-layout.scss +0 -0
  259. /package/src/{lib/styles → styles}/tools/form-fields/_variants.scss +0 -0
  260. /package/src/{lib/translations → translations}/en.js +0 -0
  261. /package/src/{lib/utils → utils}/classNames.js +0 -0
@@ -1,35 +0,0 @@
1
- import { useLayoutEffect } from 'react';
2
-
3
- export const useModalScrollPrevention = (preventScrollUnderneath) => {
4
- useLayoutEffect(
5
- () => {
6
- if (preventScrollUnderneath === 'off') {
7
- return () => {};
8
- }
9
-
10
- if (preventScrollUnderneath === 'default') {
11
- const scrollbarWidth = Math.abs(window.innerWidth - window.document.documentElement.clientWidth);
12
- const prevOverflow = window.document.body.style.overflow;
13
- const prevPaddingRight = window.document.body.style.paddingRight;
14
-
15
- window.document.body.style.overflow = 'hidden';
16
-
17
- if (Number.isNaN(parseInt(prevPaddingRight, 10))) {
18
- window.document.body.style.paddingRight = `${scrollbarWidth}px`;
19
- } else {
20
- window.document.body.style.paddingRight = `calc(${prevPaddingRight} + ${scrollbarWidth}px)`;
21
- }
22
-
23
- return () => {
24
- window.document.body.style.overflow = prevOverflow;
25
- window.document.body.style.paddingRight = prevPaddingRight;
26
- };
27
- }
28
-
29
- preventScrollUnderneath?.start();
30
-
31
- return preventScrollUnderneath?.reset;
32
- },
33
- [preventScrollUnderneath],
34
- );
35
- };
@@ -1,521 +0,0 @@
1
- ---
2
- name: ScrollView
3
- menu: 'Miscellaneous'
4
- route: /components/scroll-view
5
- ---
6
-
7
- # ScrollView
8
-
9
- ScrollView makes long content scrollable.
10
-
11
- 👉 Please note that HTML is rendered even when no children are provided.
12
- This is needed to allow the auto-scroll feature to work.
13
-
14
- import {
15
- Playground,
16
- Props,
17
- } from 'docz'
18
- import { Placeholder } from '../../../docs/_components/Placeholder/Placeholder'
19
- import {
20
- Button,
21
- Radio,
22
- Toolbar,
23
- ToolbarItem,
24
- ScrollView,
25
- } from '../..'
26
-
27
- ## Basic Usage
28
-
29
- To implement the ScrollView component, you need to import it first:
30
-
31
- ```js
32
- import { ScrollView } from '@react-ui-org/react-ui';
33
- ```
34
-
35
- And use it:
36
-
37
- <Playground>
38
- <Placeholder height="200px">
39
- <ScrollView>
40
- <div>
41
- Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo
42
- ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis
43
- dis parturient montes, nascetur ridiculus mus. Donec quam felis,
44
- ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa
45
- quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget,
46
- arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo.
47
- Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras
48
- dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend
49
- tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac,
50
- enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus.
51
- Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean
52
- imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper
53
- ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus
54
- eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing
55
- sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar,
56
- hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec
57
- vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit
58
- amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris
59
- sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget
60
- bibendum sodales, augue velit cursus nunc.Aenean massa. Cum sociis
61
- natoque penatibus et magnis dis parturient montes, nascetur ridiculus
62
- mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis,
63
- sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel,
64
- aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet
65
- a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium.
66
- Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean
67
- vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat
68
- vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis,
69
- feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet.
70
- Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue.
71
- Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus.
72
- Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper
73
- libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit
74
- vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante
75
- tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus.
76
- Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt.
77
- Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis
78
- magna. Sed consequat, leo eget bibendum sodales, augue velit cursus
79
- nunc.
80
- </div>
81
- </ScrollView>
82
- </Placeholder>
83
- </Playground>
84
-
85
- See [API](#api) for all available options.
86
-
87
- ## General Guidelines
88
-
89
- - ScrollView takes up all **available horizontal space and expands vertically**
90
- according to the length of its content. Depending on your layout, you may need
91
- to restrict the height of its parent to activate scrolling.
92
-
93
- - While arrow controls are optional in the vertical mode, you should always
94
- **enable arrows in the horizontal mode when the scrollbar is disabled.**
95
- Because if you don't, users without horizontal-scrolling-enabled devices
96
- (like an old-school mouse) might not be able to access your content.
97
-
98
- - For dynamic content such as chat window or console output, consider using the
99
- **auto-scroll feature**. This will ensure the newest content is always
100
- visible.
101
-
102
- - ScrollView enables **scrolling on all screen sizes.** If you need to make an
103
- area in your app scrollable based on viewport size, please use custom CSS
104
- with media queries instead.
105
-
106
- - ScrollView only supports **scrolling in a single direction at a time.** It
107
- crops content that would possibly overflow in the other direction because
108
- additional scrollbars would be unreachable under scrolling shadows. If you
109
- need your content to be ready for bi-directional scrolling, either consider
110
- using just `overflow: auto` instead of ScrollView, or make your content
111
- scrollable before putting it into ScrollView and make sure its scrollbars
112
- don't collide with scrolling shadows.
113
-
114
- ## Arrows
115
-
116
- You can suppress the system scrollbar and display arrow controls instead.
117
-
118
- <Playground>
119
- <Placeholder height="200px">
120
- <ScrollView arrows scrollbar={false}>
121
- <div>
122
- Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo
123
- ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis
124
- dis parturient montes, nascetur ridiculus mus. Donec quam felis,
125
- ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa
126
- quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget,
127
- arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo.
128
- Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras
129
- dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend
130
- tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac,
131
- enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus.
132
- Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean
133
- imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper
134
- ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus
135
- eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing
136
- sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar,
137
- hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec
138
- vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit
139
- amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris
140
- sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget
141
- bibendum sodales, augue velit cursus nunc.Aenean massa. Cum sociis
142
- natoque penatibus et magnis dis parturient montes, nascetur ridiculus
143
- mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis,
144
- sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel,
145
- aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet
146
- a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium.
147
- Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean
148
- vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat
149
- vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis,
150
- feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet.
151
- Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue.
152
- Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus.
153
- Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper
154
- libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit
155
- vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante
156
- tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus.
157
- Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt.
158
- Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis
159
- magna. Sed consequat, leo eget bibendum sodales, augue velit cursus
160
- nunc.
161
- </div>
162
- </ScrollView>
163
- </Placeholder>
164
- </Playground>
165
-
166
- ## Horizontal Scrolling
167
-
168
- The horizontal mode is useful when you have (or expect to have) a lot of
169
- horizontal content and you need to make sure it remains accessible on all
170
- viewport sizes.
171
-
172
- <Playground>
173
- <ScrollView direction="horizontal" arrows>
174
- <Placeholder>
175
- <div style={{ whiteSpace: 'nowrap' }}>
176
- Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo
177
- ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis
178
- dis parturient montes, nascetur ridiculus mus. Donec quam felis,
179
- ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa
180
- quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget,
181
- arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo.
182
- </div>
183
- </Placeholder>
184
- </ScrollView>
185
- </Playground>
186
-
187
- ## Auto Scrolling
188
-
189
- ScrollView can watch its content for changes and automatically scroll to the
190
- end when the content has changed.
191
-
192
- ⚠️ The auto-scroll functionality requires all children to have the `key`
193
- property defined because it detects changes of these keys.
194
-
195
- <Playground>
196
- {() => {
197
- const generateRandomString = () => {
198
- const texts = [
199
- 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.',
200
- 'Aenean commodo ligula eget dolor. Aenean massa.',
201
- 'Aenean commodo ligula eget dolor. Aenean massa.',
202
- 'Cum sociis natoque penatibus et magnis dis parturient montes.',
203
- 'Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.',
204
- 'Nulla consequat massa quis enim. Donec pede justo, fringilla vel.',
205
- 'In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo.',
206
- ];
207
- let text = '';
208
- const repeatAmount = Math.floor(Math.random() * 9);
209
- for (let i = 0; i < (repeatAmount + 1); i += 1) {
210
- text += texts[Math.floor(Math.random() * Math.floor(texts.length - 1))];
211
- }
212
- return text;
213
- }
214
- const [autoScroll, setAutoScroll] = React.useState('always');
215
- const [direction, setDirection] = React.useState('vertical');
216
- const [scrollViewContent, setScrollViewContent] = React.useState(
217
- generateRandomString(),
218
- );
219
- return (
220
- <div>
221
- <Toolbar>
222
- <ToolbarItem>
223
- <Radio
224
- label="Direction:"
225
- onChange={(e) => setDirection(e.target.value)}
226
- options={[
227
- {
228
- label: 'Vertical',
229
- value: 'vertical',
230
- },
231
- {
232
- label: 'Horizontal',
233
- value: 'horizontal',
234
- },
235
- ]}
236
- value={direction}
237
- />
238
- </ToolbarItem>
239
- <ToolbarItem>
240
- <Radio
241
- label="Autoscroll:"
242
- onChange={(e) => setAutoScroll(e.target.value)}
243
- options={[
244
- {
245
- label: 'Always',
246
- value: 'always',
247
- },
248
- {
249
- label: 'When end is detected',
250
- value: 'detectEnd',
251
- },
252
- ]}
253
- value={autoScroll}
254
- />
255
- </ToolbarItem>
256
- <ToolbarItem>
257
- <Button
258
- label="Add text"
259
- onClick={
260
- () => setScrollViewContent(
261
- `${scrollViewContent} ${generateRandomString()}`,
262
- )
263
- }
264
- />
265
- </ToolbarItem>
266
- </Toolbar>
267
- <Placeholder height={direction === 'vertical' ? '200px' : 'auto'}>
268
- <ScrollView arrows autoScroll={autoScroll} direction={direction}>
269
- <div
270
- key={scrollViewContent.length}
271
- style={{
272
- whiteSpace: (direction === 'horizontal' ? 'nowrap' : 'normal'),
273
- }}
274
- >
275
- {scrollViewContent}
276
- </div>
277
- </ScrollView>
278
- </Placeholder>
279
- </div>
280
- );
281
- }}
282
- </Playground>
283
-
284
- ## Customization
285
-
286
- It's possible to entirely customize the arrow controls, including the scroll
287
- step, and the scrolling shadows.
288
-
289
- ### Custom Arrows
290
-
291
- You can pass any HTML element or even a custom React component to be used as the
292
- arrow control. Furthermore, you can change the scroll step if you need to scroll
293
- by smaller or bigger portions.
294
-
295
- <Playground>
296
- <ScrollView
297
- arrows
298
- arrowsScrollStep={300}
299
- direction="horizontal"
300
- nextArrowElement={(<span class="font-size-3">➡️</span>)}
301
- prevArrowElement={(<span class="font-size-3">⬅️</span>)}
302
- scrollbar={false}
303
- >
304
- <Placeholder>
305
- <div style={{ whiteSpace: 'nowrap' }}>
306
- Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo
307
- ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis
308
- dis parturient montes, nascetur ridiculus mus. Donec quam felis,
309
- ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa
310
- quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget,
311
- arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo.
312
- </div>
313
- </Placeholder>
314
- </ScrollView>
315
- </Playground>
316
-
317
- ### Scrolling Shadows
318
-
319
- You can customize the start and end scrolling shadows using `startShadow*` and
320
- `endShadow*` properties.
321
-
322
- <Playground>
323
- <Placeholder height="200px">
324
- <ScrollView
325
- startShadowBackground={'radial-gradient('
326
- + 'farthest-side at center top, '
327
- + 'rgba(0, 0, 0, 0.15) 0%, '
328
- + 'rgba(0, 0, 0, 0.05) 60%, '
329
- + 'rgba(0, 0, 0, 0.02) 85%, '
330
- + 'rgba(0, 0, 0, 0) 100%'
331
- + ')'
332
- }
333
- startShadowInitialOffset="-5px"
334
- startShadowSize="40px"
335
- endShadowBackground={'radial-gradient('
336
- + 'farthest-side at center bottom, '
337
- + 'rgba(0, 0, 0, 0.15) 0%, '
338
- + 'rgba(0, 0, 0, 0.05) 60%, '
339
- + 'rgba(0, 0, 0, 0.02) 85%, '
340
- + 'rgba(0, 0, 0, 0) 100%'
341
- + ')'
342
- }
343
- endShadowInitialOffset="-5px"
344
- endShadowSize="40px"
345
- >
346
- <div>
347
- Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo
348
- ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis
349
- dis parturient montes, nascetur ridiculus mus. Donec quam felis,
350
- ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa
351
- quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget,
352
- arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo.
353
- Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras
354
- dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend
355
- tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac,
356
- enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus.
357
- Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean
358
- imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper
359
- ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus
360
- eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing
361
- sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar,
362
- hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec
363
- vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit
364
- amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris
365
- sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget
366
- bibendum sodales, augue velit cursus nunc.Aenean massa. Cum sociis
367
- natoque penatibus et magnis dis parturient montes, nascetur ridiculus
368
- mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis,
369
- sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel,
370
- aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet
371
- a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium.
372
- Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean
373
- vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat
374
- vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis,
375
- feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet.
376
- Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue.
377
- Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus.
378
- Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper
379
- libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit
380
- vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante
381
- tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus.
382
- Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt.
383
- Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis
384
- magna. Sed consequat, leo eget bibendum sodales, augue velit cursus
385
- nunc.
386
- </div>
387
- </ScrollView>
388
- </Placeholder>
389
- </Playground>
390
-
391
- #### Linear Gradients
392
-
393
- For easier CSS definition of [linear gradients] for both vertical and horizontal
394
- directions at the same time, there are `--rui-local-start-shadow-direction` and
395
- `--rui-local-end-shadow-direction` custom properties that can be used inside
396
- `startShadowBackground` and `endShadowBackground` definitions. The value of the
397
- custom properties then reacts to the `direction` option:
398
-
399
- | Custom property | Vertical direction | Horizontal direction |
400
- |--------------------------------------|--------------------|----------------------|
401
- | `--rui-local-start-shadow-direction` | `to bottom` | `to right` |
402
- | `--rui-local-end-shadow-direction` | `to top` | `to left` |
403
-
404
- This is useful if you want to create a single definition of linear gradients for
405
- scrolling shadows in both directions via
406
- [global props](/customize/global-props).
407
-
408
- <Playground>
409
- {() => {
410
- const START_SHADOW_BACKGROUND = `linear-gradient(
411
- var(--rui-local-start-shadow-direction),
412
- rgba(0 0 0 / 0.5),
413
- rgba(0 0 0 / 0)
414
- )`;
415
- const END_SHADOW_BACKGROUND = `linear-gradient(
416
- var(--rui-local-end-shadow-direction),
417
- rgba(0 0 0 / 0.5),
418
- rgba(0 0 0 / 0)
419
- )`
420
- const [direction, setDirection] = React.useState('vertical');
421
- return(
422
- <>
423
- <Radio
424
- label="Direction:"
425
- onChange={(e) => setDirection(e.target.value)}
426
- options={[
427
- {
428
- label: 'Vertical',
429
- value: 'vertical',
430
- },
431
- {
432
- label: 'Horizontal',
433
- value: 'horizontal',
434
- },
435
- ]}
436
- value={direction}
437
- />
438
- <Placeholder height="200px">
439
- <ScrollView
440
- direction={direction}
441
- endShadowBackground={END_SHADOW_BACKGROUND}
442
- startShadowBackground={START_SHADOW_BACKGROUND}
443
- >
444
- <div
445
- style={{
446
- width: (direction === 'horizontal' ? '3000px' : 'auto'),
447
- }}
448
- >
449
- Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
450
- commodo ligula eget dolor. Aenean massa. Cum sociis natoque
451
- penatibus et magnis dis parturient montes, nascetur ridiculus mus.
452
- Donec quam felis, ultricies nec, pellentesque eu, pretium quis,
453
- sem. Nulla consequat massa quis enim. Donec pede justo, fringilla
454
- vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut,
455
- imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede
456
- mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum
457
- semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula,
458
- porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem
459
- ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus
460
- viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean
461
- imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper
462
- ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus,
463
- tellus eget condimentum rhoncus, sem quam semper libero, sit amet
464
- adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus
465
- pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt
466
- tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam
467
- quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis
468
- leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis
469
- magna. Sed consequat, leo eget bibendum sodales, augue velit
470
- cursus nunc. Aenean massa. Cum sociis natoque penatibus et magnis
471
- dis parturient montes, nascetur ridiculus mus. Donec quam felis,
472
- ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat
473
- massa quis enim. Donec pede justo, fringilla vel, aliquet nec,
474
- vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a,
475
- venenatis vitae, justo. Nullam dictum felis eu pede mollis
476
- pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper
477
- nisi. Aenean vulputate eleifend tellus. Aenean leo ligula,
478
- porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem
479
- ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus
480
- viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean
481
- imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper
482
- ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus,
483
- tellus eget condimentum rhoncus, sem quam semper libero, sit amet
484
- adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus
485
- pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt
486
- tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam
487
- quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis
488
- leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis
489
- magna. Sed consequat, leo eget bibendum sodales, augue velit
490
- cursus nunc.
491
- </div>
492
- </ScrollView>
493
- </Placeholder>
494
- </>
495
- )}}
496
- </Playground>
497
-
498
- ## Forwarding HTML Attributes
499
-
500
- In addition to the options below in the [component's API](#api) section, you
501
- can specify [React synthetic events] or **any HTML attribute you like.** All
502
- attributes that don't interfere with the API are forwarded to the `<div>` HTML
503
- element. This enables making the component interactive and helps to improve its
504
- accessibility.
505
-
506
- 👉 Refer to the MDN reference for the full list of supported attributes of the
507
- [div] element.
508
-
509
- ## Forwarding ref
510
-
511
- If you provide [ref], it is forwarded to the scrolling viewport native HTML
512
- `<div>` element.
513
-
514
- ## API
515
-
516
- <Props table of={ScrollView} />
517
-
518
- [linear gradients]: https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/linear-gradient
519
- [React synthetic events]: https://reactjs.org/docs/events.html
520
- [div]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes
521
- [ref]: https://reactjs.org/docs/refs-and-the-dom.html