@react-ui-org/react-ui 0.47.0 → 0.49.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 (142) hide show
  1. package/dist/lib.development.js +465 -93
  2. package/dist/lib.js +1 -1
  3. package/package.json +1 -1
  4. package/src/lib/components/Alert/Alert.jsx +3 -0
  5. package/src/lib/components/Alert/Alert.scss +10 -10
  6. package/src/lib/components/Alert/README.mdx +18 -2
  7. package/src/lib/components/Alert/index.js +1 -1
  8. package/src/lib/components/Badge/Badge.jsx +4 -8
  9. package/src/lib/components/Badge/Badge.scss +21 -21
  10. package/src/lib/components/Badge/README.mdx +15 -1
  11. package/src/lib/components/Badge/index.js +1 -1
  12. package/src/lib/components/Button/Button.jsx +23 -34
  13. package/src/lib/components/Button/README.mdx +21 -7
  14. package/src/lib/components/Button/_base.scss +20 -20
  15. package/src/lib/components/Button/_priorities.scss +35 -35
  16. package/src/lib/components/Button/helpers/getRootLabelVisibilityClassName.js +7 -7
  17. package/src/lib/components/Button/helpers/getRootPriorityClassName.js +3 -3
  18. package/src/lib/components/Button/index.js +1 -1
  19. package/src/lib/components/ButtonGroup/ButtonGroup.jsx +2 -8
  20. package/src/lib/components/ButtonGroup/README.mdx +18 -2
  21. package/src/lib/components/Card/Card.jsx +6 -10
  22. package/src/lib/components/Card/Card.scss +13 -13
  23. package/src/lib/components/Card/CardBody.jsx +6 -10
  24. package/src/lib/components/Card/CardFooter.jsx +6 -7
  25. package/src/lib/components/Card/README.mdx +21 -5
  26. package/src/lib/components/CheckboxField/CheckboxField.jsx +17 -44
  27. package/src/lib/components/CheckboxField/README.mdx +18 -6
  28. package/src/lib/components/CheckboxField/index.js +1 -1
  29. package/src/lib/components/FileInputField/FileInputField.jsx +20 -29
  30. package/src/lib/components/FileInputField/FileInputField.scss +3 -3
  31. package/src/lib/components/FileInputField/README.mdx +30 -28
  32. package/src/lib/components/FileInputField/index.js +1 -1
  33. package/src/lib/components/FormLayout/FormLayout.jsx +5 -9
  34. package/src/lib/components/FormLayout/FormLayout.scss +3 -3
  35. package/src/lib/components/FormLayout/FormLayoutCustomField.jsx +4 -1
  36. package/src/lib/components/FormLayout/FormLayoutCustomField.scss +8 -8
  37. package/src/lib/components/FormLayout/README.mdx +28 -13
  38. package/src/lib/components/Grid/Grid.jsx +31 -35
  39. package/src/lib/components/Grid/Grid.scss +10 -15
  40. package/src/lib/components/Grid/GridSpan.jsx +5 -11
  41. package/src/lib/components/Grid/README.mdx +48 -36
  42. package/src/lib/components/Grid/_helpers/generateResponsiveCustomProperties.js +11 -3
  43. package/src/lib/components/Grid/_settings.scss +18 -0
  44. package/src/lib/components/Grid/_tools.scss +5 -5
  45. package/src/lib/components/Modal/Modal.jsx +147 -254
  46. package/src/lib/components/Modal/Modal.scss +7 -55
  47. package/src/lib/components/Modal/ModalBody.jsx +60 -0
  48. package/src/lib/components/Modal/ModalBody.scss +18 -0
  49. package/src/lib/components/Modal/ModalCloseButton.jsx +45 -0
  50. package/src/lib/components/Modal/ModalCloseButton.scss +18 -0
  51. package/src/lib/components/Modal/ModalContent.jsx +39 -0
  52. package/src/lib/components/Modal/ModalContent.scss +5 -0
  53. package/src/lib/components/Modal/ModalFooter.jsx +42 -0
  54. package/src/lib/components/Modal/ModalFooter.scss +35 -0
  55. package/src/lib/components/Modal/ModalHeader.jsx +44 -0
  56. package/src/lib/components/Modal/ModalHeader.scss +30 -0
  57. package/src/lib/components/Modal/ModalTitle.jsx +44 -0
  58. package/src/lib/components/Modal/ModalTitle.scss +10 -0
  59. package/src/lib/components/Modal/README.mdx +865 -195
  60. package/src/lib/components/Modal/_helpers/getJustifyClassName.js +19 -0
  61. package/src/lib/components/Modal/_helpers/getScrollingClassName.js +11 -0
  62. package/src/lib/components/Modal/_settings.scss +1 -5
  63. package/src/lib/components/Modal/_theme.scss +6 -0
  64. package/src/lib/components/Modal/index.js +7 -1
  65. package/src/lib/components/Paper/Paper.jsx +5 -9
  66. package/src/lib/components/Paper/Paper.scss +2 -2
  67. package/src/lib/components/Paper/README.mdx +15 -1
  68. package/src/lib/components/Paper/index.js +1 -1
  69. package/src/lib/components/Popover/Popover.jsx +14 -30
  70. package/src/lib/components/Popover/Popover.scss +7 -6
  71. package/src/lib/components/Popover/PopoverWrapper.jsx +5 -12
  72. package/src/lib/components/Popover/PopoverWrapper.scss +3 -0
  73. package/src/lib/components/Popover/README.mdx +32 -11
  74. package/src/lib/components/Popover/_theme.scss +1 -1
  75. package/src/lib/components/Radio/README.mdx +13 -6
  76. package/src/lib/components/Radio/Radio.jsx +39 -29
  77. package/src/lib/components/Radio/Radio.scss +3 -3
  78. package/src/lib/components/Radio/index.js +1 -1
  79. package/src/lib/components/ScrollView/README.mdx +165 -84
  80. package/src/lib/components/ScrollView/ScrollView.jsx +115 -117
  81. package/src/lib/components/ScrollView/ScrollView.scss +18 -16
  82. package/src/lib/components/ScrollView/index.js +1 -1
  83. package/src/lib/components/SelectField/README.mdx +83 -7
  84. package/src/lib/components/SelectField/SelectField.jsx +86 -61
  85. package/src/lib/components/SelectField/SelectField.scss +8 -8
  86. package/src/lib/components/SelectField/_components/Option/Option.jsx +46 -0
  87. package/src/lib/components/SelectField/_components/Option/index.js +1 -0
  88. package/src/lib/components/SelectField/index.js +1 -1
  89. package/src/lib/components/Table/README.mdx +25 -9
  90. package/src/lib/components/Table/Table.jsx +43 -101
  91. package/src/lib/components/Table/Table.scss +0 -24
  92. package/src/lib/components/Table/_components/TableBodyCell/TableBodyCell.jsx +46 -0
  93. package/src/lib/components/Table/_components/TableBodyCell/index.js +1 -0
  94. package/src/lib/components/Table/_components/TableCell.scss +25 -0
  95. package/src/lib/components/Table/_components/TableHeaderCell/TableHeaderCell.jsx +71 -0
  96. package/src/lib/components/Table/_components/TableHeaderCell/index.js +1 -0
  97. package/src/lib/components/Table/index.js +1 -1
  98. package/src/lib/components/Tabs/README.mdx +21 -3
  99. package/src/lib/components/Tabs/Tabs.jsx +6 -1
  100. package/src/lib/components/Tabs/TabsItem.jsx +3 -0
  101. package/src/lib/components/Tabs/TabsItem.scss +1 -2
  102. package/src/lib/components/Text/README.mdx +25 -7
  103. package/src/lib/components/Text/Text.jsx +3 -7
  104. package/src/lib/components/Text/Text.scss +6 -6
  105. package/src/lib/components/Text/_helpers/getRootClampClassName.js +2 -2
  106. package/src/lib/components/Text/_helpers/getRootHyphensClassName.js +2 -2
  107. package/src/lib/components/Text/_helpers/getRootWordWrappingClassName.js +2 -2
  108. package/src/lib/components/Text/index.js +1 -1
  109. package/src/lib/components/TextArea/README.mdx +34 -31
  110. package/src/lib/components/TextArea/TextArea.jsx +23 -63
  111. package/src/lib/components/TextArea/TextArea.scss +8 -8
  112. package/src/lib/components/TextArea/index.js +1 -1
  113. package/src/lib/components/TextField/README.mdx +56 -54
  114. package/src/lib/components/TextField/TextField.jsx +25 -52
  115. package/src/lib/components/TextField/TextField.scss +9 -9
  116. package/src/lib/components/TextField/index.js +1 -1
  117. package/src/lib/components/TextLink/README.mdx +13 -6
  118. package/src/lib/components/TextLink/TextLink.jsx +0 -10
  119. package/src/lib/components/TextLink/index.js +1 -1
  120. package/src/lib/components/Toggle/README.mdx +18 -6
  121. package/src/lib/components/Toggle/Toggle.jsx +18 -44
  122. package/src/lib/components/Toggle/index.js +1 -1
  123. package/src/lib/components/Toolbar/README.mdx +21 -6
  124. package/src/lib/components/Toolbar/Toolbar.jsx +9 -43
  125. package/src/lib/components/Toolbar/Toolbar.scss +24 -12
  126. package/src/lib/components/Toolbar/ToolbarGroup.jsx +7 -26
  127. package/src/lib/components/Toolbar/ToolbarItem.jsx +3 -7
  128. package/src/lib/components/Toolbar/_helpers/getAlignClassName.js +19 -0
  129. package/src/lib/components/Toolbar/_helpers/getJustifyClassName.js +16 -0
  130. package/src/lib/components/_helpers/getRootColorClassName.js +10 -10
  131. package/src/lib/components/_helpers/getRootSizeClassName.js +3 -3
  132. package/src/lib/components/_helpers/transferProps.js +1 -1
  133. package/src/lib/index.js +24 -16
  134. package/src/lib/provider/withGlobalProps.jsx +20 -3
  135. package/src/lib/styles/tools/form-fields/_box-field-layout.scss +15 -15
  136. package/src/lib/styles/tools/form-fields/_inline-field-elements.scss +1 -1
  137. package/src/lib/styles/tools/form-fields/_inline-field-layout.scss +9 -9
  138. package/src/lib/theme.scss +18 -26
  139. package/src/lib/translations/en.js +1 -1
  140. package/src/lib/components/Grid/_theme.scss +0 -11
  141. package/src/lib/components/ScrollView/_theme.scss +0 -2
  142. package/src/lib/components/withForwardedRef.jsx +0 -11
@@ -0,0 +1,19 @@
1
+ export const getJustifyClassName = (value, styles) => {
2
+ if (value === 'start') {
3
+ return styles.isRootJustifiedToStart;
4
+ }
5
+
6
+ if (value === 'center') {
7
+ return styles.isRootJustifiedToCenter;
8
+ }
9
+
10
+ if (value === 'end') {
11
+ return styles.isRootJustifiedToEnd;
12
+ }
13
+
14
+ if (value === 'space-between') {
15
+ return styles.isRootJustifiedToSpaceBetween;
16
+ }
17
+
18
+ return styles.isRootJustifiedToStretch;
19
+ };
@@ -0,0 +1,11 @@
1
+ export const getScrollingClassName = (type, styles) => {
2
+ if (type === 'auto') {
3
+ return styles.isRootScrollingAuto;
4
+ }
5
+
6
+ if (type === 'custom') {
7
+ return styles.isRootScrollingCustom;
8
+ }
9
+
10
+ return null;
11
+ };
@@ -2,12 +2,8 @@
2
2
  @use "../../styles/settings/z-indexes";
3
3
  @use "../../styles/theme/borders";
4
4
  @use "../../styles/theme/typography";
5
- @use "../../styles/tools/spacing";
6
5
 
7
- $padding-x: spacing.of(5);
8
- $padding-y: spacing.of(3);
9
- $content-padding-bottom: spacing.of(6);
10
6
  $border-radius: borders.$radius;
11
- $head-title-font-size: map.get(typography.$size-values, 1);
12
7
  $z-index: z-indexes.$modal;
13
8
  $backdrop-z-index: z-indexes.$modal-backdrop;
9
+ $title-font-size: map.get(typography.$size-values, 1);
@@ -1,6 +1,12 @@
1
+ $padding-x: var(--rui-Modal__padding-x);
2
+ $padding-y: var(--rui-Modal__padding-y);
1
3
  $background: var(--rui-Modal__background);
2
4
  $box-shadow: var(--rui-Modal__box-shadow);
5
+ $separator-width: var(--rui-Modal__separator__width);
6
+ $separator-color: var(--rui-Modal__separator__color);
7
+ $header-gap: var(--rui-Modal__header__gap);
3
8
  $footer-background: var(--rui-Modal__footer__background);
9
+ $footer-gap: var(--rui-Modal__footer__gap);
4
10
  $backdrop-background: var(--rui-Modal__backdrop__background);
5
11
  $outer-spacing-xs: var(--rui-Modal__outer-spacing--xs);
6
12
  $outer-spacing-sm: var(--rui-Modal__outer-spacing--sm);
@@ -1 +1,7 @@
1
- export { default } from './Modal';
1
+ export { default as Modal } from './Modal';
2
+ export { default as ModalBody } from './ModalBody';
3
+ export { default as ModalCloseButton } from './ModalCloseButton';
4
+ export { default as ModalContent } from './ModalContent';
5
+ export { default as ModalHeader } from './ModalHeader';
6
+ export { default as ModalFooter } from './ModalFooter';
7
+ export { default as ModalTitle } from './ModalTitle';
@@ -2,28 +2,28 @@ import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
3
  import { withGlobalProps } from '../../provider';
4
4
  import { classNames } from '../../utils/classNames';
5
+ import { transferProps } from '../_helpers/transferProps';
5
6
  import styles from './Paper.scss';
6
7
 
7
8
  export const Paper = ({
8
9
  children,
9
- id,
10
10
  muted,
11
11
  raised,
12
+ ...restProps
12
13
  }) => (
13
14
  <div
15
+ {...transferProps(restProps)}
14
16
  className={classNames(
15
17
  styles.root,
16
- muted && styles.rootMuted,
17
- raised && styles.rootRaised,
18
+ muted && styles.isRootMuted,
19
+ raised && styles.isRootRaised,
18
20
  )}
19
- id={id}
20
21
  >
21
22
  {children}
22
23
  </div>
23
24
  );
24
25
 
25
26
  Paper.defaultProps = {
26
- id: undefined,
27
27
  muted: false,
28
28
  raised: false,
29
29
  };
@@ -33,10 +33,6 @@ Paper.propTypes = {
33
33
  * Content to be placed onto Paper.
34
34
  */
35
35
  children: PropTypes.node.isRequired,
36
- /**
37
- * ID of the root HTML element.
38
- */
39
- id: PropTypes.string,
40
36
  /**
41
37
  * Visually suppress Paper.
42
38
  */
@@ -7,11 +7,11 @@
7
7
  background-color: theme.$background-color;
8
8
  }
9
9
 
10
- .rootMuted {
10
+ .isRootMuted {
11
11
  background-color: theme.$muted-background-color;
12
12
  opacity: theme.$muted-opacity;
13
13
  }
14
14
 
15
- .rootRaised {
15
+ .isRootRaised {
16
16
  box-shadow: theme.$raised-box-shadow;
17
17
  }
@@ -10,7 +10,7 @@ import {
10
10
  Playground,
11
11
  Props,
12
12
  } from 'docz'
13
- import { Paper } from './Paper'
13
+ import { Paper } from '../..'
14
14
 
15
15
  Paper is a basic surface to hold content.
16
16
 
@@ -63,6 +63,17 @@ Dim background and add transparency to visually suppress the Paper.
63
63
  </Paper>
64
64
  </Playground>
65
65
 
66
+ ## Forwarding HTML Attributes
67
+
68
+ In addition to the options below in the [component's API](#api) section, you
69
+ can specify [React synthetic events] or **any HTML attribute you like.** All
70
+ attributes that don't interfere with the API are forwarded to the root `<div>`
71
+ HTML element. This enables making the component interactive and helps to improve
72
+ its accessibility.
73
+
74
+ 👉 Refer to the MDN reference for the full list of supported attributes of the
75
+ [div] element.
76
+
66
77
  ## API
67
78
 
68
79
  <Props table of={Paper} />
@@ -79,3 +90,6 @@ Dim background and add transparency to visually suppress the Paper.
79
90
  | `--rui-Paper--muted__background-color` | Background color of muted paper |
80
91
  | `--rui-Paper--muted__opacity` | Opacity of muted paper |
81
92
  | `--rui-Paper--raised__box-shadow` | Box shadow of raised paper |
93
+
94
+ [React synthetic events]: https://reactjs.org/docs/events.html
95
+ [div]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes
@@ -1 +1 @@
1
- export { default } from './Paper';
1
+ export { default as Paper } from './Paper';
@@ -4,30 +4,28 @@ import { createPortal } from 'react-dom';
4
4
  import { withGlobalProps } from '../../provider';
5
5
  import { classNames } from '../../utils/classNames';
6
6
  import { transferProps } from '../_helpers/transferProps';
7
- import withForwardedRef from '../withForwardedRef';
8
7
  import getRootSideClassName from './_helpers/getRootSideClassName';
9
8
  import getRootAlignmentClassName from './_helpers/getRootAlignmentClassName';
10
9
  import styles from './Popover.scss';
11
10
 
12
- export const Popover = ({
13
- forwardedRef,
14
- placement,
15
- children,
16
- id,
17
- portalId,
18
- ...restProps
19
- }) => {
11
+ export const Popover = React.forwardRef((props, ref) => {
12
+ const {
13
+ placement,
14
+ children,
15
+ portalId,
16
+ ...restProps
17
+ } = props;
18
+
20
19
  const PopoverEl = (
21
20
  <div
21
+ {...transferProps(restProps)}
22
22
  className={classNames(
23
23
  styles.root,
24
- forwardedRef && styles.isRootControlled,
24
+ ref && styles.isRootControlled,
25
25
  getRootSideClassName(placement, styles),
26
26
  getRootAlignmentClassName(placement, styles),
27
27
  )}
28
- id={id}
29
- ref={forwardedRef}
30
- {...transferProps(restProps)}
28
+ ref={ref}
31
29
  >
32
30
  {children}
33
31
  <span className={styles.arrow} />
@@ -39,11 +37,9 @@ export const Popover = ({
39
37
  }
40
38
 
41
39
  return createPortal(PopoverEl, document.getElementById(portalId));
42
- };
40
+ });
43
41
 
44
42
  Popover.defaultProps = {
45
- forwardedRef: undefined,
46
- id: undefined,
47
43
  placement: 'bottom',
48
44
  portalId: null,
49
45
  };
@@ -53,18 +49,6 @@ Popover.propTypes = {
53
49
  * Popover content.
54
50
  */
55
51
  children: PropTypes.node.isRequired,
56
- /**
57
- * Reference forwarded to the root `div` element.
58
- */
59
- forwardedRef: PropTypes.oneOfType([
60
- PropTypes.func,
61
- // eslint-disable-next-line react/forbid-prop-types
62
- PropTypes.shape({ current: PropTypes.any }),
63
- ]),
64
- /**
65
- * ID of the root HTML element.
66
- */
67
- id: PropTypes.string,
68
52
  /**
69
53
  * Popover placement affects position of the arrow.
70
54
  * Compatible with [Floating UI API](https://floating-ui.com/docs/computePosition#placement).
@@ -89,6 +73,6 @@ Popover.propTypes = {
89
73
  portalId: PropTypes.string,
90
74
  };
91
75
 
92
- export const PopoverWithContext = withForwardedRef(withGlobalProps(Popover, 'Popover'));
76
+ export const PopoverWithGlobalProps = withGlobalProps(Popover, 'Popover');
93
77
 
94
- export default PopoverWithContext;
78
+ export default PopoverWithGlobalProps;
@@ -4,14 +4,15 @@
4
4
 
5
5
  @use "theme";
6
6
 
7
- .wrapper {
8
- position: relative;
9
- }
10
-
11
7
  .root {
12
8
  position: absolute;
13
- width: theme.$width;
9
+ width: max-content;
10
+ max-width: theme.$max-width;
14
11
  padding: theme.$padding;
12
+ text-align: left;
13
+ white-space: normal;
14
+ word-break: normal;
15
+ word-wrap: break-word;
15
16
  color: theme.$color;
16
17
  border: theme.$border-width solid theme.$border-color;
17
18
  border-radius: theme.$border-radius;
@@ -205,7 +206,7 @@
205
206
  transform: translate(0, -100%) rotateZ(90deg);
206
207
  }
207
208
 
208
- // Controlled
209
+ // Controlled placement
209
210
  .isRootControlled.isRootAtTop,
210
211
  .isRootControlled.isRootAtBottom,
211
212
  .isRootControlled.isRootAtLeft,
@@ -1,26 +1,23 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
3
  import { withGlobalProps } from '../../provider';
4
- import withForwardedRef from '../withForwardedRef';
5
- import styles from './Popover.scss';
4
+ import { transferProps } from '../_helpers/transferProps';
5
+ import styles from './PopoverWrapper.scss';
6
6
 
7
7
  export const PopoverWrapper = ({
8
8
  children,
9
- id,
10
9
  tag: Tag,
11
10
  ...restProps
12
11
  }) => (
13
12
  <Tag
14
- className={styles.wrapper}
15
- id={id}
16
- {...restProps}
13
+ {...transferProps(restProps)}
14
+ className={styles.root}
17
15
  >
18
16
  {children}
19
17
  </Tag>
20
18
  );
21
19
 
22
20
  PopoverWrapper.defaultProps = {
23
- id: undefined,
24
21
  tag: 'div',
25
22
  };
26
23
 
@@ -29,10 +26,6 @@ PopoverWrapper.propTypes = {
29
26
  * Popover reference and the Popover itself.
30
27
  */
31
28
  children: PropTypes.node.isRequired,
32
- /**
33
- * ID of the root HTML element.
34
- */
35
- id: PropTypes.string,
36
29
  /**
37
30
  * HTML tag to render. Can be any valid HTML tag of your choice, usually a
38
31
  * [block-level element](https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements).
@@ -40,7 +33,7 @@ PopoverWrapper.propTypes = {
40
33
  tag: PropTypes.string,
41
34
  };
42
35
 
43
- export const PopoverWrapperWithContext = withForwardedRef(withGlobalProps(PopoverWrapper, 'PopoverWrapper'));
36
+ export const PopoverWrapperWithContext = withGlobalProps(PopoverWrapper, 'PopoverWrapper');
44
37
 
45
38
  export default PopoverWrapperWithContext;
46
39
 
@@ -0,0 +1,3 @@
1
+ .root {
2
+ position: relative;
3
+ }
@@ -16,13 +16,15 @@ import {
16
16
  Props,
17
17
  } from 'docz'
18
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'
19
+ import {
20
+ Button,
21
+ Popover,
22
+ ButtonGroup,
23
+ SelectField,
24
+ Toolbar,
25
+ ToolbarItem,
26
+ PopoverWrapper,
27
+ } from '../..'
26
28
 
27
29
  Popover displays additional information without interrupting user flow.
28
30
 
@@ -205,8 +207,8 @@ As opposed to the [basic setup](#placement), Popover will be placed according to
205
207
  its triggering component (`reference`), but still recognizing the closest parent
206
208
  element with `position: relative` or `position: absolute` if there is any.
207
209
 
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
+ Popover reacts on the `ref` option, necessary for advanced positioning:
211
+ when `ref` is set, Popover resets its built-in positioning and relies
210
212
  on provided `style`.
211
213
 
212
214
  👉 Please consult [Floating UI] documentation to understand how it works and to
@@ -284,13 +286,12 @@ get an idea of all possible cases you may need to cover.
284
286
  >
285
287
  <Button
286
288
  aria-describedby={isPopoverOpen ? 'my-advanced-popover' : undefined}
287
- forwardedRef={reference}
288
289
  label="Trigger Popover"
289
290
  onClick={() => setIsPopoverOpen(!isPopoverOpen)}
291
+ ref={reference}
290
292
  />
291
293
  {isPopoverOpen && (
292
294
  <Popover
293
- forwardedRef={floating}
294
295
  id="my-advanced-popover"
295
296
  placement={finalPlacement}
296
297
  style={{
@@ -298,6 +299,7 @@ get an idea of all possible cases you may need to cover.
298
299
  top: y ? y : '',
299
300
  left: x ? x : '',
300
301
  }}
302
+ ref={floating}
301
303
  >
302
304
  Auto-flipping Popover
303
305
  </Popover>
@@ -309,6 +311,22 @@ get an idea of all possible cases you may need to cover.
309
311
  }}
310
312
  </Playground>
311
313
 
314
+ ## Forwarding HTML Attributes
315
+
316
+ In addition to the options below in the [component's API](#api) section, you
317
+ can specify [React synthetic events] or **any HTML attribute you like.** All
318
+ attributes that don't interfere with the API are forwarded to the root `<div>`
319
+ HTML element. This enables making the component interactive and helps to improve
320
+ its accessibility.
321
+
322
+ 👉 Refer to the MDN reference for the full list of supported attributes of the
323
+ [div] element.
324
+
325
+ ## Forwarding ref
326
+
327
+ If you provide [ref], it is forwarded to the root native HTML `<div>` element,
328
+ which enables [Advanced Positioning](#advanced-positioning).
329
+
312
330
  ## API
313
331
 
314
332
  <Props table of={Popover} />
@@ -331,3 +349,6 @@ get an idea of all possible cases you may need to cover.
331
349
  | `--rui-Popover__box-shadow` | Popover box shadow |
332
350
 
333
351
  [Floating UI]: https://floating-ui.com/docs/react-dom
352
+ [React synthetic events]: https://reactjs.org/docs/events.html
353
+ [div]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes
354
+ [ref]: https://reactjs.org/docs/refs-and-the-dom.html
@@ -2,7 +2,7 @@
2
2
 
3
3
  @use "sass:math";
4
4
 
5
- $width: var(--rui-Popover__width);
5
+ $max-width: var(--rui-Popover__max-width);
6
6
  $padding: var(--rui-Popover__padding);
7
7
  $border-width: var(--rui-Popover__border-width);
8
8
  $border-color: var(--rui-Popover__border-color);
@@ -12,7 +12,7 @@ import {
12
12
  Playground,
13
13
  Props,
14
14
  } from 'docz'
15
- import { Radio } from './Radio'
15
+ import { Radio } from '../..'
16
16
 
17
17
  ## Basic Usage
18
18
 
@@ -283,12 +283,18 @@ It's possible to disable just some options or the whole set.
283
283
  }}
284
284
  </Playground>
285
285
 
286
- ## API
286
+ ## Forwarding HTML Attributes
287
+
288
+ In addition to the options below in the [component's API](#api) section, you
289
+ can specify [React synthetic events] or you can **add whatever HTML attribute
290
+ you like.** All attributes that don't interfere with the API are forwarded to
291
+ the native HTML `<input>`. This enables making the component interactive and helps
292
+ to improve its accessibility.
287
293
 
288
- In addition to the options below, you can specify [React synthetic events] or
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
291
- interactive and helps improve its accessibility.
294
+ 👉 Refer to the MDN reference for the full list of supported attributes of the
295
+ [radio] input type.
296
+
297
+ ## API
292
298
 
293
299
  <Props table of={Radio} />
294
300
 
@@ -303,3 +309,4 @@ options. On top of that, the following options are available for Radio.
303
309
  | `--rui-FormField--check__input--radio--checked__background-image` | Checked input background image (inline, URL, …) |
304
310
 
305
311
  [React synthetic events]: https://reactjs.org/docs/events.html
312
+ [radio]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio#additional_attributes
@@ -30,8 +30,8 @@ export const Radio = ({
30
30
  styles.root,
31
31
  context && styles.isRootInFormLayout,
32
32
  resolveContextOrProp(context && context.layout, layout) === 'horizontal'
33
- ? styles.rootLayoutHorizontal
34
- : styles.rootLayoutVertical,
33
+ ? styles.isRootLayoutHorizontal
34
+ : styles.isRootLayoutVertical,
35
35
  disabled && styles.isRootDisabled,
36
36
  required && styles.isRootRequired,
37
37
  getRootValidationStateClassName(validationState, styles),
@@ -50,34 +50,37 @@ export const Radio = ({
50
50
  <div className={styles.field}>
51
51
  <ul className={styles.list}>
52
52
  {
53
- options.map((option) => (
54
- <li key={option.value}>
55
- <label
56
- className={styles.option}
57
- htmlFor={id && `${id}__item__${option.value}`}
58
- id={id && `${id}__item__${option.value}__label`}
59
- >
60
- <input
61
- {...transferProps(restProps)}
62
- className={styles.input}
63
- checked={restProps.onChange
64
- ? (value === option.value) || false
65
- : undefined}
66
- disabled={disabled || option.disabled}
67
- id={id && `${id}__item__${option.value}`}
68
- name={id}
69
- type="radio"
70
- value={option.value}
71
- />
72
- <span
73
- className={styles.optionLabel}
74
- id={id && `${id}__item__${option.value}__labelText`}
53
+ options.map((option) => {
54
+ const key = option.key ?? option.value;
55
+ return (
56
+ <li key={key}>
57
+ <label
58
+ className={styles.option}
59
+ htmlFor={id && `${id}__item__${key}`}
60
+ id={id && `${id}__item__${key}__label`}
75
61
  >
76
- { option.label }
77
- </span>
78
- </label>
79
- </li>
80
- ))
62
+ <input
63
+ {...transferProps(restProps)}
64
+ className={styles.input}
65
+ checked={restProps.onChange
66
+ ? (value === option.value) || false
67
+ : undefined}
68
+ disabled={disabled || option.disabled}
69
+ id={id && `${id}__item__${key}`}
70
+ name={id}
71
+ type="radio"
72
+ value={option.value}
73
+ />
74
+ <span
75
+ className={styles.optionLabel}
76
+ id={id && `${id}__item__${key}__labelText`}
77
+ >
78
+ { option.label }
79
+ </span>
80
+ </label>
81
+ </li>
82
+ );
83
+ })
81
84
  }
82
85
  </ul>
83
86
  {helpText && (
@@ -134,6 +137,9 @@ Radio.propTypes = {
134
137
  * * `<ID>__item__<VALUE>`
135
138
  * * `<ID>__item__<VALUE>__label`
136
139
  * * `<ID>__item__<VALUE>__labelText`
140
+ *
141
+ * If `key` in the option definition object is set,
142
+ * then `option.key` is used instead of `option.value` in place of `<VALUE>`.
137
143
  */
138
144
  id: PropTypes.string,
139
145
  /**
@@ -154,9 +160,13 @@ Radio.propTypes = {
154
160
  layout: PropTypes.oneOf(['horizontal', 'vertical']),
155
161
  /**
156
162
  * Set of options to be chosen from.
163
+ *
164
+ * For generating unique IDs the `option.value` is normally used. For cases when this is not practical or
165
+ * the `option.value` values are not unique the `option.key` attribute can be set manually.
157
166
  */
158
167
  options: PropTypes.arrayOf(PropTypes.shape({
159
168
  disabled: PropTypes.bool,
169
+ key: PropTypes.string,
160
170
  label: PropTypes.string.isRequired,
161
171
  value: PropTypes.oneOfType([
162
172
  PropTypes.string,
@@ -60,12 +60,12 @@
60
60
  }
61
61
 
62
62
  // Layouts
63
- .rootLayoutVertical,
64
- .rootLayoutHorizontal {
63
+ .isRootLayoutVertical,
64
+ .isRootLayoutHorizontal {
65
65
  @include box-field-layout.vertical($has-list: true);
66
66
  }
67
67
 
68
- .rootLayoutHorizontal {
68
+ .isRootLayoutHorizontal {
69
69
  @include box-field-layout.horizontal($has-min-tap-target: true);
70
70
  }
71
71
 
@@ -1 +1 @@
1
- export { default } from './Radio';
1
+ export { default as Radio } from './Radio';