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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
@@ -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