@react-ui-org/react-ui 0.42.1 → 0.44.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/CONTRIBUTING.md +44 -25
  2. package/README.md +1 -1
  3. package/dist/lib.development.js +1597 -651
  4. package/dist/lib.js +1 -9
  5. package/package.json +47 -46
  6. package/src/lib/components/{ui/Alert → Alert}/Alert.jsx +17 -14
  7. package/src/lib/components/{ui/Alert → Alert}/Alert.scss +3 -3
  8. package/src/lib/components/{ui/Alert → Alert}/README.mdx +6 -6
  9. package/src/lib/components/{ui/Alert → Alert}/_settings.scss +1 -1
  10. package/src/lib/components/{ui/Alert → Alert}/_theme.scss +0 -0
  11. package/src/lib/components/{ui/Alert → Alert}/_tools.scss +0 -0
  12. package/src/lib/components/{ui/Alert → Alert}/index.js +0 -0
  13. package/src/lib/components/{ui/Badge → Badge}/Badge.jsx +2 -2
  14. package/src/lib/components/{ui/Badge → Badge}/Badge.scss +3 -3
  15. package/src/lib/components/{ui/Badge → Badge}/README.mdx +3 -3
  16. package/src/lib/components/{ui/Badge → Badge}/index.js +0 -0
  17. package/src/lib/components/Button/Button.jsx +198 -0
  18. package/src/lib/components/{ui/Button → Button}/Button.scss +0 -0
  19. package/src/lib/components/{ui/Button → Button}/README.mdx +161 -76
  20. package/src/lib/components/Button/_base.scss +148 -0
  21. package/src/lib/components/{ui/Button → Button}/_priorities.scss +0 -4
  22. package/src/lib/components/{ui/Button → Button}/_settings.scss +2 -3
  23. package/src/lib/components/{ui/Button → Button}/_theme.scss +3 -11
  24. package/src/lib/components/{ui/Button → Button}/_tools.scss +27 -44
  25. package/src/lib/components/Button/helpers/getRootLabelVisibilityClassName.js +33 -0
  26. package/src/lib/components/{ui/Button → Button}/helpers/getRootPriorityClassName.js +0 -4
  27. package/src/lib/components/{ui/Button → Button}/index.js +0 -0
  28. package/src/lib/components/{ui/ButtonGroup → ButtonGroup}/ButtonGroup.jsx +9 -11
  29. package/src/lib/components/{ui/ButtonGroup → ButtonGroup}/ButtonGroup.scss +0 -0
  30. package/src/lib/components/ButtonGroup/ButtonGroupContext.js +3 -0
  31. package/src/lib/components/{ui/ButtonGroup → ButtonGroup}/README.mdx +30 -6
  32. package/src/lib/components/ButtonGroup/index.js +2 -0
  33. package/src/lib/components/{layout/CTA → CTA}/CTA.jsx +5 -2
  34. package/src/lib/components/{layout/CTA → CTA}/CTA.scss +2 -2
  35. package/src/lib/components/{layout/CTA → CTA}/CTACenter.jsx +1 -1
  36. package/src/lib/components/{layout/CTA → CTA}/CTAEnd.jsx +1 -1
  37. package/src/lib/components/{layout/CTA → CTA}/CTAStart.jsx +1 -1
  38. package/src/lib/components/{layout/CTA → CTA}/README.mdx +4 -4
  39. package/src/lib/components/{layout/CTA → CTA}/index.js +0 -0
  40. package/src/lib/components/{ui/Card → Card}/Card.jsx +6 -4
  41. package/src/lib/components/{ui/Card → Card}/Card.scss +1 -1
  42. package/src/lib/components/{ui/Card → Card}/CardBody.jsx +1 -1
  43. package/src/lib/components/{ui/Card → Card}/CardFooter.jsx +1 -1
  44. package/src/lib/components/{ui/Card → Card}/README.mdx +4 -4
  45. package/src/lib/components/{ui/Card → Card}/_theme.scss +0 -0
  46. package/src/lib/components/{ui/Card → Card}/_tools.scss +0 -0
  47. package/src/lib/components/{ui/Card → Card}/index.js +0 -0
  48. package/src/lib/components/{layout/Center → Center}/Center.jsx +1 -1
  49. package/src/lib/components/{layout/Center → Center}/Center.scss +0 -0
  50. package/src/lib/components/{layout/Center → Center}/README.mdx +2 -2
  51. package/src/lib/components/{layout/Center → Center}/index.js +0 -0
  52. package/src/lib/components/CheckboxField/CheckboxField.jsx +164 -0
  53. package/src/lib/components/{ui/CheckboxField → CheckboxField}/CheckboxField.scss +5 -5
  54. package/src/lib/components/{ui/CheckboxField → CheckboxField}/README.mdx +17 -14
  55. package/src/lib/components/{ui/CheckboxField → CheckboxField}/index.js +0 -0
  56. package/src/lib/components/FileInputField/FileInputField.jsx +162 -0
  57. package/src/lib/components/{ui/FileInputField → FileInputField}/FileInputField.scss +5 -5
  58. package/src/lib/components/{ui/FileInputField → FileInputField}/README.mdx +8 -6
  59. package/src/lib/components/{ui/FileInputField → FileInputField}/index.js +0 -0
  60. package/src/lib/components/{layout/FormLayout → FormLayout}/FormLayout.jsx +16 -18
  61. package/src/lib/components/{layout/FormLayout → FormLayout}/FormLayout.scss +3 -3
  62. package/src/lib/components/FormLayout/FormLayoutContext.js +3 -0
  63. package/src/lib/components/{layout/FormLayout → FormLayout}/FormLayoutCustomField.jsx +33 -30
  64. package/src/lib/components/{layout/FormLayout → FormLayout}/FormLayoutCustomField.scss +4 -4
  65. package/src/lib/components/{layout/FormLayout → FormLayout}/README.mdx +37 -47
  66. package/src/lib/components/{layout/FormLayout → FormLayout}/_theme.scss +0 -0
  67. package/src/lib/components/{layout/FormLayout → FormLayout}/index.js +1 -0
  68. package/src/lib/components/{layout/Grid → Grid}/Grid.jsx +23 -5
  69. package/src/lib/components/{layout/Grid → Grid}/Grid.scss +13 -4
  70. package/src/lib/components/{layout/Grid → Grid}/GridSpan.jsx +10 -3
  71. package/src/lib/components/{layout/Grid → Grid}/README.mdx +42 -38
  72. package/src/lib/components/{layout/Grid → Grid}/_theme.scss +1 -2
  73. package/src/lib/components/{layout/Grid → Grid}/_tools.scss +2 -2
  74. package/src/lib/components/{layout/Grid → Grid}/helpers/generateResponsiveCustomProperties.js +0 -0
  75. package/src/lib/components/{layout/Grid → Grid}/index.js +0 -0
  76. package/src/lib/components/Link/Link.jsx +45 -0
  77. package/src/lib/components/Link/Link.scss +11 -0
  78. package/src/lib/components/Link/README.mdx +85 -0
  79. package/src/lib/components/Link/_theme.scss +4 -0
  80. package/src/lib/components/Link/index.js +1 -0
  81. package/src/lib/components/{layout/List → List}/List.jsx +1 -1
  82. package/src/lib/components/{layout/List → List}/List.scss +2 -2
  83. package/src/lib/components/{layout/List → List}/ListItem.jsx +1 -1
  84. package/src/lib/components/{layout/List → List}/README.mdx +3 -3
  85. package/src/lib/components/{layout/List → List}/_theme.scss +0 -0
  86. package/src/lib/components/{layout/List → List}/index.js +0 -0
  87. package/src/lib/components/{layout/Media → Media}/Media.jsx +4 -2
  88. package/src/lib/components/{layout/Media → Media}/Media.scss +1 -1
  89. package/src/lib/components/{layout/Media → Media}/MediaBody.jsx +1 -1
  90. package/src/lib/components/{layout/Media → Media}/MediaObject.jsx +1 -1
  91. package/src/lib/components/{layout/Media → Media}/README.mdx +2 -2
  92. package/src/lib/components/{layout/Media → Media}/index.js +0 -0
  93. package/src/lib/components/{ui/Modal → Modal}/Modal.jsx +28 -27
  94. package/src/lib/components/{ui/Modal → Modal}/Modal.scss +5 -5
  95. package/src/lib/components/{ui/Modal → Modal}/README.mdx +42 -42
  96. package/src/lib/components/{ui/Modal → Modal}/_settings.scss +4 -4
  97. package/src/lib/components/{ui/Modal → Modal}/_theme.scss +0 -0
  98. package/src/lib/components/{ui/Modal → Modal}/index.js +0 -0
  99. package/src/lib/components/{ui/Paper → Paper}/Paper.jsx +8 -1
  100. package/src/lib/components/{ui/Paper → Paper}/Paper.scss +5 -0
  101. package/src/lib/components/{ui/Paper → Paper}/README.mdx +15 -3
  102. package/src/lib/components/{ui/Paper → Paper}/_theme.scss +2 -0
  103. package/src/lib/components/{ui/Paper → Paper}/index.js +0 -0
  104. package/src/lib/components/{ui/Radio → Radio}/README.mdx +20 -17
  105. package/src/lib/components/Radio/Radio.jsx +188 -0
  106. package/src/lib/components/{ui/Radio → Radio}/Radio.scss +9 -9
  107. package/src/lib/components/{ui/Radio → Radio}/index.js +0 -0
  108. package/src/lib/components/{ui/ScrollView → ScrollView}/README.mdx +11 -11
  109. package/src/lib/components/{ui/ScrollView → ScrollView}/ScrollView.jsx +9 -10
  110. package/src/lib/components/{ui/ScrollView → ScrollView}/ScrollView.scss +6 -6
  111. package/src/lib/components/{ui/ScrollView → ScrollView}/_theme.scss +0 -0
  112. package/src/lib/components/{ui/ScrollView → ScrollView}/index.js +0 -0
  113. package/src/lib/components/{ui/SelectField → SelectField}/README.mdx +47 -44
  114. package/src/lib/components/SelectField/SelectField.jsx +219 -0
  115. package/src/lib/components/{ui/SelectField → SelectField}/SelectField.scss +6 -6
  116. package/src/lib/components/{ui/SelectField → SelectField}/index.js +0 -0
  117. package/src/lib/components/{ui/Table → Table}/README.mdx +10 -10
  118. package/src/lib/components/{ui/Table → Table}/Table.jsx +9 -13
  119. package/src/lib/components/{ui/Table → Table}/Table.scss +1 -1
  120. package/src/lib/components/{ui/Table → Table}/_settings.scss +4 -4
  121. package/src/lib/components/{ui/Table → Table}/index.js +0 -0
  122. package/src/lib/components/{ui/Tabs → Tabs}/README.mdx +4 -4
  123. package/src/lib/components/{ui/Tabs → Tabs}/Tabs.jsx +4 -4
  124. package/src/lib/components/{ui/Tabs → Tabs}/Tabs.scss +1 -1
  125. package/src/lib/components/{ui/Tabs → Tabs}/TabsItem.jsx +4 -3
  126. package/src/lib/components/{ui/Tabs → Tabs}/TabsItem.scss +3 -3
  127. package/src/lib/components/{ui/Tabs → Tabs}/_theme.scss +0 -0
  128. package/src/lib/components/{ui/Tabs → Tabs}/index.js +0 -0
  129. package/src/lib/components/{ui/Text → Text}/README.mdx +19 -19
  130. package/src/lib/components/{ui/Text → Text}/Text.jsx +1 -1
  131. package/src/lib/components/{ui/Text → Text}/Text.scss +0 -0
  132. package/src/lib/components/{ui/Text → Text}/helpers/getRootHyphensClassName.js +0 -0
  133. package/src/lib/components/{ui/Text → Text}/helpers/getRootWordWrappingClassName.js +0 -0
  134. package/src/lib/components/{ui/Text → Text}/index.js +0 -0
  135. package/src/lib/components/{ui/TextArea → TextArea}/README.mdx +8 -6
  136. package/src/lib/components/{ui/TextArea → TextArea}/TextArea.jsx +78 -78
  137. package/src/lib/components/{ui/TextArea → TextArea}/TextArea.scss +6 -6
  138. package/src/lib/components/{ui/TextArea → TextArea}/index.js +0 -0
  139. package/src/lib/components/{ui/TextField → TextField}/README.mdx +7 -6
  140. package/src/lib/components/{ui/TextField → TextField}/TextField.jsx +20 -22
  141. package/src/lib/components/{ui/TextField → TextField}/TextField.scss +6 -6
  142. package/src/lib/components/{ui/TextField → TextField}/index.js +0 -0
  143. package/src/lib/components/{ui/Toggle → Toggle}/README.mdx +17 -14
  144. package/src/lib/components/Toggle/Toggle.jsx +163 -0
  145. package/src/lib/components/{ui/Toggle → Toggle}/Toggle.scss +5 -5
  146. package/src/lib/components/{ui/Toggle → Toggle}/index.js +0 -0
  147. package/src/lib/components/{layout/Toolbar → Toolbar}/README.mdx +29 -29
  148. package/src/lib/components/{layout/Toolbar → Toolbar}/Toolbar.jsx +1 -1
  149. package/src/lib/components/{layout/Toolbar → Toolbar}/Toolbar.scss +1 -1
  150. package/src/lib/components/{layout/Toolbar → Toolbar}/ToolbarGroup.jsx +1 -1
  151. package/src/lib/components/{layout/Toolbar → Toolbar}/ToolbarItem.jsx +1 -1
  152. package/src/lib/components/{layout/Toolbar → Toolbar}/_theme.scss +0 -0
  153. package/src/lib/components/{layout/Toolbar → Toolbar}/index.js +0 -0
  154. package/src/lib/components/{ui/withForwardedRef.jsx → withForwardedRef.jsx} +0 -0
  155. package/src/lib/helpers/resolveContextOrProp.js +7 -0
  156. package/src/lib/index.js +34 -35
  157. package/src/lib/styles/tools/_accessibility.scss +9 -0
  158. package/src/lib/theme.scss +25 -7
  159. package/src/lib/components/ui/Button/Button.jsx +0 -191
  160. package/src/lib/components/ui/Button/_base.scss +0 -154
  161. package/src/lib/components/ui/Button/helpers/getRootLabelVisibilityClassName.js +0 -11
  162. package/src/lib/components/ui/ButtonGroup/index.js +0 -1
  163. package/src/lib/components/ui/CheckboxField/CheckboxField.jsx +0 -173
  164. package/src/lib/components/ui/FileInputField/FileInputField.jsx +0 -158
  165. package/src/lib/components/ui/Radio/Radio.jsx +0 -179
  166. package/src/lib/components/ui/SelectField/SelectField.jsx +0 -214
  167. package/src/lib/components/ui/Toggle/Toggle.jsx +0 -174
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: CheckboxField
3
- menu: 'UI'
4
- route: /components/ui/checkbox-field
3
+ menu: 'Inputs'
4
+ route: /components/checkbox-field
5
5
  ---
6
6
 
7
7
  # CheckboxField
@@ -29,9 +29,9 @@ And use it:
29
29
  const [agree, setAgree] = React.useState(true);
30
30
  return (
31
31
  <CheckboxField
32
- changeHandler={() => setAgree(!agree)}
33
32
  checked={agree}
34
33
  label="I agree"
34
+ onChange={() => setAgree(!agree)}
35
35
  />
36
36
  );
37
37
  }}
@@ -44,13 +44,13 @@ See [API](#api) for all available options.
44
44
  - Use the CheckboxField when there are lists of options and the user may
45
45
  **select any number of choices,** including zero, one, or several. For
46
46
  selecting just a single option from the list, use either the
47
- [Radio](/components/ui/radio) or [SelectField](/components/ui/select-field)
47
+ [Radio](/components/radio) or [SelectField](/components/select-field)
48
48
  component.
49
49
 
50
50
  - Use the CheckboxField for boolean (true/false) input **in forms that require
51
51
  to be confirmed** by a button to become active. To toggle things on or off
52
52
  with an immediate effect (without confirmation), use rather the
53
- [Toggle](/components/ui/toggle) component.
53
+ [Toggle](/components/toggle) component.
54
54
 
55
55
  - **Use positive wording for the checkbox label,** so that it's clear what will
56
56
  happen when the user turns on the checkbox. Avoid negations such as “Don't
@@ -81,10 +81,10 @@ turning the checkbox on or off.
81
81
  const [getNewsletter, setGetNewsletter] = React.useState(true);
82
82
  return (
83
83
  <CheckboxField
84
- changeHandler={() => setGetNewsletter(!getNewsletter)}
85
84
  checked={getNewsletter}
86
85
  helpText="We will not bother you more than once a month, we promise!"
87
86
  label="Send me newsletter"
87
+ onChange={() => setGetNewsletter(!getNewsletter)}
88
88
  />
89
89
  );
90
90
  }}
@@ -100,10 +100,10 @@ label remains accessible to assistive technologies.
100
100
  const [checked, setChecked] = React.useState(true);
101
101
  return (
102
102
  <CheckboxField
103
- changeHandler={() => setChecked(!checked)}
104
103
  checked={checked}
105
104
  isLabelVisible={false}
106
105
  label="You cannot see this"
106
+ onChange={() => setChecked(!checked)}
107
107
  />
108
108
  );
109
109
  }}
@@ -116,10 +116,10 @@ It's also possible to display label before input:
116
116
  const [checked, setChecked] = React.useState(true);
117
117
  return (
118
118
  <CheckboxField
119
- changeHandler={() => setChecked(!checked)}
120
119
  checked={checked}
121
120
  label="Label precedes input"
122
121
  labelPosition="before"
122
+ onChange={() => setChecked(!checked)}
123
123
  />
124
124
  );
125
125
  }}
@@ -140,22 +140,22 @@ have.
140
140
  return (
141
141
  <>
142
142
  <CheckboxField
143
- changeHandler={() => setAgree(!agree)}
144
143
  checked={agree}
145
144
  label="I have read and agree with terms and conditions"
145
+ onChange={() => setAgree(!agree)}
146
146
  validationState="valid"
147
147
  />
148
148
  <CheckboxField
149
- changeHandler={() => setAgree(!agree)}
150
149
  checked={agree}
151
150
  label="I have read and agree with terms and conditions"
151
+ onChange={() => setAgree(!agree)}
152
152
  validationState="warning"
153
153
  validationText="Please wait 10 minutes until we verify your data."
154
154
  />
155
155
  <CheckboxField
156
- changeHandler={() => setAgree(!agree)}
157
156
  checked={agree}
158
157
  label="I have read and agree with terms and conditions"
158
+ onChange={() => setAgree(!agree)}
159
159
  required
160
160
  validationState="invalid"
161
161
  validationText="You must agree to be able to proceed."
@@ -183,9 +183,10 @@ Disabled state makes the input unavailable.
183
183
 
184
184
  ## API
185
185
 
186
- In addition to the options below, you can add any custom attributes that do not
187
- interfere with the API, and they will be passed to the `input` HTML element.
188
- This is useful mainly to improve component's accessibility.
186
+ In addition to the options below, you can specify [React synthetic events] or
187
+ any custom HTML attributes that do not interfere with the API, and they will be
188
+ passed to the `input` HTML element. This enables making the component
189
+ interactive and helps improve its accessibility.
189
190
 
190
191
  <Props table of={CheckboxField} />
191
192
 
@@ -198,3 +199,5 @@ options. On top of that, the following options are available for CheckboxField.
198
199
  |----------------------------------------------------------------------|----------------------------------------------|
199
200
  | `--rui-FormField--check__input--checkbox__border-radius` | Input corner radius |
200
201
  | `--rui-FormField--check__input--checkbox--checked__background-image` | Background image of checked input |
202
+
203
+ [React synthetic events]: https://reactjs.org/docs/events.html
@@ -0,0 +1,162 @@
1
+ import PropTypes from 'prop-types';
2
+ import React, { useContext } from 'react';
3
+ import getRootValidationStateClassName from '../../helpers/getRootValidationStateClassName';
4
+ import { resolveContextOrProp } from '../../helpers/resolveContextOrProp';
5
+ import { withProviderContext } from '../../provider';
6
+ import transferProps from '../../utils/transferProps';
7
+ import { FormLayoutContext } from '../FormLayout';
8
+ import withForwardedRef from '../withForwardedRef';
9
+ import styles from './FileInputField.scss';
10
+
11
+ export const FileInputField = ({
12
+ disabled,
13
+ forwardedRef,
14
+ fullWidth,
15
+ helpText,
16
+ id,
17
+ isLabelVisible,
18
+ label,
19
+ layout,
20
+ required,
21
+ validationState,
22
+ validationText,
23
+ ...restProps
24
+ }) => {
25
+ const context = useContext(FormLayoutContext);
26
+
27
+ return (
28
+ <label
29
+ className={[
30
+ styles.root,
31
+ fullWidth ? styles.isRootFullWidth : '',
32
+ context ? styles.isRootInFormLayout : '',
33
+ resolveContextOrProp(context && context.layout, layout) === 'horizontal'
34
+ ? styles.rootLayoutHorizontal
35
+ : styles.rootLayoutVertical,
36
+ disabled ? styles.isRootDisabled : '',
37
+ required ? styles.isRootRequired : '',
38
+ getRootValidationStateClassName(validationState, styles),
39
+ ].join(' ')}
40
+ htmlFor={id}
41
+ id={id && `${id}__label`}
42
+ >
43
+ <div
44
+ className={[
45
+ styles.label,
46
+ isLabelVisible ? '' : styles.isLabelHidden,
47
+ ].join(' ')}
48
+ id={id && `${id}__labelText`}
49
+ >
50
+ {label}
51
+ </div>
52
+ <div className={styles.field}>
53
+ <div className={styles.inputContainer}>
54
+ <input
55
+ {...transferProps(restProps)}
56
+ className={styles.input}
57
+ disabled={disabled}
58
+ id={id}
59
+ ref={forwardedRef}
60
+ required={required}
61
+ type="file"
62
+ />
63
+ </div>
64
+ {helpText && (
65
+ <div
66
+ className={styles.helpText}
67
+ id={id && `${id}__helpText`}
68
+ >
69
+ {helpText}
70
+ </div>
71
+ )}
72
+ {validationText && (
73
+ <div
74
+ className={styles.validationText}
75
+ id={id && `${id}__validationText`}
76
+ >
77
+ {validationText}
78
+ </div>
79
+ )}
80
+ </div>
81
+ </label>
82
+ );
83
+ };
84
+
85
+ FileInputField.defaultProps = {
86
+ disabled: false,
87
+ forwardedRef: undefined,
88
+ fullWidth: false,
89
+ helpText: null,
90
+ id: undefined,
91
+ isLabelVisible: true,
92
+ layout: 'vertical',
93
+ required: false,
94
+ validationState: null,
95
+ validationText: null,
96
+ };
97
+
98
+ FileInputField.propTypes = {
99
+ /**
100
+ * If `true`, the input will be disabled.
101
+ */
102
+ disabled: PropTypes.bool,
103
+ /**
104
+ * Reference forwarded to the `input` element.
105
+ */
106
+ forwardedRef: PropTypes.oneOfType([
107
+ PropTypes.func,
108
+ // eslint-disable-next-line react/forbid-prop-types
109
+ PropTypes.shape({ current: PropTypes.any }),
110
+ ]),
111
+ /**
112
+ * If `true`, the field will span the full width of its parent.
113
+ */
114
+ fullWidth: PropTypes.bool,
115
+ /**
116
+ * Optional help text.
117
+ */
118
+ helpText: PropTypes.node,
119
+ /**
120
+ * ID of the `<input>` HTML element.
121
+ *
122
+ * Also serves as base for ids of nested elements:
123
+ * * `<ID>__label`
124
+ * * `<ID>__labelText`
125
+ * * `<ID>__helpText`
126
+ * * `<ID>__validationText`
127
+ */
128
+ id: PropTypes.string,
129
+ /**
130
+ * If `false`, the label will be visually hidden (but remains accessible by assistive
131
+ * technologies).
132
+ */
133
+ isLabelVisible: PropTypes.bool,
134
+ /**
135
+ * Text field label.
136
+ */
137
+ label: PropTypes.string.isRequired,
138
+ /**
139
+ * Layout of the field.
140
+ *
141
+ * Ignored if the component is rendered within `FormLayout` component
142
+ * as the value is inherited in such case.
143
+ *
144
+ */
145
+ layout: PropTypes.oneOf(['horizontal', 'vertical']),
146
+ /**
147
+ * If `true`, the input will be required.
148
+ */
149
+ required: PropTypes.bool,
150
+ /**
151
+ * Alter the field to provide feedback based on validation result.
152
+ */
153
+ validationState: PropTypes.oneOf(['invalid', 'valid', 'warning']),
154
+ /**
155
+ * Validation message to be displayed.
156
+ */
157
+ validationText: PropTypes.node,
158
+ };
159
+
160
+ export const FileInputFieldWithContext = withForwardedRef(withProviderContext(FileInputField, 'FileInputField'));
161
+
162
+ export default FileInputFieldWithContext;
@@ -1,8 +1,8 @@
1
- @use '../../../styles/tools/form-fields/box-field-elements';
2
- @use '../../../styles/tools/form-fields/box-field-layout';
3
- @use '../../../styles/tools/form-fields/foundation';
4
- @use '../../../styles/tools/form-fields/variants';
5
- @use '../../../styles/tools/accessibility';
1
+ @use '../../styles/tools/form-fields/box-field-elements';
2
+ @use '../../styles/tools/form-fields/box-field-layout';
3
+ @use '../../styles/tools/form-fields/foundation';
4
+ @use '../../styles/tools/form-fields/variants';
5
+ @use '../../styles/tools/accessibility';
6
6
 
7
7
  // Foundation
8
8
  .root {
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: FileInputField
3
- menu: 'UI'
4
- route: /components/ui/file-input-field
3
+ menu: 'Inputs'
4
+ route: /components/file-input-field
5
5
  ---
6
6
 
7
7
  # FileInputField
@@ -189,10 +189,10 @@ It's possible to disable the whole input.
189
189
 
190
190
  ## API
191
191
 
192
- In addition to the options below, you can add any custom attributes that do not
193
- interfere with the API, and they will be passed to the `input` HTML element.
194
- This is useful mainly to improve component's
195
- [accessibility](#forwarding-html-attributes).
192
+ In addition to the options below, you can specify [React synthetic events] or
193
+ any custom HTML attributes that do not interfere with the API, and they will be
194
+ passed to the `input` HTML element. This enables making the component
195
+ interactive and helps improve its [accessibility](#forwarding-html-attributes).
196
196
 
197
197
  <Props table of={FileInputField} />
198
198
 
@@ -200,3 +200,5 @@ This is useful mainly to improve component's
200
200
 
201
201
  Head to [Forms Theming](/customize/theming/forms) to see shared form theming
202
202
  options.
203
+
204
+ [React synthetic events]: https://reactjs.org/docs/events.html
@@ -1,7 +1,7 @@
1
- import flattenChildren from 'react-keyed-flatten-children';
2
1
  import PropTypes from 'prop-types';
3
2
  import React from 'react';
4
- import { withProviderContext } from '../../../provider';
3
+ import { withProviderContext } from '../../provider';
4
+ import { FormLayoutContext } from './FormLayoutContext';
5
5
  import styles from './FormLayout.scss';
6
6
 
7
7
  const PREDEFINED_LABEL_WIDTH_VALUES = ['auto', 'default', 'limited'];
@@ -56,20 +56,11 @@ export const FormLayout = (props) => {
56
56
  ].join(' ')}
57
57
  {...hasCustomLabelWidth ? { style: { '--rui-custom-label-width': labelWidth } } : {}}
58
58
  >
59
- {/*
60
- Flatten children to one-dimensional array so we get over React Fragments with the `map()`
61
- function.
62
- */}
63
- {flattenChildren(children).map((child) => {
64
- if (!React.isValidElement(child)) {
65
- return null;
66
- }
67
-
68
- return React.cloneElement(child, {
69
- inFormLayout: true,
70
- layout: fieldLayout,
71
- });
72
- })}
59
+ <FormLayoutContext.Provider
60
+ value={{ layout: fieldLayout }}
61
+ >
62
+ {children}
63
+ </FormLayoutContext.Provider>
73
64
  </div>
74
65
  );
75
66
  };
@@ -88,8 +79,15 @@ FormLayout.propTypes = {
88
79
  */
89
80
  autoWidth: PropTypes.bool,
90
81
  /**
91
- * Supported form field components: CheckboxField, Radio, SelectField, TextArea, TextField,
92
- * Toggle, and FormLayoutCustomField.
82
+ * Supported form field components:
83
+ * * `CheckboxField`
84
+ * * `FileInputField`
85
+ * * `FormLayoutCustomField`
86
+ * * `Radio`
87
+ * * `SelectField`
88
+ * * `TextArea`
89
+ * * `TextField`
90
+ * * `Toggle`
93
91
  */
94
92
  children: PropTypes.node,
95
93
  /**
@@ -13,9 +13,9 @@
13
13
  // (a global default which can be customised per use).
14
14
  // https://github.com/react-ui-org/react-ui/issues/232
15
15
 
16
- @use '../../../styles/settings/forms';
17
- @use '../../../styles/tools/breakpoint';
18
- @use '../../../styles/tools/spacing';
16
+ @use '../../styles/settings/forms';
17
+ @use '../../styles/tools/breakpoint';
18
+ @use '../../styles/tools/spacing';
19
19
  @use 'theme';
20
20
 
21
21
  .root {
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+
3
+ export const FormLayoutContext = React.createContext(null);
@@ -1,9 +1,10 @@
1
1
  import PropTypes from 'prop-types';
2
- import React from 'react';
3
- import getRootSizeClassName from '../../../helpers/getRootSizeClassName';
4
- import getRootValidationStateClassName from '../../../helpers/getRootValidationStateClassName';
5
- import { withProviderContext } from '../../../provider';
2
+ import React, { useContext } from 'react';
3
+ import getRootSizeClassName from '../../helpers/getRootSizeClassName';
4
+ import getRootValidationStateClassName from '../../helpers/getRootValidationStateClassName';
5
+ import { withProviderContext } from '../../provider';
6
6
  import styles from './FormLayoutCustomField.scss';
7
+ import { FormLayoutContext } from './FormLayoutContext';
7
8
 
8
9
  const renderLabel = (id, label, labelForId) => {
9
10
  if (labelForId && label) {
@@ -40,31 +41,34 @@ export const FormLayoutCustomField = ({
40
41
  innerFieldSize,
41
42
  label,
42
43
  labelForId,
43
- layout,
44
44
  required,
45
45
  validationState,
46
- }) => (
47
- <div
48
- id={id}
49
- className={[
50
- styles.root,
51
- fullWidth ? styles.isRootFullWidth : '',
52
- layout === 'vertical' ? styles.rootLayoutVertical : styles.rootLayoutHorizontal,
53
- disabled ? styles.isRootDisabled : '',
54
- required ? styles.isRootRequired : '',
55
- getRootSizeClassName(innerFieldSize, styles),
56
- getRootValidationStateClassName(validationState, styles),
57
- ].join(' ')}
58
- >
59
- {renderLabel(id, label, labelForId)}
46
+ }) => {
47
+ const context = useContext(FormLayoutContext);
48
+
49
+ return (
60
50
  <div
61
- id={id && `${id}__field`}
62
- className={styles.field}
51
+ id={id}
52
+ className={[
53
+ styles.root,
54
+ fullWidth ? styles.isRootFullWidth : '',
55
+ context && context.layout === 'horizontal' ? styles.rootLayoutHorizontal : styles.rootLayoutVertical,
56
+ disabled ? styles.isRootDisabled : '',
57
+ required ? styles.isRootRequired : '',
58
+ getRootSizeClassName(innerFieldSize, styles),
59
+ getRootValidationStateClassName(validationState, styles),
60
+ ].join(' ')}
63
61
  >
64
- {children}
62
+ {renderLabel(id, label, labelForId)}
63
+ <div
64
+ id={id && `${id}__field`}
65
+ className={styles.field}
66
+ >
67
+ {children}
68
+ </div>
65
69
  </div>
66
- </div>
67
- );
70
+ );
71
+ };
68
72
 
69
73
  FormLayoutCustomField.defaultProps = {
70
74
  children: null,
@@ -74,7 +78,6 @@ FormLayoutCustomField.defaultProps = {
74
78
  innerFieldSize: null,
75
79
  label: null,
76
80
  labelForId: undefined,
77
- layout: 'vertical',
78
81
  required: false,
79
82
  validationState: null,
80
83
  };
@@ -94,6 +97,10 @@ FormLayoutCustomField.propTypes = {
94
97
  fullWidth: PropTypes.bool,
95
98
  /**
96
99
  * ID of the root HTML element.
100
+ *
101
+ * Also serves as base for ids of nested elements:
102
+ * * `<ID>__field`
103
+ * * `<ID>__label`
97
104
  */
98
105
  id: PropTypes.string,
99
106
  /**
@@ -105,13 +112,9 @@ FormLayoutCustomField.propTypes = {
105
112
  */
106
113
  label: PropTypes.string,
107
114
  /**
108
- * Optional ID of labelled field to keep accessibility features.
115
+ * Optional ID of labeled field to keep accessibility features. Only available if `label` is set.
109
116
  */
110
117
  labelForId: PropTypes.string,
111
- /**
112
- * Layout of the field, controlled by parent FormLayout.
113
- */
114
- layout: PropTypes.oneOf(['horizontal', 'vertical']),
115
118
  /**
116
119
  * If `true`, label will be styled as required.
117
120
  */
@@ -1,7 +1,7 @@
1
- @use '../../../styles/tools/form-fields/foundation';
2
- @use '../../../styles/tools/form-fields/box-field-layout';
3
- @use '../../../styles/tools/form-fields/box-field-sizes';
4
- @use '../../../styles/tools/form-fields/variants';
1
+ @use '../../styles/tools/form-fields/foundation';
2
+ @use '../../styles/tools/form-fields/box-field-layout';
3
+ @use '../../styles/tools/form-fields/box-field-sizes';
4
+ @use '../../styles/tools/form-fields/variants';
5
5
 
6
6
  // Foundation
7
7
  .root {