@react-ui-org/react-ui 0.45.0 → 0.46.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. package/CONTRIBUTING.md +7 -0
  2. package/dist/lib.development.js +113 -89
  3. package/dist/lib.js +1 -1
  4. package/package.json +4 -4
  5. package/src/lib/components/Badge/Badge.jsx +1 -4
  6. package/src/lib/components/Button/README.mdx +1 -1
  7. package/src/lib/components/ButtonGroup/ButtonGroup.jsx +30 -22
  8. package/src/lib/components/Card/CardBody.jsx +5 -11
  9. package/src/lib/components/Card/CardFooter.jsx +10 -5
  10. package/src/lib/components/CheckboxField/CheckboxField.jsx +9 -9
  11. package/src/lib/components/CheckboxField/CheckboxField.scss +1 -1
  12. package/src/lib/components/CheckboxField/README.mdx +1 -1
  13. package/src/lib/components/FileInputField/README.mdx +1 -1
  14. package/src/lib/components/FormLayout/FormLayout.jsx +11 -10
  15. package/src/lib/components/FormLayout/FormLayoutCustomField.jsx +6 -1
  16. package/src/lib/components/FormLayout/README.mdx +7 -9
  17. package/src/lib/components/Grid/Grid.jsx +3 -2
  18. package/src/lib/components/Grid/GridSpan.jsx +3 -2
  19. package/src/lib/components/List/List.jsx +3 -2
  20. package/src/lib/components/List/ListItem.jsx +3 -2
  21. package/src/lib/components/Media/Media.jsx +12 -5
  22. package/src/lib/components/Media/MediaBody.jsx +18 -7
  23. package/src/lib/components/Media/MediaObject.jsx +18 -7
  24. package/src/lib/components/Modal/Modal.jsx +2 -1
  25. package/src/lib/components/Paper/Paper.jsx +1 -2
  26. package/src/lib/components/Radio/README.mdx +1 -1
  27. package/src/lib/components/Radio/Radio.scss +1 -1
  28. package/src/lib/components/ScrollView/README.mdx +3 -0
  29. package/src/lib/components/ScrollView/ScrollView.jsx +2 -1
  30. package/src/lib/components/SelectField/README.mdx +1 -1
  31. package/src/lib/components/Tabs/Tabs.jsx +1 -2
  32. package/src/lib/components/Text/README.mdx +1 -1
  33. package/src/lib/components/Text/Text.jsx +8 -2
  34. package/src/lib/components/Text/Text.scss +12 -2
  35. package/src/lib/components/Text/_helpers/getRootClampClassName.js +11 -0
  36. package/src/lib/components/TextArea/README.mdx +1 -1
  37. package/src/lib/components/TextArea/TextArea.jsx +4 -1
  38. package/src/lib/components/TextField/README.mdx +1 -1
  39. package/src/lib/components/TextLink/README.mdx +77 -0
  40. package/src/lib/components/{Link/Link.jsx → TextLink/TextLink.jsx} +11 -12
  41. package/src/lib/components/TextLink/TextLink.scss +11 -0
  42. package/src/lib/components/TextLink/_theme.scss +4 -0
  43. package/src/lib/components/TextLink/index.js +1 -0
  44. package/src/lib/components/Toggle/README.mdx +1 -1
  45. package/src/lib/components/Toggle/Toggle.jsx +9 -9
  46. package/src/lib/components/Toggle/Toggle.scss +1 -1
  47. package/src/lib/components/Toolbar/README.mdx +16 -0
  48. package/src/lib/components/Toolbar/Toolbar.jsx +18 -10
  49. package/src/lib/components/Toolbar/Toolbar.scss +13 -8
  50. package/src/lib/components/Toolbar/ToolbarGroup.jsx +13 -9
  51. package/src/lib/components/Toolbar/ToolbarItem.jsx +26 -7
  52. package/src/lib/components/_helpers/isChildrenEmpty.js +3 -0
  53. package/src/lib/index.js +1 -1
  54. package/src/lib/styles/tools/_reset.scss +4 -1
  55. package/src/lib/styles/tools/form-fields/_box-field-layout.scss +3 -3
  56. package/src/lib/styles/tools/form-fields/_inline-field-elements.scss +12 -1
  57. package/src/lib/styles/tools/form-fields/_inline-field-layout.scss +46 -5
  58. package/src/lib/theme.scss +6 -6
  59. package/src/lib/components/Link/Link.scss +0 -11
  60. package/src/lib/components/Link/README.mdx +0 -85
  61. package/src/lib/components/Link/_theme.scss +0 -4
  62. package/src/lib/components/Link/index.js +0 -1
@@ -18,7 +18,6 @@ export const Tabs = ({
18
18
  );
19
19
 
20
20
  Tabs.defaultProps = {
21
- children: null,
22
21
  id: undefined,
23
22
  };
24
23
 
@@ -26,7 +25,7 @@ Tabs.propTypes = {
26
25
  /**
27
26
  * Nested `TabsItem` elements.
28
27
  */
29
- children: PropTypes.node,
28
+ children: PropTypes.node.isRequired,
30
29
  /**
31
30
  * ID of the root HTML element. It also serves as base for nested element:
32
31
  * * `<ID>__list`
@@ -81,7 +81,7 @@ appended by an ellipsis (`…`).
81
81
  label="Number of lines"
82
82
  min={1}
83
83
  max={100}
84
- onChange={(e) => setLines(e.target.value)}
84
+ onChange={(e) => setLines(Number(e.target.value))}
85
85
  type="number"
86
86
  value={lines}
87
87
  />
@@ -2,6 +2,8 @@ import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
3
  import { withProviderContext } from '../../provider';
4
4
  import { classNames } from '../../utils/classNames';
5
+ import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
6
+ import { getRootClampClassName } from './_helpers/getRootClampClassName';
5
7
  import { getRootHyphensClassName } from './_helpers/getRootHyphensClassName';
6
8
  import { getRootWordWrappingClassName } from './_helpers/getRootWordWrappingClassName';
7
9
  import styles from './Text.scss';
@@ -14,19 +16,23 @@ export const Text = ({
14
16
  lines,
15
17
  wordWrapping,
16
18
  }) => {
19
+ if (isChildrenEmpty(children)) {
20
+ return null;
21
+ }
22
+
17
23
  const HtmlElement = blockLevel ? 'div' : 'span';
18
24
 
19
25
  return (
20
26
  <HtmlElement
21
27
  className={(hyphens !== 'none' || lines > 0 || wordWrapping !== 'normal')
22
28
  ? classNames(
23
- (lines > 0) ? styles.rootClampLines : '',
29
+ getRootClampClassName(lines, styles),
24
30
  getRootHyphensClassName(hyphens, styles),
25
31
  getRootWordWrappingClassName(wordWrapping, styles),
26
32
  )
27
33
  : undefined}
28
34
  id={id}
29
- style={(lines > 0) ? { '--rui-custom-lines': lines } : undefined}
35
+ style={(lines > 1) ? { '--rui-custom-lines': lines } : undefined}
30
36
  >
31
37
  {children}
32
38
  </HtmlElement>
@@ -1,10 +1,20 @@
1
1
  // 1. `word-break: break-word` is deprecated in favour of `overflow-wrap: anywhere`, but it's still
2
2
  // required for Safari.
3
3
  // https://caniuse.com/mdn-css_properties_overflow-wrap_anywhere
4
+ //
5
+ // 2. Different approaches are used for single and multiline texts because the latter approach
6
+ // doesn't always work for single-line texts.
7
+
8
+ .rootClampSingleLine {
9
+ display: block; // 2.
10
+ overflow: hidden;
11
+ text-overflow: ellipsis;
12
+ white-space: nowrap;
13
+ }
4
14
 
5
15
  // stylelint-disable property-no-vendor-prefix, value-no-vendor-prefix
6
- .rootClampLines {
7
- display: -webkit-box;
16
+ .rootClampMultiLine {
17
+ display: -webkit-box; // 2.
8
18
  -webkit-line-clamp: var(--rui-custom-lines);
9
19
  -webkit-box-orient: vertical;
10
20
  overflow: hidden;
@@ -0,0 +1,11 @@
1
+ export const getRootClampClassName = (lines, styles) => {
2
+ if (lines === 1) {
3
+ return styles.rootClampSingleLine;
4
+ }
5
+
6
+ if (lines > 1) {
7
+ return styles.rootClampMultiLine;
8
+ }
9
+
10
+ return null;
11
+ };
@@ -350,7 +350,7 @@ It's possible to disable the whole input.
350
350
 
351
351
  In addition to the options below, you can specify [React synthetic events] or
352
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
353
+ passed to the `<textarea>` HTML element. This enables making the component
354
354
  interactive and helps improve its [accessibility](#forwarding-html-attributes).
355
355
 
356
356
  <Props table of={TextArea} />
@@ -192,7 +192,10 @@ TextArea.propTypes = {
192
192
  /**
193
193
  * Value of the input.
194
194
  */
195
- value: PropTypes.string,
195
+ value: PropTypes.oneOfType([
196
+ PropTypes.string,
197
+ PropTypes.number,
198
+ ]),
196
199
  /**
197
200
  * Design variant of the field, further customizable with CSS custom properties.
198
201
  */
@@ -493,7 +493,7 @@ It's possible to disable the whole input.
493
493
 
494
494
  In addition to the options below, you can specify [React synthetic events] or
495
495
  any custom HTML attributes that do not interfere with the API, and they will be
496
- passed to the `input` HTML element. This enables making the component
496
+ passed to the `<input>` HTML element. This enables making the component
497
497
  interactive and helps improve its [accessibility](#forwarding-html-attributes).
498
498
 
499
499
  <Props table of={TextField} />
@@ -0,0 +1,77 @@
1
+ ---
2
+ name: TextLink
3
+ menu: 'Actions'
4
+ route: /components/text-link
5
+ ---
6
+
7
+ # TextLink
8
+
9
+ import {
10
+ Playground,
11
+ Props,
12
+ } from 'docz'
13
+ import { TextLink } from './TextLink'
14
+
15
+ TextLink allows users to follow navigation.
16
+
17
+ ## Basic Usage
18
+
19
+ To implement the TextLink component, you need to import it first:
20
+
21
+ ```js
22
+ import { TextLink } from '@react-ui-org/react-ui';
23
+ ```
24
+
25
+ And use it:
26
+
27
+ <Playground>
28
+ <TextLink
29
+ href="/contribute/guidelines"
30
+ label="How can I contribute to React UI?"
31
+ />
32
+ </Playground>
33
+
34
+ See [API](#api) for all available options.
35
+
36
+ ## General Guidelines
37
+
38
+ **Avoid using links for actions**, use a [Button](/components/button)
39
+ instead. This is because users expect navigation to happen when clicking on
40
+ something what looks like a link.
41
+
42
+ ## Custom Routing
43
+
44
+ It's common to use custom function for routing within SPAs. Use the
45
+ `onClick` option to provide such function.
46
+
47
+ <Playground>
48
+ <TextLink
49
+ href="/contribute/guidelines"
50
+ label="This link is controlled by custom function"
51
+ onClick={(event) => {
52
+ event.preventDefault();
53
+ alert('You will be redirected.')
54
+ window.location = event.currentTarget.getAttribute('href');
55
+ }}
56
+ />
57
+ </Playground>
58
+
59
+ ## API
60
+
61
+ In addition to the options below, you can specify [React synthetic events] or
62
+ any custom HTML attributes that do not interfere with the API, and they will be
63
+ passed to the `<a>` HTML element. This enables making the component interactive
64
+ and helps improve its accessibility.
65
+
66
+ <Props table of={TextLink} />
67
+
68
+ ## Theming
69
+
70
+ | Custom Property | Description |
71
+ |------------------------------------------|-----------------------------------|
72
+ | `--rui-TextLink__color` | Text color |
73
+ | `--rui-TextLink__text-decoration` | Text decoration, e.g. underline |
74
+ | `--rui-TextLink--hover__color` | Text color on hover |
75
+ | `--rui-TextLink--hover__text-decoration` | Text decoration on hover |
76
+
77
+ [React synthetic events]: https://reactjs.org/docs/events.html
@@ -2,12 +2,12 @@ import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
3
  import { withProviderContext } from '../../provider';
4
4
  import { transferProps } from '../_helpers/transferProps';
5
- import styles from './Link.scss';
5
+ import styles from './TextLink.scss';
6
6
 
7
- export const Link = ({
8
- children,
7
+ export const TextLink = ({
9
8
  href,
10
9
  id,
10
+ label,
11
11
  ...restProps
12
12
  }) => (
13
13
  <a
@@ -16,20 +16,15 @@ export const Link = ({
16
16
  className={styles.root}
17
17
  id={id}
18
18
  >
19
- {children}
19
+ {label}
20
20
  </a>
21
21
  );
22
22
 
23
- Link.defaultProps = {
24
- children: null,
23
+ TextLink.defaultProps = {
25
24
  id: undefined,
26
25
  };
27
26
 
28
- Link.propTypes = {
29
- /**
30
- * Content of the link.
31
- */
32
- children: PropTypes.node,
27
+ TextLink.propTypes = {
33
28
  /**
34
29
  * Link's `href` attribute.
35
30
  */
@@ -38,8 +33,12 @@ Link.propTypes = {
38
33
  * ID of the root HTML element.
39
34
  */
40
35
  id: PropTypes.string,
36
+ /**
37
+ * Link label.
38
+ */
39
+ label: PropTypes.string.isRequired,
41
40
  };
42
41
 
43
- export const LinkWithContext = withProviderContext(Link, 'Link');
42
+ export const LinkWithContext = withProviderContext(TextLink, 'Link');
44
43
 
45
44
  export default LinkWithContext;
@@ -0,0 +1,11 @@
1
+ @use "theme";
2
+
3
+ .root {
4
+ text-decoration: theme.$text-decoration;
5
+ color: theme.$color;
6
+
7
+ &:hover {
8
+ text-decoration: theme.$hover-text-decoration;
9
+ color: theme.$hover-color;
10
+ }
11
+ }
@@ -0,0 +1,4 @@
1
+ $color: var(--rui-TextLink__color);
2
+ $text-decoration: var(--rui-TextLink__text-decoration);
3
+ $hover-color: var(--rui-TextLink--hover__color);
4
+ $hover-text-decoration: var(--rui-TextLink--hover__text-decoration);
@@ -0,0 +1 @@
1
+ export { default } from './TextLink';
@@ -181,7 +181,7 @@ Disabled state makes the input unavailable.
181
181
 
182
182
  In addition to the options below, you can specify [React synthetic events] or
183
183
  any custom HTML attributes that do not interfere with the API, and they will be
184
- passed to the `input` HTML element. This enables making the component
184
+ passed to the `<input>` HTML element. This enables making the component
185
185
  interactive and helps improve its accessibility.
186
186
 
187
187
  <Props table of={Toggle} />
@@ -40,6 +40,15 @@ export const Toggle = ({
40
40
  id={id && `${id}__label`}
41
41
  >
42
42
  <div className={styles.field}>
43
+ <div
44
+ className={classNames(
45
+ styles.label,
46
+ !isLabelVisible && styles.isLabelHidden,
47
+ )}
48
+ id={id && `${id}__labelText`}
49
+ >
50
+ {label}
51
+ </div>
43
52
  <input
44
53
  {...transferProps(restProps)}
45
54
  checked={checked}
@@ -52,15 +61,6 @@ export const Toggle = ({
52
61
  type="checkbox"
53
62
  value={value}
54
63
  />
55
- <div
56
- className={classNames(
57
- styles.label,
58
- !isLabelVisible && styles.isLabelHidden,
59
- )}
60
- id={id && `${id}__labelText`}
61
- >
62
- {label}
63
- </div>
64
64
  </div>
65
65
  {helpText && (
66
66
  <div
@@ -17,7 +17,7 @@
17
17
  }
18
18
 
19
19
  .field {
20
- @include inline-field-layout.field();
20
+ @include inline-field-layout.field($type: toggle);
21
21
  }
22
22
 
23
23
  .input {
@@ -304,6 +304,22 @@ Toolbar.
304
304
  content placed within Toolbar. The [Text][text] component is designed
305
305
  specifically for this kind of job.
306
306
 
307
+ ## Flexible Items
308
+
309
+ Toolbar items can be made flexible to grow and shrink according to the available
310
+ space. This is useful e.g. when you need to combine text with an action.
311
+
312
+ <Playground>
313
+ <Toolbar>
314
+ <ToolbarItem flexible>
315
+ <Placeholder bordered>My Headline</Placeholder>
316
+ </ToolbarItem>
317
+ <ToolbarItem>
318
+ <Placeholder bordered>Action</Placeholder>
319
+ </ToolbarItem>
320
+ </Toolbar>
321
+ </Playground>
322
+
307
323
  ## API
308
324
 
309
325
  <Props table of={Toolbar} />
@@ -2,16 +2,19 @@ import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
3
  import { withProviderContext } from '../../provider';
4
4
  import { classNames } from '../../utils/classNames';
5
+ import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
5
6
  import styles from './Toolbar.scss';
6
7
 
7
- export const Toolbar = (props) => {
8
- const {
9
- align,
10
- children,
11
- dense,
12
- justify,
13
- nowrap,
14
- } = props;
8
+ export const Toolbar = ({
9
+ align,
10
+ children,
11
+ dense,
12
+ justify,
13
+ nowrap,
14
+ }) => {
15
+ if (isChildrenEmpty(children)) {
16
+ return null;
17
+ }
15
18
 
16
19
  const alignClass = (value) => {
17
20
  if (value === 'top') {
@@ -62,6 +65,7 @@ export const Toolbar = (props) => {
62
65
 
63
66
  Toolbar.defaultProps = {
64
67
  align: 'top',
68
+ children: null,
65
69
  dense: false,
66
70
  justify: 'start',
67
71
  nowrap: false,
@@ -73,9 +77,13 @@ Toolbar.propTypes = {
73
77
  */
74
78
  align: PropTypes.oneOf(['top', 'middle', 'bottom', 'baseline']),
75
79
  /**
76
- * Individual ToolbarItems and ToolbarGroups.
80
+ * Nested elements. Supported types are:
81
+ * * `ToolbarItems`
82
+ * * `ToolbarGroups`
83
+ *
84
+ * If none are provided nothing is rendered.
77
85
  */
78
- children: PropTypes.node.isRequired,
86
+ children: PropTypes.node,
79
87
  /**
80
88
  * If `true`, spacing of all toolbar items in the toolbar will be reduced.
81
89
  */
@@ -22,6 +22,11 @@
22
22
  margin: theme.$gap;
23
23
  }
24
24
 
25
+ .isItemFlexible {
26
+ flex: 1;
27
+ min-width: 0;
28
+ }
29
+
25
30
  .isAlignedToTop {
26
31
  align-items: flex-start;
27
32
  }
@@ -54,14 +59,6 @@
54
59
  justify-content: space-between;
55
60
  }
56
61
 
57
- .isNowrap {
58
- flex-wrap: nowrap;
59
- }
60
-
61
- .isNowrap > .item {
62
- flex: 0 1 auto;
63
- }
64
-
65
62
  .isDense {
66
63
  margin: calc(-1 * #{theme.$gap-dense});
67
64
  }
@@ -74,6 +71,14 @@
74
71
  margin: 0;
75
72
  }
76
73
 
74
+ .isNowrap {
75
+ flex-wrap: nowrap;
76
+ }
77
+
78
+ .isNowrap > .item:not(.isItemFlexible) {
79
+ flex: 0 1 auto;
80
+ }
81
+
77
82
  .toolbar.isDense {
78
83
  @include spacing.bottom(layouts, $compensation: theme.$gap-dense);
79
84
  }
@@ -2,15 +2,18 @@ import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
3
  import { withProviderContext } from '../../provider';
4
4
  import { classNames } from '../../utils/classNames';
5
+ import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
5
6
  import styles from './Toolbar.scss';
6
7
 
7
- export const ToolbarGroup = (props) => {
8
- const {
9
- align,
10
- children,
11
- dense,
12
- nowrap,
13
- } = props;
8
+ export const ToolbarGroup = ({
9
+ align,
10
+ children,
11
+ dense,
12
+ nowrap,
13
+ }) => {
14
+ if (isChildrenEmpty(children)) {
15
+ return null;
16
+ }
14
17
 
15
18
  const alignClass = (value) => {
16
19
  if (value === 'top') {
@@ -44,6 +47,7 @@ export const ToolbarGroup = (props) => {
44
47
 
45
48
  ToolbarGroup.defaultProps = {
46
49
  align: 'top',
50
+ children: null,
47
51
  dense: false,
48
52
  nowrap: false,
49
53
  };
@@ -54,9 +58,9 @@ ToolbarGroup.propTypes = {
54
58
  */
55
59
  align: PropTypes.oneOf(['top', 'middle', 'bottom', 'baseline']),
56
60
  /**
57
- * Grouped ToolbarItems.
61
+ * Grouped ToolbarItems. If none are provided nothing is rendered.
58
62
  */
59
- children: PropTypes.node.isRequired,
63
+ children: PropTypes.node,
60
64
  /**
61
65
  * If `true`, spacing of toolbar items in the group will be reduced.
62
66
  */
@@ -1,25 +1,44 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React from 'react';
3
+ import { classNames } from '../../utils/classNames';
3
4
  import { withProviderContext } from '../../provider';
5
+ import { isChildrenEmpty } from '../_helpers/isChildrenEmpty';
4
6
  import styles from './Toolbar.scss';
5
7
 
6
- export const ToolbarItem = (props) => {
7
- const {
8
- children,
9
- } = props;
8
+ export const ToolbarItem = ({
9
+ children,
10
+ flexible,
11
+ }) => {
12
+ if (isChildrenEmpty(children)) {
13
+ return null;
14
+ }
10
15
 
11
16
  return (
12
- <div className={styles.item}>
17
+ <div
18
+ className={classNames(
19
+ styles.item,
20
+ flexible && styles.isItemFlexible,
21
+ )}
22
+ >
13
23
  {children}
14
24
  </div>
15
25
  );
16
26
  };
17
27
 
28
+ ToolbarItem.defaultProps = {
29
+ children: null,
30
+ flexible: false,
31
+ };
32
+
18
33
  ToolbarItem.propTypes = {
19
34
  /**
20
- * Content of the toolbar item.
35
+ * Content of the toolbar item. If none are provided nothing is rendered.
36
+ */
37
+ children: PropTypes.node,
38
+ /**
39
+ * Allow item to grow and shrink if needed.
21
40
  */
22
- children: PropTypes.node.isRequired,
41
+ flexible: PropTypes.bool,
23
42
  };
24
43
 
25
44
  export const ToolbarItemWithContext = withProviderContext(ToolbarItem, 'ToolbarItem');
@@ -0,0 +1,3 @@
1
+ export const isChildrenEmpty = (children) => children == null
2
+ || children === false
3
+ || (Array.isArray(children) && children.length === 0);
package/src/lib/index.js CHANGED
@@ -18,7 +18,6 @@ export {
18
18
  Grid,
19
19
  GridSpan,
20
20
  } from './components/Grid';
21
- export { default as Link } from './components/Link';
22
21
  export {
23
22
  List,
24
23
  ListItem,
@@ -41,6 +40,7 @@ export { default as Table } from './components/Table';
41
40
  export { default as Text } from './components/Text';
42
41
  export { default as TextArea } from './components/TextArea';
43
42
  export { default as TextField } from './components/TextField';
43
+ export { default as TextLink } from './components/TextLink';
44
44
  export { default as Toggle } from './components/Toggle';
45
45
  export {
46
46
  Toolbar,
@@ -25,6 +25,9 @@
25
25
 
26
26
  @mixin list() {
27
27
  padding-left: 0;
28
- margin-bottom: 0;
29
28
  list-style: none;
29
+
30
+ &:not(:last-child) {
31
+ margin-bottom: 0;
32
+ }
30
33
  }
@@ -5,9 +5,9 @@
5
5
  // 2. Form fields in horizontal layout also take up only as much space as they need. Labels do not
6
6
  // wrap until label width limit is reached (50 % of available horizontal space by default).
7
7
  //
8
- // 3. Help texts and validation messages are aligned below input and wrapped. Their width is always
9
- // limited to the width of the input field so they don't shift adjacent elements when they show
10
- // up. This applies unless the field is inside FormLayout (see 10).
8
+ // 3. Help texts and validation messages are aligned below input and wrapped. Their width is always
9
+ // limited to the width of the input field so they don't shift adjacent elements when they show
10
+ // up. This applies unless the field is inside FormLayout (see 10).
11
11
  //
12
12
  // 4. Define grid spacing as padding of child elements because grid areas make row and column gaps
13
13
  // show up even when not necessary.
@@ -6,6 +6,8 @@
6
6
  //
7
7
  // 3. Reset extra space previously added to symmetrically pad the field in FormLayout context as
8
8
  // there already is a sufficient row gap provided by FormLayout.
9
+ //
10
+ // 4. Destroy tap target when subgrid is not supported.
9
11
 
10
12
  @use "../../theme/typography";
11
13
  @use "../../theme/form-fields" as theme;
@@ -93,7 +95,16 @@
93
95
  padding-top: 0;
94
96
 
95
97
  &::before {
96
- top: calc((#{typography.$line-height-base} - 1rem * #{theme.$check-tap-target-size}) / 2);
98
+ top: calc((1rem * #{typography.$line-height-base} - #{theme.$check-tap-target-size}) / 2);
99
+ }
100
+ }
101
+
102
+ &.isRootInFormLayout.rootLayoutHorizontal::before {
103
+ grid-column-start: 2;
104
+
105
+ // 4.
106
+ @supports not (grid-template-columns: subgrid) {
107
+ display: none;
97
108
  }
98
109
  }
99
110
  }