@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,71 @@
1
+ import PropTypes from 'prop-types';
2
+ import React from 'react';
3
+ import { Button } from '../../../..';
4
+ import styles from '../TableCell.scss';
5
+
6
+ export const TableHeaderCell = ({
7
+ column,
8
+ id,
9
+ sort,
10
+ }) => {
11
+ const sortDirection = sort && column.name === sort.column ? sort.direction : 'asc';
12
+ const isSortingActive = sort && column.name === sort.column;
13
+
14
+ return (
15
+ <th
16
+ className={isSortingActive ? styles.isTableHeadCellSortingActive : styles.tableHeadCell}
17
+ id={id}
18
+ >
19
+ {sort && column.isSortable && (
20
+ <div className={styles.sortButton}>
21
+ <Button
22
+ beforeLabel={
23
+ sortDirection === 'asc'
24
+ ? sort.ascendingIcon
25
+ : sort.descendingIcon
26
+ }
27
+ id={id && `${id}__sortButton`}
28
+ label={sortDirection}
29
+ labelVisibility="none"
30
+ onClick={() => sort.onClick(column.name, sortDirection)}
31
+ priority="flat"
32
+ />
33
+ </div>
34
+ )}
35
+ {column.label}
36
+ </th>
37
+ );
38
+ };
39
+
40
+ TableHeaderCell.defaultProps = {
41
+ id: undefined,
42
+ sort: null,
43
+ };
44
+
45
+ TableHeaderCell.propTypes = {
46
+ /**
47
+ * Table data column, optionally sortable. The `format` function can be used to process the
48
+ * column data before displaying them.
49
+ */
50
+ column: PropTypes.shape({
51
+ isSortable: PropTypes.bool,
52
+ label: PropTypes.string,
53
+ name: PropTypes.string.isRequired,
54
+ }).isRequired,
55
+ /**
56
+ * ID of the HTML <th> element and nested button for sorting.
57
+ */
58
+ id: PropTypes.string,
59
+ /**
60
+ * Sorting configuration required to make columns sortable.
61
+ */
62
+ sort: PropTypes.shape({
63
+ ascendingIcon: PropTypes.node.isRequired,
64
+ column: PropTypes.string.isRequired,
65
+ descendingIcon: PropTypes.node.isRequired,
66
+ direction: PropTypes.oneOf(['asc', 'desc']).isRequired,
67
+ onClick: PropTypes.func.isRequired,
68
+ }),
69
+ };
70
+
71
+ export default TableHeaderCell;
@@ -0,0 +1 @@
1
+ export { default as TableHeaderCell } from './TableHeaderCell';
@@ -1 +1 @@
1
- export { default } from './Table';
1
+ export { default as Table } from './Table';
@@ -11,9 +11,11 @@ import {
11
11
  Props,
12
12
  } from 'docz'
13
13
  import { Icon } from '../../../docs/_components/Icon/Icon'
14
- import ScrollView from '../ScrollView'
15
- import { Tabs } from './Tabs'
16
- import { TabsItem } from './TabsItem'
14
+ import {
15
+ ScrollView,
16
+ Tabs,
17
+ TabsItem,
18
+ } from '../..'
17
19
 
18
20
  Tabs separate related content into groups within a single context.
19
21
 
@@ -169,6 +171,18 @@ accessible no matter the space they have around. Wrap Tabs into
169
171
  }}
170
172
  </Playground>
171
173
 
174
+ ## Forwarding HTML Attributes
175
+
176
+ In addition to the options below in the [component's API](#api) section, you
177
+ can specify [React synthetic events] or **any HTML attribute you like.** All
178
+ attributes that don't interfere with the API are forwarded to the `<nav>` HTML
179
+ element in case of `Tabs` component and to the `<li>` HTML element in
180
+ case of `TabsItem`. This enables making the component interactive and helps
181
+ to improve its accessibility.
182
+
183
+ 👉 Refer to the MDN reference for the full list of supported attributes of the
184
+ [nav] and [li] element.
185
+
172
186
  ## API
173
187
 
174
188
  <Props table of={Tabs} />
@@ -218,3 +232,7 @@ Where:
218
232
  - `<PROPERTY>` is one of `font-weight`, `color`, `border-width`, `border-color`,
219
233
  `background-color`, `box-shadow`, `shift-y` (shifts vertically the whole
220
234
  item), or `label__shift-y` (tweaks vertical position of tab label).
235
+
236
+ [React synthetic events]: https://reactjs.org/docs/events.html
237
+ [nav]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/nav#attributes
238
+ [li]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/li#attributes
@@ -1,13 +1,18 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
3
  import { withGlobalProps } from '../../provider';
4
+ import { transferProps } from '../_helpers/transferProps';
4
5
  import styles from './Tabs.scss';
5
6
 
6
7
  export const Tabs = ({
7
8
  children,
8
9
  id,
10
+ ...restProps
9
11
  }) => (
10
- <nav id={id}>
12
+ <nav
13
+ {...transferProps(restProps)}
14
+ id={id}
15
+ >
11
16
  <ul
12
17
  className={styles.list}
13
18
  id={id && `${id}__list`}
@@ -1,6 +1,7 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
3
  import { withGlobalProps } from '../../provider';
4
+ import { transferProps } from '../_helpers/transferProps';
4
5
  import { classNames } from '../../utils/classNames';
5
6
  import styles from './TabsItem.scss';
6
7
 
@@ -12,8 +13,10 @@ export const TabsItem = ({
12
13
  isActive,
13
14
  label,
14
15
  onClick,
16
+ ...restProps
15
17
  }) => (
16
18
  <li
19
+ {...transferProps(restProps)}
17
20
  className={classNames(
18
21
  styles.root,
19
22
  isActive && styles.isRootActive,
@@ -47,8 +47,7 @@
47
47
  line-height: 1;
48
48
  text-decoration: none;
49
49
  color: theme.$item-color;
50
- border-width: theme.$item-border-width;
51
- border-style: solid;
50
+ border: theme.$item-border-width solid;
52
51
  border-color: theme.$item-border-color;
53
52
  border-top-left-radius: theme.$item-border-radius;
54
53
  border-top-right-radius: theme.$item-border-radius;
@@ -11,13 +11,15 @@ import {
11
11
  Props,
12
12
  } from 'docz'
13
13
  import { Placeholder } from '../../../docs/_components/Placeholder/Placeholder'
14
- import { Toolbar } from '../Toolbar/Toolbar'
15
- import { ToolbarGroup } from '../Toolbar/ToolbarGroup'
16
- import { ToolbarItem } from '../Toolbar/ToolbarItem'
17
- import { Button } from '../Button/Button'
18
- import { ButtonGroup } from '../ButtonGroup/ButtonGroup'
19
- import { TextField } from '../TextField/TextField'
20
- import { Text } from './Text'
14
+ import {
15
+ Button,
16
+ ButtonGroup,
17
+ Text,
18
+ TextField,
19
+ Toolbar,
20
+ ToolbarGroup,
21
+ ToolbarItem,
22
+ } from '../..'
21
23
 
22
24
  Text is a tiny component to control wrapping of text content.
23
25
 
@@ -212,6 +214,22 @@ will override automatic break point selection in `auto` mode when present.
212
214
  }}
213
215
  </Playground>
214
216
 
217
+ ## Forwarding HTML Attributes
218
+
219
+ In addition to the options below in the [component's API](#api) section, you
220
+ can specify [React synthetic events] or **any HTML attribute you like.** All
221
+ attributes that don't interfere with the API are forwarded either to the
222
+ `<span>` or to the `<div>` HTML element in case that `blockLevel` is set to
223
+ `true`. This enables making the component interactive and helps to improve its
224
+ accessibility.
225
+
226
+ 👉 Refer to the MDN reference for the full list of supported attributes of the
227
+ [span] and [div] element.
228
+
215
229
  ## API
216
230
 
217
231
  <Props table of={Text} />
232
+
233
+ [React synthetic events]: https://reactjs.org/docs/events.html
234
+ [span]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/span#attributes
235
+ [div]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes
@@ -1,6 +1,7 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
3
  import { withGlobalProps } from '../../provider';
4
+ import { transferProps } from '../_helpers/transferProps';
4
5
  import { classNames } from '../../utils/classNames';
5
6
  import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
6
7
  import { getRootClampClassName } from './_helpers/getRootClampClassName';
@@ -12,9 +13,9 @@ export const Text = ({
12
13
  blockLevel,
13
14
  children,
14
15
  hyphens,
15
- id,
16
16
  lines,
17
17
  wordWrapping,
18
+ ...restProps
18
19
  }) => {
19
20
  if (isChildrenEmpty(children)) {
20
21
  return null;
@@ -24,6 +25,7 @@ export const Text = ({
24
25
 
25
26
  return (
26
27
  <HtmlElement
28
+ {...transferProps(restProps)}
27
29
  className={(hyphens !== 'none' || lines > 0 || wordWrapping !== 'normal')
28
30
  ? classNames(
29
31
  getRootClampClassName(lines, styles),
@@ -31,7 +33,6 @@ export const Text = ({
31
33
  getRootWordWrappingClassName(wordWrapping, styles),
32
34
  )
33
35
  : undefined}
34
- id={id}
35
36
  style={(lines > 1) ? { '--rui-custom-lines': lines } : undefined}
36
37
  >
37
38
  {children}
@@ -43,7 +44,6 @@ Text.defaultProps = {
43
44
  blockLevel: false,
44
45
  children: null,
45
46
  hyphens: 'none',
46
- id: undefined,
47
47
  lines: undefined,
48
48
  wordWrapping: 'normal',
49
49
  };
@@ -61,10 +61,6 @@ Text.propTypes = {
61
61
  * Turn on hyphenation. Head to [Hyphens](#hyphens) to learn more.
62
62
  */
63
63
  hyphens: PropTypes.oneOf(['none', 'auto', 'manual']),
64
- /**
65
- * Optional ID of the root HTML element.
66
- */
67
- id: PropTypes.string,
68
64
  /**
69
65
  * Optional number of lines. If exceeded, the content is truncated and appended by an ellipsis (`…`).
70
66
  */
@@ -5,7 +5,7 @@
5
5
  // 2. Different approaches are used for single and multiline texts because the latter approach
6
6
  // doesn't always work for single-line texts.
7
7
 
8
- .rootClampSingleLine {
8
+ .isRootClampSingleLine {
9
9
  display: block; // 2.
10
10
  overflow: hidden;
11
11
  text-overflow: ellipsis;
@@ -13,7 +13,7 @@
13
13
  }
14
14
 
15
15
  // stylelint-disable property-no-vendor-prefix, value-no-vendor-prefix
16
- .rootClampMultiLine {
16
+ .isRootClampMultiLine {
17
17
  display: -webkit-box; // 2.
18
18
  -webkit-line-clamp: var(--rui-custom-lines);
19
19
  -webkit-box-orient: vertical;
@@ -22,19 +22,19 @@
22
22
  }
23
23
  // stylelint-enable property-no-vendor-prefix, value-no-vendor-prefix
24
24
 
25
- .rootHyphensAuto {
25
+ .isRootHyphensAuto {
26
26
  hyphens: auto;
27
27
  }
28
28
 
29
- .rootHyphensManual {
29
+ .isRootHyphensManual {
30
30
  hyphens: manual;
31
31
  }
32
32
 
33
- .rootWordWrappingAnywhere {
33
+ .isRootWordWrappingAnywhere {
34
34
  word-break: break-all;
35
35
  }
36
36
 
37
- .rootWordWrappingLongWords {
37
+ .isRootWordWrappingLongWords {
38
38
  word-break: break-word; // 1.
39
39
  overflow-wrap: anywhere;
40
40
  }
@@ -1,10 +1,10 @@
1
1
  export const getRootClampClassName = (lines, styles) => {
2
2
  if (lines === 1) {
3
- return styles.rootClampSingleLine;
3
+ return styles.isRootClampSingleLine;
4
4
  }
5
5
 
6
6
  if (lines > 1) {
7
- return styles.rootClampMultiLine;
7
+ return styles.isRootClampMultiLine;
8
8
  }
9
9
 
10
10
  return null;
@@ -1,10 +1,10 @@
1
1
  export const getRootHyphensClassName = (hyphens, styles) => {
2
2
  if (hyphens === 'auto') {
3
- return styles.rootHyphensAuto;
3
+ return styles.isRootHyphensAuto;
4
4
  }
5
5
 
6
6
  if (hyphens === 'manual') {
7
- return styles.rootHyphensManual;
7
+ return styles.isRootHyphensManual;
8
8
  }
9
9
 
10
10
  return null;
@@ -1,10 +1,10 @@
1
1
  export const getRootWordWrappingClassName = (wordWrapping, styles) => {
2
2
  if (wordWrapping === 'anywhere') {
3
- return styles.rootWordWrappingAnywhere;
3
+ return styles.isRootWordWrappingAnywhere;
4
4
  }
5
5
 
6
6
  if (wordWrapping === 'long-words') {
7
- return styles.rootWordWrappingLongWords;
7
+ return styles.isRootWordWrappingLongWords;
8
8
  }
9
9
 
10
10
  return null;
@@ -1 +1 @@
1
- export { default } from './Text';
1
+ export { default as Text } from './Text';
@@ -12,7 +12,7 @@ import {
12
12
  Playground,
13
13
  Props,
14
14
  } from 'docz'
15
- import { TextArea } from './TextArea'
15
+ import { TextArea } from '../..'
16
16
 
17
17
  ## Basic Usage
18
18
 
@@ -142,31 +142,6 @@ to achieve that effect.
142
142
  />
143
143
  </Playground>
144
144
 
145
- ## Forwarding HTML Attributes
146
-
147
- When you want to improve the accessibility of your text fields even further, you
148
- can **add whatever HTML attribute you like.** All attributes that don't
149
- interfere with [component's API](#api) are forwarded to the native HTML input.
150
-
151
- <Playground>
152
- <TextArea
153
- label="Address"
154
- autoComplete="street-address"
155
- minLength={3}
156
- maxLength={80}
157
- />
158
- <TextArea
159
- label="Address"
160
- variant="filled"
161
- autoComplete="street-address"
162
- minLength={3}
163
- maxLength={80}
164
- />
165
- </Playground>
166
-
167
- 👉 Refer to the MDN reference for the full list of
168
- [supported attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#Attributes).
169
-
170
145
  ## Invisible Label
171
146
 
172
147
  In some cases, it may be convenient to visually hide the field label. The label
@@ -346,12 +321,38 @@ It's possible to disable the whole input.
346
321
  />
347
322
  </Playground>
348
323
 
349
- ## API
324
+ ## Forwarding HTML Attributes
350
325
 
351
- In addition to the options below, you can specify [React synthetic events] or
352
- any custom HTML attributes that do not interfere with the API, and they will be
353
- passed to the `<textarea>` HTML element. This enables making the component
354
- interactive and helps improve its [accessibility](#forwarding-html-attributes).
326
+ In addition to the options below in the [component's API](#api) section, you
327
+ can specify [React synthetic events] or you can **add whatever HTML attribute
328
+ you like.** All attributes that don't interfere with the API are forwarded to
329
+ the native HTML `<textarea>`. This enables making the component interactive and
330
+ to helps to improve its accessibility.
331
+
332
+ <Playground>
333
+ <TextArea
334
+ label="Address"
335
+ autoComplete="street-address"
336
+ minLength={3}
337
+ maxLength={80}
338
+ />
339
+ <TextArea
340
+ label="Address"
341
+ variant="filled"
342
+ autoComplete="street-address"
343
+ minLength={3}
344
+ maxLength={80}
345
+ />
346
+ </Playground>
347
+
348
+ 👉 Refer to the MDN reference for the full list of supported attributes of the
349
+ [textarea] element.
350
+
351
+ ## Forwarding ref
352
+
353
+ If you provide [ref], it is forwarded to the native HTML `<textarea>` element.
354
+
355
+ ## API
355
356
 
356
357
  <Props table of={TextArea} />
357
358
 
@@ -361,3 +362,5 @@ Head to [Forms Theming](/customize/theming/forms) to see shared form theming
361
362
  options.
362
363
 
363
364
  [React synthetic events]: https://reactjs.org/docs/events.html
365
+ [textarea]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#attributes
366
+ [ref]: https://reactjs.org/docs/refs-and-the-dom.html
@@ -7,29 +7,25 @@ import { getRootValidationStateClassName } from '../_helpers/getRootValidationSt
7
7
  import { resolveContextOrProp } from '../_helpers/resolveContextOrProp';
8
8
  import { transferProps } from '../_helpers/transferProps';
9
9
  import { FormLayoutContext } from '../FormLayout';
10
- import withForwardedRef from '../withForwardedRef';
11
10
  import styles from './TextArea.scss';
12
11
 
13
- export const TextArea = ({
14
- cols,
15
- disabled,
16
- forwardedRef,
17
- fullWidth,
18
- helpText,
19
- id,
20
- isLabelVisible,
21
- label,
22
- layout,
23
- placeholder,
24
- required,
25
- rows,
26
- size,
27
- validationState,
28
- validationText,
29
- value,
30
- variant,
31
- ...restProps
32
- }) => {
12
+ export const TextArea = React.forwardRef((props, ref) => {
13
+ const {
14
+ disabled,
15
+ fullWidth,
16
+ helpText,
17
+ id,
18
+ isLabelVisible,
19
+ label,
20
+ layout,
21
+ required,
22
+ size,
23
+ validationState,
24
+ validationText,
25
+ variant,
26
+ ...restProps
27
+ } = props;
28
+
33
29
  const context = useContext(FormLayoutContext);
34
30
 
35
31
  return (
@@ -39,13 +35,13 @@ export const TextArea = ({
39
35
  fullWidth && styles.isRootFullWidth,
40
36
  context && styles.isRootInFormLayout,
41
37
  resolveContextOrProp(context && context.layout, layout) === 'horizontal'
42
- ? styles.rootLayoutHorizontal
43
- : styles.rootLayoutVertical,
38
+ ? styles.isRootLayoutHorizontal
39
+ : styles.isRootLayoutVertical,
44
40
  disabled && styles.isRootDisabled,
45
41
  required && styles.isRootRequired,
46
42
  getRootSizeClassName(size, styles),
47
43
  getRootValidationStateClassName(validationState, styles),
48
- variant === 'filled' ? styles.rootVariantFilled : styles.rootVariantOutline,
44
+ variant === 'filled' ? styles.isRootVariantFilled : styles.isRootVariantOutline,
49
45
  )}
50
46
  htmlFor={id}
51
47
  id={id && `${id}__label`}
@@ -64,14 +60,10 @@ export const TextArea = ({
64
60
  <textarea
65
61
  {...transferProps(restProps)}
66
62
  className={styles.input}
67
- cols={cols}
68
63
  disabled={disabled}
69
64
  id={id}
70
- placeholder={placeholder}
71
- ref={forwardedRef}
65
+ ref={ref}
72
66
  required={required}
73
- rows={rows}
74
- value={value}
75
67
  />
76
68
  {variant === 'filled' && (
77
69
  <div className={styles.bottomLine} />
@@ -96,44 +88,27 @@ export const TextArea = ({
96
88
  </div>
97
89
  </label>
98
90
  );
99
- };
91
+ });
100
92
 
101
93
  TextArea.defaultProps = {
102
- cols: null,
103
94
  disabled: false,
104
- forwardedRef: undefined,
105
95
  fullWidth: false,
106
96
  helpText: null,
107
97
  id: undefined,
108
98
  isLabelVisible: true,
109
99
  layout: 'vertical',
110
- placeholder: null,
111
100
  required: false,
112
- rows: 3,
113
101
  size: 'medium',
114
102
  validationState: null,
115
103
  validationText: null,
116
- value: undefined,
117
104
  variant: 'outline',
118
105
  };
119
106
 
120
107
  TextArea.propTypes = {
121
- /**
122
- * The number of visible text columns for the control.
123
- */
124
- cols: PropTypes.number,
125
108
  /**
126
109
  * If `true`, the input will be disabled.
127
110
  */
128
111
  disabled: PropTypes.bool,
129
- /**
130
- * Reference forwarded to the `textarea` element.
131
- */
132
- forwardedRef: PropTypes.oneOfType([
133
- PropTypes.func,
134
- // eslint-disable-next-line react/forbid-prop-types
135
- PropTypes.shape({ current: PropTypes.any }),
136
- ]),
137
112
  /**
138
113
  * If `true`, the field will span the full width of its parent.
139
114
  */
@@ -165,18 +140,10 @@ TextArea.propTypes = {
165
140
  * as the value is inherited in such case.
166
141
  */
167
142
  layout: PropTypes.oneOf(['horizontal', 'vertical']),
168
- /**
169
- * Optional example value.
170
- */
171
- placeholder: PropTypes.string,
172
143
  /**
173
144
  * If `true`, the input will be required.
174
145
  */
175
146
  required: PropTypes.bool,
176
- /**
177
- * The number of visible text lines for the control.
178
- */
179
- rows: PropTypes.number,
180
147
  /**
181
148
  * Size of the field.
182
149
  */
@@ -189,19 +156,12 @@ TextArea.propTypes = {
189
156
  * Validation message to be displayed.
190
157
  */
191
158
  validationText: PropTypes.node,
192
- /**
193
- * Value of the input.
194
- */
195
- value: PropTypes.oneOfType([
196
- PropTypes.string,
197
- PropTypes.number,
198
- ]),
199
159
  /**
200
160
  * Design variant of the field, further customizable with CSS custom properties.
201
161
  */
202
162
  variant: PropTypes.oneOf(['filled', 'outline']),
203
163
  };
204
164
 
205
- export const TextAreaWithGlobalProps = withForwardedRef(withGlobalProps(TextArea, 'TextArea'));
165
+ export const TextAreaWithGlobalProps = withGlobalProps(TextArea, 'TextArea');
206
166
 
207
167
  export default TextAreaWithGlobalProps;
@@ -37,11 +37,11 @@
37
37
  }
38
38
 
39
39
  // Visual variants
40
- .rootVariantFilled {
40
+ .isRootVariantFilled {
41
41
  @include variants.visual(box, $variant: filled);
42
42
  }
43
43
 
44
- .rootVariantOutline {
44
+ .isRootVariantOutline {
45
45
  @include variants.visual(box, $variant: outline);
46
46
  }
47
47
 
@@ -64,12 +64,12 @@
64
64
  }
65
65
 
66
66
  // Layouts
67
- .rootLayoutVertical,
68
- .rootLayoutHorizontal {
67
+ .isRootLayoutVertical,
68
+ .isRootLayoutHorizontal {
69
69
  @include box-field-layout.vertical();
70
70
  }
71
71
 
72
- .rootLayoutHorizontal {
72
+ .isRootLayoutHorizontal {
73
73
  @include box-field-layout.horizontal();
74
74
  }
75
75
 
@@ -82,14 +82,14 @@
82
82
  }
83
83
 
84
84
  // Sizes
85
- .rootSizeSmall {
85
+ .isRootSizeSmall {
86
86
  @include box-field-sizes.size(small, $is-multiline: true);
87
87
  }
88
88
 
89
- .rootSizeMedium {
89
+ .isRootSizeMedium {
90
90
  @include box-field-sizes.size(medium, $is-multiline: true);
91
91
  }
92
92
 
93
- .rootSizeLarge {
93
+ .isRootSizeLarge {
94
94
  @include box-field-sizes.size(large, $is-multiline: true);
95
95
  }
@@ -1 +1 @@
1
- export { default } from './TextArea';
1
+ export { default as TextArea } from './TextArea';