@react-ui-org/react-ui 0.52.0 → 0.53.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (260) hide show
  1. package/CODEOWNERS +23 -0
  2. package/README.md +10 -7
  3. package/dist/react-ui.css +42 -0
  4. package/dist/react-ui.js +1 -0
  5. package/package.json +64 -77
  6. package/src/{lib/components → components}/Alert/Alert.jsx +1 -1
  7. package/src/{lib/components/Alert/README.mdx → components/Alert/README.md} +84 -100
  8. package/src/{lib/components → components}/Badge/Badge.jsx +1 -1
  9. package/src/{lib/components → components}/Badge/Badge.scss +1 -1
  10. package/src/components/Badge/README.md +103 -0
  11. package/src/{lib/components → components}/Button/Button.jsx +1 -1
  12. package/src/components/Button/README.md +580 -0
  13. package/src/{lib/components → components}/ButtonGroup/ButtonGroup.jsx +11 -9
  14. package/src/{lib/components/ButtonGroup/README.mdx → components/ButtonGroup/README.md} +128 -134
  15. package/src/{lib/components → components}/Card/Card.jsx +1 -1
  16. package/src/components/Card/README.md +314 -0
  17. package/src/{lib/components/CheckboxField/README.mdx → components/CheckboxField/README.md} +96 -108
  18. package/src/{lib/components/FileInputField/README.mdx → components/FileInputField/README.md} +83 -95
  19. package/src/{lib/components → components}/FormLayout/FormLayout.jsx +4 -4
  20. package/src/components/FormLayout/README.md +462 -0
  21. package/src/{lib/components → components}/Grid/Grid.jsx +2 -2
  22. package/src/components/Grid/README.md +281 -0
  23. package/src/{lib/components → components}/InputGroup/InputGroup.jsx +20 -19
  24. package/src/{lib/components → components}/InputGroup/InputGroup.scss +1 -6
  25. package/src/{lib/components/InputGroup/README.mdx → components/InputGroup/README.md} +145 -163
  26. package/src/{lib/components → components}/Modal/Modal.jsx +6 -6
  27. package/src/components/Modal/README.md +1090 -0
  28. package/src/components/Modal/_hooks/useModalScrollPrevention.js +37 -0
  29. package/src/{lib/components/Paper/README.mdx → components/Paper/README.md} +18 -30
  30. package/src/{lib/components/Popover/README.mdx → components/Popover/README.md} +102 -132
  31. package/src/{lib/components/Radio/README.mdx → components/Radio/README.md} +122 -134
  32. package/src/{lib/components → components}/Radio/Radio.jsx +11 -12
  33. package/src/{lib/components → components}/Radio/Radio.scss +1 -6
  34. package/src/components/ScrollView/README.md +503 -0
  35. package/src/{lib/components → components}/ScrollView/ScrollView.jsx +12 -3
  36. package/src/components/SelectField/README.md +681 -0
  37. package/src/components/Table/README.md +259 -0
  38. package/src/{lib/components → components}/Table/Table.jsx +4 -1
  39. package/src/{lib/components → components}/Table/_components/TableHeaderCell/TableHeaderCell.jsx +1 -1
  40. package/src/{lib/components/Tabs/README.mdx → components/Tabs/README.md} +117 -134
  41. package/src/{lib/components → components}/Tabs/TabsItem.jsx +3 -3
  42. package/src/components/Text/README.md +220 -0
  43. package/src/components/TextArea/README.md +359 -0
  44. package/src/{lib/components/TextField/README.mdx → components/TextField/README.md} +336 -342
  45. package/src/{lib/components/TextLink/README.mdx → components/TextLink/README.md} +19 -31
  46. package/src/{lib/components/Toggle/README.mdx → components/Toggle/README.md} +98 -110
  47. package/src/components/Toolbar/README.md +359 -0
  48. package/src/{lib/components → components}/Toolbar/_helpers/getAlignClassName.js +12 -4
  49. package/src/components/_helpers/getRootPriorityClassName.js +15 -0
  50. package/src/{lib/index.js → index.js} +6 -0
  51. package/src/{lib/provider → provider}/RUIProvider.jsx +17 -11
  52. package/src/{lib/styles → styles}/tools/_caret.scss +1 -1
  53. package/src/{lib/styles → styles}/tools/form-fields/_box-field-elements.scss +1 -1
  54. package/src/{lib/styles → styles}/tools/form-fields/_box-field-layout.scss +26 -14
  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-sizes.scss +0 -0
  256. /package/src/{lib/styles → styles}/tools/form-fields/_foundation.scss +0 -0
  257. /package/src/{lib/styles → styles}/tools/form-fields/_inline-field-layout.scss +0 -0
  258. /package/src/{lib/styles → styles}/tools/form-fields/_variants.scss +0 -0
  259. /package/src/{lib/translations → translations}/en.js +0 -0
  260. /package/src/{lib/utils → utils}/classNames.js +0 -0
@@ -0,0 +1,681 @@
1
+ # SelectField
2
+
3
+ SelectField allows users to select one option from a set.
4
+
5
+ ## Basic Usage
6
+
7
+ To implement the SelectField component, you need to import it first:
8
+
9
+ ```js
10
+ import { SelectField } from '@react-ui-org/react-ui';
11
+ ```
12
+
13
+ And use it:
14
+
15
+ ```docoff-react-preview
16
+ React.createElement(() => {
17
+ const [fruit, setFruit] = React.useState('apple');
18
+ return (
19
+ <SelectField
20
+ label="Your favourite fruit"
21
+ onChange={(e) => setFruit(e.target.value)}
22
+ options={[
23
+ {
24
+ label: 'Apple',
25
+ value: 'apple',
26
+ },
27
+ {
28
+ label: 'Banana',
29
+ value: 'banana',
30
+ },
31
+ {
32
+ label: 'Grapefruit',
33
+ value: 'grapefruit',
34
+ },
35
+ ]}
36
+ value={fruit}
37
+ />
38
+ );
39
+ });
40
+ ```
41
+
42
+ See [API](#api) for all available options.
43
+
44
+ ## General Guidelines
45
+
46
+ - Use SelectField for **many options**. For sets of just a few options
47
+ (say 3 at maximum) consider using the [Radio](/components/Radio) component.
48
+ This will help keep your UI clean and uncluttered and prevent your users from
49
+ being overwhelmed by too many options.
50
+
51
+ - **Don't use for boolean** (true/false) selection or to toggle things on and
52
+ off. [CheckboxField](/components/CheckboxField) and
53
+ [Toggle](/components/Toggle) are more suitable for such cases.
54
+
55
+ - Use **short and descriptive labels**, ideally nouns rather than seemingly
56
+ polite phrases like _Please select your favourite fruit_. Short labels will
57
+ help your users accomplish their task faster.
58
+
59
+ - Only make the SelectField's label invisible when there is **another visual
60
+ clue** to guide users through filling the input. Using the first option as
61
+ label is not recommended either — it disappears once user makes their choice.
62
+
63
+ - When a short label is not enough, use **help texts to guide users** before
64
+ they enter anything.
65
+
66
+ - Use **clear, calm error messages** when there's a problem with what they
67
+ entered.
68
+
69
+ - In case of a large amount of options, consider **grouping related items
70
+ together** by nesting them.
71
+
72
+ 👉 We use the **native `select`** HTML element to improve user experience on
73
+ mobile devices by using the native select of the platform.
74
+
75
+ ## Design Variants
76
+
77
+ To satisfy the design requirements of your project, all input fields in React UI
78
+ come in two design variants to choose from: outline and filled. Both can be
79
+ further [customized](#theming) with CSS custom properties.
80
+
81
+ ```docoff-react-preview
82
+ React.createElement(() => {
83
+ const [fruit, setFruit] = React.useState('apple');
84
+ const options = [
85
+ {
86
+ label: 'Apple',
87
+ value: 'apple',
88
+ },
89
+ {
90
+ label: 'Banana',
91
+ value: 'banana',
92
+ },
93
+ {
94
+ label: 'Grapefruit',
95
+ value: 'grapefruit',
96
+ },
97
+ ];
98
+ return (
99
+ <>
100
+ <SelectField
101
+ label="Your favourite fruit"
102
+ onChange={(e) => setFruit(e.target.value)}
103
+ options={options}
104
+ value={fruit}
105
+ />
106
+ <SelectField
107
+ label="Your favourite fruit"
108
+ onChange={(e) => setFruit(e.target.value)}
109
+ options={options}
110
+ variant="filled"
111
+ value={fruit}
112
+ />
113
+ </>
114
+ );
115
+ });
116
+ ```
117
+
118
+ ## Sizes
119
+
120
+ Aside from the default (medium) size, two additional sizes are available: small
121
+ and large.
122
+
123
+ ```docoff-react-preview
124
+ React.createElement(() => {
125
+ const [fruit, setFruit] = React.useState('apple');
126
+ const options = [
127
+ {
128
+ label: 'Apple',
129
+ value: 'apple',
130
+ },
131
+ {
132
+ label: 'Banana',
133
+ value: 'banana',
134
+ },
135
+ {
136
+ label: 'Grapefruit',
137
+ value: 'grapefruit',
138
+ },
139
+ ];
140
+ return (
141
+ <>
142
+ <SelectField
143
+ label="Your favourite fruit"
144
+ onChange={(e) => setFruit(e.target.value)}
145
+ options={options}
146
+ size="small"
147
+ value={fruit}
148
+ />
149
+ <SelectField
150
+ label="Your favourite fruit"
151
+ onChange={(e) => setFruit(e.target.value)}
152
+ options={options}
153
+ value={fruit}
154
+ />
155
+ <SelectField
156
+ label="Your favourite fruit"
157
+ onChange={(e) => setFruit(e.target.value)}
158
+ options={options}
159
+ size="large"
160
+ value={fruit}
161
+ />
162
+ <SelectField
163
+ label="Your favourite fruit"
164
+ onChange={(e) => setFruit(e.target.value)}
165
+ options={options}
166
+ size="small"
167
+ value={fruit}
168
+ variant="filled"
169
+ />
170
+ <SelectField
171
+ label="Your favourite fruit"
172
+ onChange={(e) => setFruit(e.target.value)}
173
+ options={options}
174
+ value={fruit}
175
+ variant="filled"
176
+ />
177
+ <SelectField
178
+ label="Your favourite fruit"
179
+ onChange={(e) => setFruit(e.target.value)}
180
+ options={options}
181
+ size="large"
182
+ value={fruit}
183
+ variant="filled"
184
+ />
185
+ </>
186
+ );
187
+ });
188
+ ```
189
+
190
+ Full-width fields span the full width of a parent:
191
+
192
+ ```docoff-react-preview
193
+ React.createElement(() => {
194
+ const [fruit, setFruit] = React.useState('apple');
195
+ const options = [
196
+ {
197
+ label: 'Apple',
198
+ value: 'apple',
199
+ },
200
+ {
201
+ label: 'Banana',
202
+ value: 'banana',
203
+ },
204
+ {
205
+ label: 'Grapefruit',
206
+ value: 'grapefruit',
207
+ },
208
+ ];
209
+ return (
210
+ <>
211
+ <SelectField
212
+ fullWidth
213
+ label="Your favourite fruit"
214
+ onChange={(e) => setFruit(e.target.value)}
215
+ options={options}
216
+ value={fruit}
217
+ />
218
+ <SelectField
219
+ fullWidth
220
+ label="Your favourite fruit"
221
+ onChange={(e) => setFruit(e.target.value)}
222
+ options={options}
223
+ value={fruit}
224
+ variant="filled"
225
+ />
226
+ </>
227
+ );
228
+ });
229
+ ```
230
+
231
+ ## Grouping Related Options
232
+
233
+ For a large amount of options you can group related items together by nesting
234
+ them (implements the `optgroup` HTML element).
235
+
236
+ ```docoff-react-preview
237
+ React.createElement(() => {
238
+ const [crop, setCrop] = React.useState('apple');
239
+ const options = [
240
+ {
241
+ label: 'Fruits',
242
+ options: [
243
+ {
244
+ label: 'Apple',
245
+ value: 'apple',
246
+ },
247
+ {
248
+ label: 'Banana',
249
+ value: 'banana',
250
+ },
251
+ {
252
+ label: 'Grapefruit',
253
+ value: 'grapefruit',
254
+ },
255
+ ],
256
+ },
257
+ {
258
+ label: 'Vegetables',
259
+ options: [
260
+ {
261
+ label: 'Beetroot',
262
+ value: 'beetroot',
263
+ },
264
+ {
265
+ label: 'Carrot',
266
+ value: 'carrot',
267
+ },
268
+ {
269
+ label: 'Tomato',
270
+ value: 'tomato',
271
+ },
272
+ ],
273
+ },
274
+ ];
275
+ return (
276
+ <>
277
+ <SelectField
278
+ label="Your favourite crop"
279
+ onChange={(e) => setCrop(e.target.value)}
280
+ options={options}
281
+ value={crop}
282
+ />
283
+ <SelectField
284
+ label="Your favourite crop"
285
+ onChange={(e) => setCrop(e.target.value)}
286
+ options={options}
287
+ value={crop}
288
+ variant="filled"
289
+ />
290
+ </>
291
+ );
292
+ });
293
+ ```
294
+
295
+ ## Invisible Label
296
+
297
+ While it may be acceptable for login screens with just a few fields or for other
298
+ simple forms, it's dangerous to hide labels from users in most cases. Keep in
299
+ mind you should **provide another visual clue** so users know what to fill into
300
+ the input.
301
+
302
+ ```docoff-react-preview
303
+ React.createElement(() => {
304
+ const [fruit, setFruit] = React.useState('apple');
305
+ const options = [
306
+ {
307
+ label: 'Apple',
308
+ value: 'apple',
309
+ },
310
+ {
311
+ label: 'Banana',
312
+ value: 'banana',
313
+ },
314
+ {
315
+ label: 'Grapefruit',
316
+ value: 'grapefruit',
317
+ },
318
+ ];
319
+ return (
320
+ <>
321
+ <SelectField
322
+ isLabelVisible={false}
323
+ label="Your favourite fruit"
324
+ onChange={(e) => setFruit(e.target.value)}
325
+ options={options}
326
+ value={fruit}
327
+ />
328
+ <SelectField
329
+ isLabelVisible={false}
330
+ label="Your favourite fruit"
331
+ onChange={(e) => setFruit(e.target.value)}
332
+ options={options}
333
+ value={fruit}
334
+ variant="filled"
335
+ />
336
+ </>
337
+ );
338
+ });
339
+ ```
340
+
341
+ ## Horizontal Layout
342
+
343
+ The default vertical layout is very easy to use and work with. However, there
344
+ are situations where horizontal layout suits better — and that's why React UI
345
+ supports this kind of layout as well.
346
+
347
+ ```docoff-react-preview
348
+ React.createElement(() => {
349
+ const [fruit, setFruit] = React.useState('apple');
350
+ const options = [
351
+ {
352
+ label: 'Apple',
353
+ value: 'apple',
354
+ },
355
+ {
356
+ label: 'Banana',
357
+ value: 'banana',
358
+ },
359
+ {
360
+ label: 'Grapefruit',
361
+ value: 'grapefruit',
362
+ },
363
+ ];
364
+ return (
365
+ <>
366
+ <SelectField
367
+ label="Your favourite fruit"
368
+ layout="horizontal"
369
+ onChange={(e) => setFruit(e.target.value)}
370
+ options={options}
371
+ value={fruit}
372
+ />
373
+ <SelectField
374
+ label="Your favourite fruit"
375
+ layout="horizontal"
376
+ onChange={(e) => setFruit(e.target.value)}
377
+ options={options}
378
+ value={fruit}
379
+ variant="filled"
380
+ />
381
+ <SelectField
382
+ fullWidth
383
+ label="Your favourite fruit"
384
+ layout="horizontal"
385
+ onChange={(e) => setFruit(e.target.value)}
386
+ options={options}
387
+ value={fruit}
388
+ />
389
+ <SelectField
390
+ fullWidth
391
+ label="Your favourite fruit"
392
+ layout="horizontal"
393
+ onChange={(e) => setFruit(e.target.value)}
394
+ options={options}
395
+ value={fruit}
396
+ variant="filled"
397
+ />
398
+ <SelectField
399
+ fullWidth
400
+ isLabelVisible={false}
401
+ label="Your favourite fruit"
402
+ layout="horizontal"
403
+ onChange={(e) => setFruit(e.target.value)}
404
+ options={options}
405
+ value={fruit}
406
+ />
407
+ <SelectField
408
+ fullWidth
409
+ isLabelVisible={false}
410
+ label="Your favourite fruit"
411
+ layout="horizontal"
412
+ onChange={(e) => setFruit(e.target.value)}
413
+ options={options}
414
+ value={fruit}
415
+ variant="filled"
416
+ />
417
+ </>
418
+ );
419
+ });
420
+ ```
421
+
422
+ ## Help Text
423
+
424
+ You may provide an additional help text to clarify how the input should be
425
+ filled.
426
+
427
+ ```docoff-react-preview
428
+ React.createElement(() => {
429
+ const [fruit, setFruit] = React.useState('apple');
430
+ const options = [
431
+ {
432
+ label: 'Apple',
433
+ value: 'apple',
434
+ },
435
+ {
436
+ label: 'Banana',
437
+ value: 'banana',
438
+ },
439
+ {
440
+ label: 'Grapefruit',
441
+ value: 'grapefruit',
442
+ },
443
+ ];
444
+ return (
445
+ <>
446
+ <SelectField
447
+ helpText="Choose one or more kinds of fruit to feel happy."
448
+ label="Your favourite fruit"
449
+ onChange={(e) => setFruit(e.target.value)}
450
+ options={options}
451
+ value={fruit}
452
+ />
453
+ <SelectField
454
+ helpText="Choose one or more kinds of fruit to feel happy."
455
+ label="Your favourite fruit"
456
+ onChange={(e) => setFruit(e.target.value)}
457
+ options={options}
458
+ value={fruit}
459
+ variant="filled"
460
+ />
461
+ <SelectField
462
+ helpText="Choose one or more kinds of fruit to feel happy."
463
+ label="Your favourite fruit"
464
+ layout="horizontal"
465
+ onChange={(e) => setFruit(e.target.value)}
466
+ options={options}
467
+ value={fruit}
468
+ />
469
+ <SelectField
470
+ helpText="Choose one or more kinds of fruit to feel happy."
471
+ label="Your favourite fruit"
472
+ layout="horizontal"
473
+ onChange={(e) => setFruit(e.target.value)}
474
+ options={options}
475
+ value={fruit}
476
+ variant="filled"
477
+ />
478
+ <SelectField
479
+ fullWidth
480
+ helpText="Choose one or more kinds of fruit to feel happy."
481
+ label="Your favourite fruit"
482
+ layout="horizontal"
483
+ onChange={(e) => setFruit(e.target.value)}
484
+ options={options}
485
+ value={fruit}
486
+ />
487
+ <SelectField
488
+ fullWidth
489
+ helpText="Choose one or more kinds of fruit to feel happy."
490
+ label="Your favourite fruit"
491
+ layout="horizontal"
492
+ onChange={(e) => setFruit(e.target.value)}
493
+ options={options}
494
+ value={fruit}
495
+ variant="filled"
496
+ />
497
+ </>
498
+ );
499
+ });
500
+ ```
501
+
502
+ ## States
503
+
504
+ ### Validation States
505
+
506
+ Validation states visually present the result of validation of the input. You
507
+ should always **provide a validation message for states other than valid** so
508
+ users know what happened and what action they should take or what options they
509
+ have.
510
+
511
+ ```docoff-react-preview
512
+ React.createElement(() => {
513
+ const [fruit, setFruit] = React.useState('apple');
514
+ const options = [
515
+ {
516
+ label: 'Apple',
517
+ value: 'apple',
518
+ },
519
+ {
520
+ label: 'Banana',
521
+ value: 'banana',
522
+ },
523
+ {
524
+ label: 'Grapefruit',
525
+ value: 'grapefruit',
526
+ },
527
+ ];
528
+ return (
529
+ <>
530
+ <SelectField
531
+ label="Your favourite fruit"
532
+ onChange={(e) => setFruit(e.target.value)}
533
+ options={options}
534
+ required
535
+ validationState="valid"
536
+ validationText="Great, they're in stock!"
537
+ value={fruit}
538
+ />
539
+ <SelectField
540
+ label="Your favourite fruit"
541
+ onChange={(e) => setFruit(e.target.value)}
542
+ options={options}
543
+ required
544
+ validationState="warning"
545
+ validationText="Oh, really?"
546
+ value={fruit}
547
+ />
548
+ <SelectField
549
+ label="Your favourite fruit"
550
+ onChange={(e) => setFruit(e.target.value)}
551
+ options={options}
552
+ required
553
+ validationState="invalid"
554
+ validationText="You must select at least one kind of fruit."
555
+ value={fruit}
556
+ />
557
+ <SelectField
558
+ label="Your favourite fruit"
559
+ onChange={(e) => setFruit(e.target.value)}
560
+ options={options}
561
+ required
562
+ validationState="valid"
563
+ validationText="Great, they're in stock!"
564
+ value={fruit}
565
+ variant="filled"
566
+ />
567
+ <SelectField
568
+ label="Your favourite fruit"
569
+ onChange={(e) => setFruit(e.target.value)}
570
+ options={options}
571
+ required
572
+ validationState="warning"
573
+ validationText="Oh, really?"
574
+ value={fruit}
575
+ variant="filled"
576
+ />
577
+ <SelectField
578
+ label="Your favourite fruit"
579
+ onChange={(e) => setFruit(e.target.value)}
580
+ options={options}
581
+ required
582
+ value={fruit}
583
+ validationState="invalid"
584
+ validationText="You must select at least one kind of fruit."
585
+ variant="filled"
586
+ />
587
+ </>
588
+ );
589
+ })
590
+ ```
591
+
592
+ ### Disabled State
593
+
594
+ It's possible to disable just some options or the whole input.
595
+
596
+ ```docoff-react-preview
597
+ React.createElement(() => {
598
+ const [fruit, setFruit] = React.useState('apple');
599
+ const options = [
600
+ {
601
+ label: 'Apple',
602
+ value: 'apple',
603
+ },
604
+ {
605
+ disabled: true,
606
+ label: 'Banana',
607
+ value: 'banana',
608
+ },
609
+ {
610
+ label: 'Grapefruit',
611
+ value: 'grapefruit',
612
+ },
613
+ ];
614
+ return (
615
+ <>
616
+ <SelectField
617
+ label="Your favourite fruit"
618
+ onChange={(e) => setFruit(e.target.value)}
619
+ options={options}
620
+ value={fruit}
621
+ />
622
+ <SelectField
623
+ label="Your favourite fruit"
624
+ onChange={(e) => setFruit(e.target.value)}
625
+ options={options}
626
+ value={fruit}
627
+ variant="filled"
628
+ />
629
+ <SelectField
630
+ disabled
631
+ label="Your favourite fruit"
632
+ onChange={(e) => setFruit(e.target.value)}
633
+ options={options}
634
+ value="apple"
635
+ />
636
+ <SelectField
637
+ disabled
638
+ label="Your favourite fruit"
639
+ onChange={(e) => setFruit(e.target.value)}
640
+ options={options}
641
+ value="apple"
642
+ variant="filled"
643
+ />
644
+ </>
645
+ );
646
+ })
647
+ ```
648
+
649
+ ## Forwarding HTML Attributes
650
+
651
+ In addition to the options below in the [component's API](#api) section, you
652
+ can specify [React synthetic events] or you can **add whatever HTML attribute
653
+ you like.** All attributes that don't interfere with the API are forwarded to
654
+ the native HTML `<select>`. This enables making the component interactive and helps
655
+ to improve its accessibility.
656
+
657
+ 👉 Refer to the MDN reference for the full list of supported attributes of the
658
+ [select] element.
659
+
660
+ ## Forwarding ref
661
+
662
+ If you provide [ref], it is forwarded to the native HTML `<select>` element.
663
+
664
+ ## API
665
+
666
+ <docoff-react-props src="/components/SelectField/SelectField.jsx"></docoff-react-props>
667
+
668
+ ## Theming
669
+
670
+ Head to [Forms Theming](/docs/customize/theming/forms) to see shared form theming
671
+ options. On top of that, the following options are available for SelectField.
672
+
673
+ | Custom Property | Description |
674
+ |------------------------------------------------------|--------------------------------------------------------------|
675
+ | `--rui-FormField--box--select__caret__border-style` | SelectField arrow border style (e.g. `solid`) |
676
+ | `--rui-FormField--box--select__caret__background` | SelectField arrow background (including `url()` or gradient) |
677
+ | `--rui-FormField--box--select__option--disabled__color` | Text color of disabled SelectField options |
678
+
679
+ [React synthetic events]: https://reactjs.org/docs/events.html
680
+ [select]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select#attributes
681
+ [ref]: https://reactjs.org/docs/refs-and-the-dom.html