@react-ui-org/react-ui 0.44.1 → 0.47.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 (192) hide show
  1. package/CONTRIBUTING.md +7 -0
  2. package/README.md +15 -16
  3. package/dist/lib.development.js +271 -415
  4. package/dist/lib.js +1 -1
  5. package/package.json +11 -13
  6. package/src/lib/components/Alert/Alert.jsx +45 -44
  7. package/src/lib/components/Alert/Alert.scss +48 -48
  8. package/src/lib/components/Alert/README.mdx +2 -5
  9. package/src/lib/components/Alert/_settings.scss +4 -4
  10. package/src/lib/components/Alert/_theme.scss +50 -50
  11. package/src/lib/components/Alert/_tools.scss +6 -6
  12. package/src/lib/components/Badge/Badge.jsx +9 -11
  13. package/src/lib/components/Badge/Badge.scss +57 -57
  14. package/src/lib/components/Button/Button.jsx +14 -13
  15. package/src/lib/components/Button/Button.scss +2 -2
  16. package/src/lib/components/Button/README.mdx +11 -6
  17. package/src/lib/components/Button/_base.scss +69 -69
  18. package/src/lib/components/Button/_priorities.scss +49 -49
  19. package/src/lib/components/Button/_settings.scss +10 -10
  20. package/src/lib/components/Button/_theme.scss +18 -15
  21. package/src/lib/components/Button/_tools.scss +98 -100
  22. package/src/lib/components/Button/helpers/getRootLabelVisibilityClassName.js +4 -4
  23. package/src/lib/components/ButtonGroup/ButtonGroup.jsx +41 -25
  24. package/src/lib/components/ButtonGroup/ButtonGroup.scss +3 -3
  25. package/src/lib/components/ButtonGroup/README.mdx +1 -1
  26. package/src/lib/components/Card/Card.jsx +10 -9
  27. package/src/lib/components/Card/Card.scss +28 -28
  28. package/src/lib/components/Card/CardBody.jsx +17 -12
  29. package/src/lib/components/Card/CardFooter.jsx +22 -9
  30. package/src/lib/components/Card/_theme.scss +50 -50
  31. package/src/lib/components/Card/_tools.scss +6 -6
  32. package/src/lib/components/CheckboxField/CheckboxField.jsx +21 -20
  33. package/src/lib/components/CheckboxField/CheckboxField.scss +20 -20
  34. package/src/lib/components/CheckboxField/README.mdx +1 -1
  35. package/src/lib/components/FileInputField/FileInputField.jsx +16 -15
  36. package/src/lib/components/FileInputField/FileInputField.scss +19 -19
  37. package/src/lib/components/FileInputField/README.mdx +1 -1
  38. package/src/lib/components/FormLayout/FormLayout.jsx +19 -17
  39. package/src/lib/components/FormLayout/FormLayout.scss +17 -17
  40. package/src/lib/components/FormLayout/FormLayoutCustomField.jsx +18 -12
  41. package/src/lib/components/FormLayout/FormLayoutCustomField.scss +18 -18
  42. package/src/lib/components/FormLayout/README.mdx +26 -49
  43. package/src/lib/components/Grid/Grid.jsx +25 -24
  44. package/src/lib/components/Grid/Grid.scss +33 -29
  45. package/src/lib/components/Grid/GridSpan.jsx +11 -10
  46. package/src/lib/components/Grid/README.mdx +46 -20
  47. package/src/lib/components/Grid/{helpers → _helpers}/generateResponsiveCustomProperties.js +0 -2
  48. package/src/lib/components/Grid/_theme.scss +9 -9
  49. package/src/lib/components/Grid/_tools.scss +20 -20
  50. package/src/lib/components/Modal/Modal.jsx +38 -32
  51. package/src/lib/components/Modal/Modal.scss +73 -73
  52. package/src/lib/components/Modal/README.mdx +2 -5
  53. package/src/lib/components/Modal/_settings.scss +5 -5
  54. package/src/lib/components/Modal/_theme.scss +17 -17
  55. package/src/lib/components/Paper/Paper.jsx +9 -9
  56. package/src/lib/components/Paper/Paper.scss +8 -8
  57. package/src/lib/components/Popover/Popover.jsx +94 -0
  58. package/src/lib/components/Popover/Popover.scss +235 -0
  59. package/src/lib/components/Popover/PopoverWrapper.jsx +46 -0
  60. package/src/lib/components/Popover/README.mdx +333 -0
  61. package/src/lib/components/Popover/_helpers/getRootAlignmentClassName.js +13 -0
  62. package/src/lib/components/Popover/_helpers/getRootSideClassName.js +17 -0
  63. package/src/lib/components/Popover/_theme.scss +16 -0
  64. package/src/lib/components/Popover/index.js +2 -0
  65. package/src/lib/components/Radio/README.mdx +1 -1
  66. package/src/lib/components/Radio/Radio.jsx +15 -14
  67. package/src/lib/components/Radio/Radio.scss +26 -26
  68. package/src/lib/components/ScrollView/README.mdx +5 -5
  69. package/src/lib/components/ScrollView/ScrollView.jsx +22 -22
  70. package/src/lib/components/ScrollView/ScrollView.scss +113 -113
  71. package/src/lib/{services/elementPositionService.js → components/ScrollView/_helpers/getElementsPositionDifference.js} +0 -2
  72. package/src/lib/{hooks → components/ScrollView/_hooks}/useLoadResizeHook.js +1 -1
  73. package/src/lib/{hooks → components/ScrollView/_hooks}/useScrollPositionHook.js +1 -1
  74. package/src/lib/components/SelectField/README.mdx +1 -1
  75. package/src/lib/components/SelectField/SelectField.jsx +17 -16
  76. package/src/lib/components/SelectField/SelectField.scss +30 -30
  77. package/src/lib/components/Table/README.mdx +1 -1
  78. package/src/lib/components/Table/Table.jsx +3 -3
  79. package/src/lib/components/Table/Table.scss +28 -35
  80. package/src/lib/components/Table/_settings.scss +5 -5
  81. package/src/lib/components/Tabs/Tabs.jsx +4 -5
  82. package/src/lib/components/Tabs/Tabs.scss +21 -21
  83. package/src/lib/components/Tabs/TabsItem.jsx +7 -6
  84. package/src/lib/components/Tabs/TabsItem.scss +78 -78
  85. package/src/lib/components/Text/README.mdx +3 -3
  86. package/src/lib/components/Text/Text.jsx +16 -9
  87. package/src/lib/components/Text/Text.scss +23 -13
  88. package/src/lib/components/Text/_helpers/getRootClampClassName.js +11 -0
  89. package/src/lib/components/Text/{helpers → _helpers}/getRootHyphensClassName.js +1 -1
  90. package/src/lib/components/Text/{helpers → _helpers}/getRootWordWrappingClassName.js +1 -1
  91. package/src/lib/components/TextArea/README.mdx +1 -1
  92. package/src/lib/components/TextArea/TextArea.jsx +21 -17
  93. package/src/lib/components/TextArea/TextArea.scss +27 -27
  94. package/src/lib/components/TextField/README.mdx +1 -1
  95. package/src/lib/components/TextField/TextField.jsx +19 -18
  96. package/src/lib/components/TextField/TextField.scss +28 -28
  97. package/src/lib/components/TextLink/README.mdx +77 -0
  98. package/src/lib/components/TextLink/TextLink.jsx +44 -0
  99. package/src/lib/components/TextLink/TextLink.scss +11 -0
  100. package/src/lib/components/TextLink/_theme.scss +4 -0
  101. package/src/lib/components/TextLink/index.js +1 -0
  102. package/src/lib/components/Toggle/README.mdx +1 -1
  103. package/src/lib/components/Toggle/Toggle.jsx +21 -20
  104. package/src/lib/components/Toggle/Toggle.scss +20 -20
  105. package/src/lib/components/Toolbar/README.mdx +33 -5
  106. package/src/lib/components/Toolbar/Toolbar.jsx +33 -17
  107. package/src/lib/components/Toolbar/Toolbar.scss +29 -42
  108. package/src/lib/components/Toolbar/ToolbarGroup.jsx +28 -16
  109. package/src/lib/components/Toolbar/ToolbarItem.jsx +36 -10
  110. package/src/lib/{helpers → components/_helpers}/getRootColorClassName.js +1 -1
  111. package/src/lib/{helpers → components/_helpers}/getRootSizeClassName.js +1 -1
  112. package/src/lib/{helpers → components/_helpers}/getRootValidationStateClassName.js +1 -1
  113. package/src/lib/components/_helpers/isChildrenEmpty.js +3 -0
  114. package/src/lib/{helpers → components/_helpers}/resolveContextOrProp.js +0 -0
  115. package/src/lib/{utils → components/_helpers}/transferProps.js +1 -1
  116. package/src/lib/foundation.scss +11 -11
  117. package/src/lib/helpers.scss +2 -2
  118. package/src/lib/index.js +8 -17
  119. package/src/lib/provider/index.js +2 -1
  120. package/src/lib/provider/withGlobalProps.jsx +21 -0
  121. package/src/lib/styles/_utilities.scss +13 -13
  122. package/src/lib/styles/elements/_code.scss +7 -7
  123. package/src/lib/styles/elements/_links.scss +8 -8
  124. package/src/lib/styles/elements/_lists.scss +3 -3
  125. package/src/lib/styles/elements/_page.scss +14 -14
  126. package/src/lib/styles/elements/_rulers.scss +6 -6
  127. package/src/lib/styles/elements/_small.scss +2 -2
  128. package/src/lib/styles/generic/_box-sizing.scss +3 -2
  129. package/src/lib/styles/generic/_forms.scss +3 -3
  130. package/src/lib/styles/generic/_reset.scss +6 -6
  131. package/src/lib/styles/generic/_shared.scss +3 -3
  132. package/src/lib/styles/helpers/_animation.scss +8 -8
  133. package/src/lib/styles/settings/_breakpoints.scss +7 -7
  134. package/src/lib/styles/settings/_escaped-characters.scss +5 -5
  135. package/src/lib/styles/settings/_form-fields.scss +24 -24
  136. package/src/lib/styles/settings/_utilities.scss +112 -100
  137. package/src/lib/styles/theme/_colors.scss +50 -50
  138. package/src/lib/styles/theme/_form-fields.scss +32 -32
  139. package/src/lib/styles/theme/_spacing.scss +11 -11
  140. package/src/lib/styles/theme/_typography.scss +12 -11
  141. package/src/lib/styles/theme-constants/_breakpoints.scss +4 -4
  142. package/src/lib/styles/theme-constants/_colors.scss +2 -2
  143. package/src/lib/styles/theme-constants/_svg.scss +1 -2
  144. package/src/lib/styles/tools/_accessibility.scss +29 -29
  145. package/src/lib/styles/tools/_breakpoint.scss +11 -14
  146. package/src/lib/styles/tools/_caret.scss +8 -8
  147. package/src/lib/styles/tools/_colors.scss +3 -3
  148. package/src/lib/styles/tools/_reset.scss +24 -21
  149. package/src/lib/styles/tools/_scrollbar.scss +4 -4
  150. package/src/lib/styles/tools/_spacing.scss +14 -22
  151. package/src/lib/styles/tools/_string.scss +9 -9
  152. package/src/lib/styles/tools/_svg.scss +13 -16
  153. package/src/lib/styles/tools/_transition.scss +42 -44
  154. package/src/lib/styles/tools/_utilities.scss +19 -19
  155. package/src/lib/styles/tools/form-fields/_box-field-elements.scss +88 -88
  156. package/src/lib/styles/tools/form-fields/_box-field-layout.scss +147 -147
  157. package/src/lib/styles/tools/form-fields/_box-field-sizes.scss +13 -15
  158. package/src/lib/styles/tools/form-fields/_foundation.scss +12 -12
  159. package/src/lib/styles/tools/form-fields/_inline-field-elements.scss +82 -71
  160. package/src/lib/styles/tools/form-fields/_inline-field-layout.scss +88 -47
  161. package/src/lib/styles/tools/form-fields/_variants.scss +104 -106
  162. package/src/lib/theme.scss +959 -954
  163. package/src/lib/utils/classNames.js +8 -0
  164. package/src/lib/components/CTA/CTA.jsx +0 -60
  165. package/src/lib/components/CTA/CTA.scss +0 -71
  166. package/src/lib/components/CTA/CTACenter.jsx +0 -27
  167. package/src/lib/components/CTA/CTAEnd.jsx +0 -27
  168. package/src/lib/components/CTA/CTAStart.jsx +0 -27
  169. package/src/lib/components/CTA/README.mdx +0 -119
  170. package/src/lib/components/CTA/index.js +0 -4
  171. package/src/lib/components/Center/Center.jsx +0 -27
  172. package/src/lib/components/Center/Center.scss +0 -7
  173. package/src/lib/components/Center/README.mdx +0 -52
  174. package/src/lib/components/Center/index.js +0 -1
  175. package/src/lib/components/Link/Link.jsx +0 -45
  176. package/src/lib/components/Link/Link.scss +0 -11
  177. package/src/lib/components/Link/README.mdx +0 -85
  178. package/src/lib/components/Link/_theme.scss +0 -4
  179. package/src/lib/components/Link/index.js +0 -1
  180. package/src/lib/components/List/List.jsx +0 -71
  181. package/src/lib/components/List/List.scss +0 -53
  182. package/src/lib/components/List/ListItem.jsx +0 -31
  183. package/src/lib/components/List/README.mdx +0 -114
  184. package/src/lib/components/List/_theme.scss +0 -1
  185. package/src/lib/components/List/index.js +0 -2
  186. package/src/lib/components/Media/Media.jsx +0 -29
  187. package/src/lib/components/Media/Media.scss +0 -16
  188. package/src/lib/components/Media/MediaBody.jsx +0 -21
  189. package/src/lib/components/Media/MediaObject.jsx +0 -21
  190. package/src/lib/components/Media/README.mdx +0 -63
  191. package/src/lib/components/Media/index.js +0 -3
  192. package/src/lib/provider/withProviderContext.jsx +0 -32
@@ -0,0 +1,46 @@
1
+ import PropTypes from 'prop-types';
2
+ import React from 'react';
3
+ import { withGlobalProps } from '../../provider';
4
+ import withForwardedRef from '../withForwardedRef';
5
+ import styles from './Popover.scss';
6
+
7
+ export const PopoverWrapper = ({
8
+ children,
9
+ id,
10
+ tag: Tag,
11
+ ...restProps
12
+ }) => (
13
+ <Tag
14
+ className={styles.wrapper}
15
+ id={id}
16
+ {...restProps}
17
+ >
18
+ {children}
19
+ </Tag>
20
+ );
21
+
22
+ PopoverWrapper.defaultProps = {
23
+ id: undefined,
24
+ tag: 'div',
25
+ };
26
+
27
+ PopoverWrapper.propTypes = {
28
+ /**
29
+ * Popover reference and the Popover itself.
30
+ */
31
+ children: PropTypes.node.isRequired,
32
+ /**
33
+ * ID of the root HTML element.
34
+ */
35
+ id: PropTypes.string,
36
+ /**
37
+ * HTML tag to render. Can be any valid HTML tag of your choice, usually a
38
+ * [block-level element](https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements).
39
+ */
40
+ tag: PropTypes.string,
41
+ };
42
+
43
+ export const PopoverWrapperWithContext = withForwardedRef(withGlobalProps(PopoverWrapper, 'PopoverWrapper'));
44
+
45
+ export default PopoverWrapperWithContext;
46
+
@@ -0,0 +1,333 @@
1
+ ---
2
+ name: Popover
3
+ menu: 'Miscellaneous'
4
+ route: /components/popover
5
+ ---
6
+
7
+ # Popover
8
+
9
+ import {
10
+ useFloating,
11
+ autoUpdate,
12
+ flip,
13
+ } from '@floating-ui/react-dom'
14
+ import {
15
+ Playground,
16
+ Props,
17
+ } from 'docz'
18
+ import { Placeholder } from '../../../docs/_components/Placeholder/Placeholder'
19
+ import { Button } from '../Button/Button'
20
+ import { ButtonGroup } from '../ButtonGroup/ButtonGroup'
21
+ import { SelectField } from '../SelectField/SelectField'
22
+ import { Toolbar } from '../Toolbar/Toolbar'
23
+ import { ToolbarItem } from '../Toolbar/ToolbarItem'
24
+ import { Popover } from './Popover'
25
+ import { PopoverWrapper } from './PopoverWrapper'
26
+
27
+ Popover displays additional information without interrupting user flow.
28
+
29
+ ## Basic Usage
30
+
31
+ To implement the Popover component, you need to import it first:
32
+
33
+ ```js
34
+ import { Popover, PopoverWrapper } from '@react-ui-org/react-ui';
35
+ ```
36
+
37
+ And use it:
38
+
39
+ <Playground>
40
+ {() => {
41
+ const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);
42
+ // All inline styles in this example are for demonstration purposes only.
43
+ return (
44
+ <div
45
+ style={{
46
+ display: 'grid',
47
+ placeContent: 'center',
48
+ minWidth: '20rem',
49
+ minHeight: '10rem',
50
+ }}
51
+ >
52
+ <PopoverWrapper>
53
+ <Button
54
+ aria-describedby={isPopoverOpen ? 'my-popover' : undefined}
55
+ label="Want to see a popover? Click me!"
56
+ onClick={() => setIsPopoverOpen(!isPopoverOpen)}
57
+ />
58
+ {isPopoverOpen && (
59
+ <Popover id="my-popover">
60
+ Hello there!
61
+ </Popover>
62
+ )}
63
+ </PopoverWrapper>
64
+ </div>
65
+ );
66
+ }}
67
+ </Playground>
68
+
69
+ See [API](#api) for all available options.
70
+
71
+ ## Placement
72
+
73
+ Available placements are: top, right, bottom, and left. Additionally, all basic
74
+ placements can be aligned to the center (default, no suffix), start (e.g.
75
+ `top-start`), or end (e.g. `bottom-end`). Check Popover [API](#api) for the
76
+ complete list of accepted values.
77
+
78
+ <Playground>
79
+ {() => {
80
+ const [align, setAlign] = React.useState('');
81
+ // All inline styles in this example are for demonstration purposes only.
82
+ return (
83
+ <>
84
+ <Toolbar align="baseline">
85
+ <ToolbarItem>
86
+ <span id="alignment-options-label">Alignment:</span>
87
+ </ToolbarItem>
88
+ <ToolbarItem>
89
+ <ButtonGroup aria-labelledby="alignment-options-label">
90
+ <Button
91
+ color={align === '-start' ? 'dark' : 'primary'}
92
+ label="start"
93
+ onClick={() => setAlign('-start')}
94
+ />
95
+ <Button
96
+ color={align === '' ? 'dark' : 'primary'}
97
+ label="center"
98
+ onClick={() => setAlign('')}
99
+ />
100
+ <Button
101
+ color={align === '-end' ? 'dark' : 'primary'}
102
+ label="end"
103
+ onClick={() => setAlign('-end')}
104
+ />
105
+ </ButtonGroup>
106
+ </ToolbarItem>
107
+ </Toolbar>
108
+ <div
109
+ style={{
110
+ display: 'grid',
111
+ placeContent: 'center',
112
+ minWidth: '20rem',
113
+ minHeight: '15rem',
114
+ }}
115
+ >
116
+ <PopoverWrapper>
117
+ <Placeholder bordered aria-describedby="my-popover-top">
118
+ Popovers
119
+ <br />
120
+ all day long…
121
+ </Placeholder>
122
+ <Popover id="my-popover-top" placement={`top${align}`}>
123
+ Top side
124
+ </Popover>
125
+ <Popover id="my-popover-right" placement={`right${align}`}>
126
+ Right side
127
+ </Popover>
128
+ <Popover id="my-popover-bottom" placement={`bottom${align}`}>
129
+ Bottom side
130
+ </Popover>
131
+ <Popover id="my-popover-left" placement={`left${align}`}>
132
+ Left side
133
+ </Popover>
134
+ </PopoverWrapper>
135
+ </div>
136
+ </>
137
+ );
138
+ }}
139
+ </Playground>
140
+
141
+ ## PopoverWrapper
142
+
143
+ PopoverWrapper is an optional wrapper to make positioning of Popover even
144
+ easier.
145
+
146
+ By default, Popover is placed relative to the closest parent element with
147
+ `position: relative` or `position: absolute`. Maybe you already have one of
148
+ these in your CSS. PopoverWrapper is here for situations when you don't.
149
+
150
+ ```jsx
151
+ <PopoverWrapper>
152
+ <Button
153
+ aria-describedby={isPopoverOpen ? 'my-popover' : undefined}
154
+ label="Want to see a popover? Click me!"
155
+ onClick={() => setIsPopoverOpen(!isPopoverOpen)}
156
+ />
157
+ {isPopoverOpen && <Popover id="my-popover">Hello there!</Popover>}
158
+ </PopoverWrapper>
159
+ ```
160
+
161
+ How do you know you may need PopoverWrapper?
162
+
163
+ - You are **not** rendering Popover in a React portal.
164
+ - You are using Popover in a complex layout and it does not pop up where you
165
+ need it.
166
+ - You are using Floating UI with `absolute` positioning strategy (see
167
+ [Advanced Positioning](#advanced-positioning) below) and your Popover keeps to
168
+ be misplaced.
169
+ - You have no idea what CSS `position` is and just want to get it working.
170
+
171
+ To sum it up, usually you will need either PopoverWrapper around your content or
172
+ `position: [ relative | absolute ]` somewhere in your CSS (but you never need
173
+ both!). Nevertheless, in the simplest situations, like in a single-column page
174
+ layout, you may not need either of these at all.
175
+
176
+ Head to PopoverWrapper [API](#popoverwrapper-api) for all available options.
177
+
178
+ ## Advanced Positioning
179
+
180
+ While the basic setup can be sufficient in some scenarios, dropping a Popover
181
+ usually won't be so easy. To handle all tricky situations and edge cases
182
+ automatically, including smart position updates to ensure Popover visibility,
183
+ we recommend to involve an external library designed specifically for this
184
+ purpose.
185
+
186
+ ℹ️ The following example is using external library [Floating UI]. To use
187
+ Floating UI, install it first:
188
+
189
+ ```shell
190
+ npm install --save @floating-ui/react-dom
191
+ ```
192
+
193
+ And import it along with Popover, e.g.:
194
+
195
+ ```js
196
+ import {
197
+ useFloating,
198
+ autoUpdate,
199
+ flip,
200
+ } from '@floating-ui/react-dom';
201
+ import { Popover } from '@react-ui-org/react-ui';
202
+ ```
203
+
204
+ As opposed to the [basic setup](#placement), Popover will be placed according to
205
+ its triggering component (`reference`), but still recognizing the closest parent
206
+ element with `position: relative` or `position: absolute` if there is any.
207
+
208
+ Popover reacts on the `forwardedRef` option, necessary for advanced positioning:
209
+ when `forwardedRef` is set, Popover resets its built-in positioning and relies
210
+ on provided `style`.
211
+
212
+ 👉 Please consult [Floating UI] documentation to understand how it works and to
213
+ get an idea of all possible cases you may need to cover.
214
+
215
+ 🖱 Try scrolling the example to see how Popover placement is updated.
216
+
217
+ <Playground>
218
+ {() => {
219
+ const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);
220
+ const [placement, setPlacement] = React.useState('top');
221
+ const {
222
+ x,
223
+ y,
224
+ reference,
225
+ floating,
226
+ placement: finalPlacement,
227
+ strategy,
228
+ } = useFloating({
229
+ placement,
230
+ middleware: [flip()],
231
+ whileElementsMounted: autoUpdate,
232
+ });
233
+ const placementOptions = [
234
+ 'top',
235
+ 'top-start',
236
+ 'top-end',
237
+ 'right',
238
+ 'right-start',
239
+ 'right-end',
240
+ 'bottom',
241
+ 'bottom-start',
242
+ 'bottom-end',
243
+ 'left',
244
+ 'left-start',
245
+ 'left-end',
246
+ ];
247
+ // All inline styles in this example EXCEPT Popover `style` are for
248
+ // demonstration purposes only.
249
+ return (
250
+ <>
251
+ <Toolbar>
252
+ <ToolbarItem>
253
+ <SelectField
254
+ label="Suggested placement:"
255
+ onChange={e => setPlacement(e.target.value)}
256
+ options={placementOptions.map((el) => ({
257
+ label: el,
258
+ value: el,
259
+ }))}
260
+ value={placement}
261
+ />
262
+ </ToolbarItem>
263
+ <ToolbarItem>
264
+ <div className="mb-2">Final placement:</div>
265
+ <code>{finalPlacement}</code>
266
+ </ToolbarItem>
267
+ </Toolbar>
268
+ <div
269
+ style={{
270
+ width: '40rem',
271
+ maxWidth: '100%',
272
+ height: '10rem',
273
+ overflow: 'auto',
274
+ }}
275
+ >
276
+ <div
277
+ style={{
278
+ position: 'relative',
279
+ width: '60rem',
280
+ height: '20rem',
281
+ paddingBlock: '7rem',
282
+ textAlign: 'center',
283
+ }}
284
+ >
285
+ <Button
286
+ aria-describedby={isPopoverOpen ? 'my-advanced-popover' : undefined}
287
+ forwardedRef={reference}
288
+ label="Trigger Popover"
289
+ onClick={() => setIsPopoverOpen(!isPopoverOpen)}
290
+ />
291
+ {isPopoverOpen && (
292
+ <Popover
293
+ forwardedRef={floating}
294
+ id="my-advanced-popover"
295
+ placement={finalPlacement}
296
+ style={{
297
+ position: strategy,
298
+ top: y ? y : '',
299
+ left: x ? x : '',
300
+ }}
301
+ >
302
+ Auto-flipping Popover
303
+ </Popover>
304
+ )}
305
+ </div>
306
+ </div>
307
+ </>
308
+ );
309
+ }}
310
+ </Playground>
311
+
312
+ ## API
313
+
314
+ <Props table of={Popover} />
315
+
316
+ ### PopoverWrapper API
317
+
318
+ <Props table of={PopoverWrapper} />
319
+
320
+ ## Theming
321
+
322
+ | Custom Property | Description |
323
+ |------------------------------------------------------|--------------------------------------------------------------|
324
+ | `--rui-Popover__width` | Popover width |
325
+ | `--rui-Popover__padding` | Popover padding |
326
+ | `--rui-Popover__border-width` | Border width |
327
+ | `--rui-Popover__border-color` | Border color |
328
+ | `--rui-Popover__border-radius` | Corner radius |
329
+ | `--rui-Popover__color` | Text color |
330
+ | `--rui-Popover__background-color` | Background color |
331
+ | `--rui-Popover__box-shadow` | Popover box shadow |
332
+
333
+ [Floating UI]: https://floating-ui.com/docs/react-dom
@@ -0,0 +1,13 @@
1
+ export default (placement, styles) => {
2
+ const alignment = placement.split('-')[1];
3
+
4
+ if (alignment === 'start') {
5
+ return styles.isRootAtStart;
6
+ }
7
+
8
+ if (alignment === 'end') {
9
+ return styles.isRootAtEnd;
10
+ }
11
+
12
+ return styles.isRootAtCenter;
13
+ };
@@ -0,0 +1,17 @@
1
+ export default (placement, styles) => {
2
+ const side = placement.split('-')[0];
3
+
4
+ if (side === 'top') {
5
+ return styles.isRootAtTop;
6
+ }
7
+
8
+ if (side === 'right') {
9
+ return styles.isRootAtRight;
10
+ }
11
+
12
+ if (side === 'bottom') {
13
+ return styles.isRootAtBottom;
14
+ }
15
+
16
+ return styles.isRootAtLeft;
17
+ };
@@ -0,0 +1,16 @@
1
+ // 1. Height must be linked to width to create 90-degree angle.
2
+
3
+ @use "sass:math";
4
+
5
+ $width: var(--rui-Popover__width);
6
+ $padding: var(--rui-Popover__padding);
7
+ $border-width: var(--rui-Popover__border-width);
8
+ $border-color: var(--rui-Popover__border-color);
9
+ $border-radius: var(--rui-Popover__border-radius);
10
+ $color: var(--rui-Popover__color);
11
+ $background-color: var(--rui-Popover__background-color);
12
+ $box-shadow: var(--rui-Popover__box-shadow);
13
+
14
+ $arrow-width: 1rem;
15
+ $arrow-height: math.div($arrow-width, 2); // 1.
16
+ $arrow-corner-offset: 0.75rem;
@@ -0,0 +1,2 @@
1
+ export { default as Popover } from './Popover';
2
+ export { default as PopoverWrapper } from './PopoverWrapper';
@@ -287,7 +287,7 @@ It's possible to disable just some options or the whole set.
287
287
 
288
288
  In addition to the options below, you can specify [React synthetic events] or
289
289
  any custom HTML attributes that do not interfere with the API, and they will be
290
- passed to the `input` HTML element. This enables making the component
290
+ passed to the `<input>` HTML element. This enables making the component
291
291
  interactive and helps improve its accessibility.
292
292
 
293
293
  <Props table of={Radio} />
@@ -1,9 +1,10 @@
1
1
  import PropTypes from 'prop-types';
2
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';
3
+ import { withGlobalProps } from '../../provider';
4
+ import { classNames } from '../../utils/classNames';
5
+ import { getRootValidationStateClassName } from '../_helpers/getRootValidationStateClassName';
6
+ import { resolveContextOrProp } from '../_helpers/resolveContextOrProp';
7
+ import { transferProps } from '../_helpers/transferProps';
7
8
  import { FormLayoutContext } from '../FormLayout';
8
9
  import styles from './Radio.scss';
9
10
 
@@ -25,23 +26,23 @@ export const Radio = ({
25
26
 
26
27
  return (
27
28
  <div
28
- className={[
29
+ className={classNames(
29
30
  styles.root,
30
- context ? styles.isRootInFormLayout : '',
31
+ context && styles.isRootInFormLayout,
31
32
  resolveContextOrProp(context && context.layout, layout) === 'horizontal'
32
33
  ? styles.rootLayoutHorizontal
33
34
  : styles.rootLayoutVertical,
34
- disabled ? styles.isRootDisabled : '',
35
- required ? styles.isRootRequired : '',
35
+ disabled && styles.isRootDisabled,
36
+ required && styles.isRootRequired,
36
37
  getRootValidationStateClassName(validationState, styles),
37
- ].join(' ')}
38
+ )}
38
39
  id={id}
39
40
  >
40
41
  <div
41
- className={[
42
+ className={classNames(
42
43
  styles.label,
43
- isLabelVisible ? '' : styles.isLabelHidden,
44
- ].join(' ')}
44
+ !isLabelVisible && styles.isLabelHidden,
45
+ )}
45
46
  id={id && `${id}__labelText`}
46
47
  >
47
48
  {label}
@@ -183,6 +184,6 @@ Radio.propTypes = {
183
184
  ]),
184
185
  };
185
186
 
186
- export const RadioWithContext = withProviderContext(Radio, 'Radio');
187
+ export const RadioWithGlobalProps = withGlobalProps(Radio, 'Radio');
187
188
 
188
- export default RadioWithContext;
189
+ export default RadioWithGlobalProps;
@@ -1,78 +1,78 @@
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/inline-field-elements';
5
- @use '../../styles/tools/form-fields/inline-field-layout';
6
- @use '../../styles/tools/form-fields/variants';
7
- @use '../../styles/tools/accessibility';
8
- @use '../../styles/tools/reset';
9
- @use '../../styles/tools/spacing';
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/inline-field-elements";
5
+ @use "../../styles/tools/form-fields/inline-field-layout";
6
+ @use "../../styles/tools/form-fields/variants";
7
+ @use "../../styles/tools/accessibility";
8
+ @use "../../styles/tools/reset";
9
+ @use "../../styles/tools/spacing";
10
10
 
11
11
  // Foundation
12
12
  .root {
13
- @include foundation.root();
14
- @include variants.visual(check);
13
+ @include foundation.root();
14
+ @include variants.visual(check);
15
15
  }
16
16
 
17
17
  .label,
18
18
  .optionLabel {
19
- @include foundation.label();
19
+ @include foundation.label();
20
20
  }
21
21
 
22
22
  .list {
23
- @include reset.list();
23
+ @include reset.list();
24
24
  }
25
25
 
26
26
  .option {
27
- @include inline-field-layout.field();
28
- @include inline-field-elements.min-tap-target($type: radio);
27
+ @include inline-field-layout.field($type: radio);
28
+ @include inline-field-elements.min-tap-target($type: radio);
29
29
  }
30
30
 
31
31
  .input {
32
- @include inline-field-elements.check-input($type: radio);
32
+ @include inline-field-elements.check-input($type: radio);
33
33
  }
34
34
 
35
35
  .helpText,
36
36
  .validationText {
37
- @include foundation.help-text();
37
+ @include foundation.help-text();
38
38
  }
39
39
 
40
40
  .isRootRequired .label {
41
- @include foundation.label-required();
41
+ @include foundation.label-required();
42
42
  }
43
43
 
44
44
  // States
45
45
  .isRootStateInvalid {
46
- @include variants.validation(invalid);
46
+ @include variants.validation(invalid);
47
47
  }
48
48
 
49
49
  .isRootStateValid {
50
- @include variants.validation(valid);
50
+ @include variants.validation(valid);
51
51
  }
52
52
 
53
53
  .isRootStateWarning {
54
- @include variants.validation(warning);
54
+ @include variants.validation(warning);
55
55
  }
56
56
 
57
57
  // Invisible label
58
58
  .isLabelHidden {
59
- @include accessibility.hide-text();
59
+ @include accessibility.hide-text();
60
60
  }
61
61
 
62
62
  // Layouts
63
63
  .rootLayoutVertical,
64
64
  .rootLayoutHorizontal {
65
- @include box-field-layout.vertical($has-list: true);
65
+ @include box-field-layout.vertical($has-list: true);
66
66
  }
67
67
 
68
68
  .rootLayoutHorizontal {
69
- @include box-field-layout.horizontal($has-min-tap-target: true);
69
+ @include box-field-layout.horizontal($has-min-tap-target: true);
70
70
  }
71
71
 
72
72
  .isRootFullWidth {
73
- @include box-field-layout.full-width();
73
+ @include box-field-layout.full-width();
74
74
  }
75
75
 
76
76
  .isRootInFormLayout {
77
- @include box-field-layout.in-form-layout();
77
+ @include box-field-layout.in-form-layout();
78
78
  }
@@ -8,6 +8,9 @@ route: /components/scroll-view
8
8
 
9
9
  ScrollView makes long content scrollable.
10
10
 
11
+ 👉 Please note that HTML is rendered even when no children are provided.
12
+ This is needed to allow the autoscroll feature to work.
13
+
11
14
  import {
12
15
  Playground,
13
16
  Props,
@@ -17,10 +20,7 @@ import Button from '../Button'
17
20
  import Radio from '../Radio'
18
21
  import { Toolbar } from '../Toolbar/Toolbar'
19
22
  import { ToolbarItem } from '../Toolbar/ToolbarItem'
20
- import {
21
- ScrollViewWithContext as ScrollView,
22
- ScrollView as ParsableScrollView,
23
- } from './ScrollView'
23
+ import { ScrollView } from './ScrollView'
24
24
 
25
25
  ## Basic Usage
26
26
 
@@ -430,7 +430,7 @@ we use in the [Modal](/components/modal#scrolling-long-content) component.
430
430
 
431
431
  ## API
432
432
 
433
- <Props table of={ParsableScrollView} />
433
+ <Props table of={ScrollView} />
434
434
 
435
435
  ## Theming
436
436