@react-ui-org/react-ui 0.52.1 → 0.53.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.
- package/CODEOWNERS +23 -0
- package/README.md +10 -7
- package/dist/react-ui.css +5 -3
- package/dist/react-ui.js +1 -1
- package/package.json +64 -77
- package/src/{lib/components → components}/Alert/Alert.jsx +1 -1
- package/src/{lib/components/Alert/README.mdx → components/Alert/README.md} +84 -100
- package/src/{lib/components → components}/Badge/Badge.jsx +1 -1
- package/src/{lib/components → components}/Badge/Badge.scss +1 -1
- package/src/components/Badge/README.md +103 -0
- package/src/{lib/components → components}/Button/Button.jsx +1 -1
- package/src/components/Button/README.md +580 -0
- package/src/{lib/components → components}/ButtonGroup/ButtonGroup.jsx +11 -9
- package/src/{lib/components/ButtonGroup/README.mdx → components/ButtonGroup/README.md} +128 -134
- package/src/{lib/components → components}/Card/Card.jsx +1 -1
- package/src/components/Card/README.md +314 -0
- package/src/{lib/components/CheckboxField/README.mdx → components/CheckboxField/README.md} +96 -108
- package/src/{lib/components/FileInputField/README.mdx → components/FileInputField/README.md} +83 -95
- package/src/{lib/components → components}/FormLayout/FormLayout.jsx +4 -4
- package/src/components/FormLayout/README.md +462 -0
- package/src/{lib/components → components}/Grid/Grid.jsx +2 -2
- package/src/components/Grid/README.md +281 -0
- package/src/{lib/components → components}/InputGroup/InputGroup.jsx +20 -19
- package/src/{lib/components → components}/InputGroup/InputGroup.scss +0 -5
- package/src/{lib/components/InputGroup/README.mdx → components/InputGroup/README.md} +145 -163
- package/src/{lib/components → components}/Modal/Modal.jsx +6 -6
- package/src/components/Modal/README.md +1090 -0
- package/src/components/Modal/_hooks/useModalScrollPrevention.js +37 -0
- package/src/{lib/components/Paper/README.mdx → components/Paper/README.md} +18 -30
- package/src/{lib/components/Popover/README.mdx → components/Popover/README.md} +102 -132
- package/src/{lib/components/Radio/README.mdx → components/Radio/README.md} +122 -134
- package/src/{lib/components → components}/Radio/Radio.jsx +11 -12
- package/src/{lib/components → components}/Radio/Radio.scss +0 -5
- package/src/components/ScrollView/README.md +503 -0
- package/src/{lib/components → components}/ScrollView/ScrollView.jsx +12 -3
- package/src/components/SelectField/README.md +681 -0
- package/src/components/Table/README.md +259 -0
- package/src/{lib/components → components}/Table/Table.jsx +4 -1
- package/src/{lib/components → components}/Table/_components/TableHeaderCell/TableHeaderCell.jsx +1 -1
- package/src/{lib/components/Tabs/README.mdx → components/Tabs/README.md} +117 -134
- package/src/{lib/components → components}/Tabs/TabsItem.jsx +3 -3
- package/src/components/Text/README.md +220 -0
- package/src/components/TextArea/README.md +359 -0
- package/src/{lib/components/TextField/README.mdx → components/TextField/README.md} +336 -342
- package/src/{lib/components/TextLink/README.mdx → components/TextLink/README.md} +19 -31
- package/src/{lib/components/Toggle/README.mdx → components/Toggle/README.md} +98 -110
- package/src/components/Toolbar/README.md +359 -0
- package/src/{lib/components → components}/Toolbar/_helpers/getAlignClassName.js +12 -4
- package/src/components/_helpers/getRootPriorityClassName.js +15 -0
- package/src/{lib/index.js → index.js} +6 -0
- package/src/{lib/provider → provider}/RUIProvider.jsx +17 -11
- package/src/{lib/styles → styles}/tools/_caret.scss +1 -1
- package/src/{lib/styles → styles}/tools/form-fields/_box-field-elements.scss +1 -1
- package/src/{lib/styles → styles}/tools/form-fields/_inline-field-elements.scss +2 -2
- package/src/{lib/theme.scss → theme.scss} +4 -3
- package/CONTRIBUTING.md +0 -137
- package/dist/lib.development.js +0 -3179
- package/dist/lib.js +0 -1
- package/public/racom.svg +0 -11
- package/src/lib/components/Badge/README.mdx +0 -126
- package/src/lib/components/Button/README.mdx +0 -581
- package/src/lib/components/Card/README.mdx +0 -326
- package/src/lib/components/FormLayout/README.mdx +0 -501
- package/src/lib/components/Grid/README.mdx +0 -299
- package/src/lib/components/Modal/README.mdx +0 -1360
- package/src/lib/components/Modal/_hooks/useModalScrollPrevention.js +0 -35
- package/src/lib/components/ScrollView/README.mdx +0 -521
- package/src/lib/components/SelectField/README.mdx +0 -693
- package/src/lib/components/Table/README.mdx +0 -275
- package/src/lib/components/Text/README.mdx +0 -241
- package/src/lib/components/TextArea/README.mdx +0 -366
- package/src/lib/components/Toolbar/README.mdx +0 -386
- package/src/{lib/components → components}/Alert/Alert.scss +0 -0
- package/src/{lib/components → components}/Alert/_settings.scss +0 -0
- package/src/{lib/components → components}/Alert/_theme.scss +0 -0
- package/src/{lib/components → components}/Alert/_tools.scss +0 -0
- package/src/{lib/components → components}/Alert/index.js +0 -0
- package/src/{lib/components → components}/Badge/index.js +0 -0
- package/src/{lib/components → components}/Button/Button.scss +0 -0
- package/src/{lib/components → components}/Button/_base.scss +0 -0
- package/src/{lib/components → components}/Button/_priorities.scss +0 -0
- package/src/{lib/components → components}/Button/_settings.scss +0 -0
- package/src/{lib/components → components}/Button/_theme.scss +0 -0
- package/src/{lib/components → components}/Button/_tools.scss +0 -0
- package/src/{lib/components → components}/Button/helpers/getRootLabelVisibilityClassName.js +0 -0
- package/src/{lib/components/_helpers → components/Button/helpers}/getRootPriorityClassName.js +0 -0
- package/src/{lib/components → components}/Button/index.js +0 -0
- package/src/{lib/components → components}/ButtonGroup/ButtonGroup.scss +0 -0
- package/src/{lib/components → components}/ButtonGroup/ButtonGroupContext.js +0 -0
- package/src/{lib/components → components}/ButtonGroup/_theme.scss +0 -0
- package/src/{lib/components → components}/ButtonGroup/index.js +0 -0
- package/src/{lib/components → components}/Card/Card.scss +0 -0
- package/src/{lib/components → components}/Card/CardBody.jsx +0 -0
- package/src/{lib/components → components}/Card/CardFooter.jsx +0 -0
- package/src/{lib/components → components}/Card/_theme.scss +0 -0
- package/src/{lib/components → components}/Card/_tools.scss +0 -0
- package/src/{lib/components → components}/Card/index.js +0 -0
- package/src/{lib/components → components}/CheckboxField/CheckboxField.jsx +0 -0
- package/src/{lib/components → components}/CheckboxField/CheckboxField.scss +0 -0
- package/src/{lib/components → components}/CheckboxField/index.js +0 -0
- package/src/{lib/components → components}/FileInputField/FileInputField.jsx +0 -0
- package/src/{lib/components → components}/FileInputField/FileInputField.scss +0 -0
- package/src/{lib/components → components}/FileInputField/index.js +0 -0
- package/src/{lib/components → components}/FormLayout/FormLayout.scss +0 -0
- package/src/{lib/components → components}/FormLayout/FormLayoutContext.js +0 -0
- package/src/{lib/components → components}/FormLayout/FormLayoutCustomField.jsx +4 -4
- package/src/{lib/components → components}/FormLayout/FormLayoutCustomField.scss +0 -0
- package/src/{lib/components → components}/FormLayout/_theme.scss +0 -0
- package/src/{lib/components → components}/FormLayout/index.js +0 -0
- package/src/{lib/components → components}/Grid/Grid.scss +0 -0
- package/src/{lib/components → components}/Grid/GridSpan.jsx +0 -0
- package/src/{lib/components → components}/Grid/_helpers/generateResponsiveCustomProperties.js +0 -0
- package/src/{lib/components → components}/Grid/_settings.scss +0 -0
- package/src/{lib/components → components}/Grid/_tools.scss +0 -0
- package/src/{lib/components → components}/Grid/index.js +0 -0
- package/src/{lib/components → components}/InputGroup/InputGroupContext.js +0 -0
- package/src/{lib/components → components}/InputGroup/_theme.scss +0 -0
- package/src/{lib/components → components}/InputGroup/index.js +0 -0
- package/src/{lib/components → components}/Modal/Modal.scss +0 -0
- package/src/{lib/components → components}/Modal/ModalBody.jsx +0 -0
- package/src/{lib/components → components}/Modal/ModalBody.scss +0 -0
- package/src/{lib/components → components}/Modal/ModalCloseButton.jsx +1 -1
- package/src/{lib/components → components}/Modal/ModalCloseButton.scss +0 -0
- package/src/{lib/components → components}/Modal/ModalContent.jsx +0 -0
- package/src/{lib/components → components}/Modal/ModalContent.scss +0 -0
- package/src/{lib/components → components}/Modal/ModalFooter.jsx +0 -0
- package/src/{lib/components → components}/Modal/ModalFooter.scss +0 -0
- package/src/{lib/components → components}/Modal/ModalHeader.jsx +0 -0
- package/src/{lib/components → components}/Modal/ModalHeader.scss +0 -0
- package/src/{lib/components → components}/Modal/ModalTitle.jsx +0 -0
- package/src/{lib/components → components}/Modal/ModalTitle.scss +0 -0
- package/src/{lib/components → components}/Modal/_helpers/getJustifyClassName.js +0 -0
- package/src/{lib/components → components}/Modal/_helpers/getPositionClassName.js +0 -0
- package/src/{lib/components → components}/Modal/_helpers/getScrollingClassName.js +0 -0
- package/src/{lib/components → components}/Modal/_helpers/getSizeClassName.js +0 -0
- package/src/{lib/components → components}/Modal/_hooks/useModalFocus.js +0 -0
- package/src/{lib/components → components}/Modal/_settings.scss +0 -0
- package/src/{lib/components → components}/Modal/_theme.scss +0 -0
- package/src/{lib/components → components}/Modal/index.js +0 -0
- package/src/{lib/components → components}/Paper/Paper.jsx +0 -0
- package/src/{lib/components → components}/Paper/Paper.scss +0 -0
- package/src/{lib/components → components}/Paper/_theme.scss +0 -0
- package/src/{lib/components → components}/Paper/index.js +0 -0
- package/src/{lib/components → components}/Popover/Popover.jsx +0 -0
- package/src/{lib/components → components}/Popover/Popover.scss +0 -0
- package/src/{lib/components → components}/Popover/PopoverWrapper.jsx +0 -0
- package/src/{lib/components → components}/Popover/PopoverWrapper.scss +0 -0
- package/src/{lib/components → components}/Popover/_helpers/getRootAlignmentClassName.js +0 -0
- package/src/{lib/components → components}/Popover/_helpers/getRootSideClassName.js +0 -0
- package/src/{lib/components → components}/Popover/_theme.scss +0 -0
- package/src/{lib/components → components}/Popover/index.js +0 -0
- package/src/{lib/components → components}/Radio/index.js +0 -0
- package/src/{lib/components → components}/ScrollView/ScrollView.scss +0 -0
- package/src/{lib/components → components}/ScrollView/_helpers/getElementsPositionDifference.js +0 -0
- package/src/{lib/components → components}/ScrollView/_hooks/useLoadResizeHook.js +0 -0
- package/src/{lib/components → components}/ScrollView/_hooks/useScrollPositionHook.js +0 -0
- package/src/{lib/components → components}/ScrollView/index.js +0 -0
- package/src/{lib/components → components}/SelectField/SelectField.jsx +0 -0
- package/src/{lib/components → components}/SelectField/SelectField.scss +0 -0
- package/src/{lib/components → components}/SelectField/_components/Option/Option.jsx +0 -0
- package/src/{lib/components → components}/SelectField/_components/Option/index.js +0 -0
- package/src/{lib/components → components}/SelectField/index.js +0 -0
- package/src/{lib/components → components}/Table/Table.scss +0 -0
- package/src/{lib/components → components}/Table/_components/TableBodyCell/TableBodyCell.jsx +0 -0
- package/src/{lib/components → components}/Table/_components/TableBodyCell/index.js +0 -0
- package/src/{lib/components → components}/Table/_components/TableCell.scss +0 -0
- package/src/{lib/components → components}/Table/_components/TableHeaderCell/index.js +0 -0
- package/src/{lib/components → components}/Table/_settings.scss +0 -0
- package/src/{lib/components → components}/Table/index.js +0 -0
- package/src/{lib/components → components}/Tabs/Tabs.jsx +0 -0
- package/src/{lib/components → components}/Tabs/Tabs.scss +0 -0
- package/src/{lib/components → components}/Tabs/TabsItem.scss +0 -0
- package/src/{lib/components → components}/Tabs/_theme.scss +0 -0
- package/src/{lib/components → components}/Tabs/index.js +0 -0
- package/src/{lib/components → components}/Text/Text.jsx +0 -0
- package/src/{lib/components → components}/Text/Text.scss +0 -0
- package/src/{lib/components → components}/Text/_helpers/getRootClampClassName.js +0 -0
- package/src/{lib/components → components}/Text/_helpers/getRootHyphensClassName.js +0 -0
- package/src/{lib/components → components}/Text/_helpers/getRootWordWrappingClassName.js +0 -0
- package/src/{lib/components → components}/Text/index.js +0 -0
- package/src/{lib/components → components}/TextArea/TextArea.jsx +0 -0
- package/src/{lib/components → components}/TextArea/TextArea.scss +0 -0
- package/src/{lib/components → components}/TextArea/index.js +0 -0
- package/src/{lib/components → components}/TextField/TextField.jsx +0 -0
- package/src/{lib/components → components}/TextField/TextField.scss +0 -0
- package/src/{lib/components → components}/TextField/index.js +0 -0
- package/src/{lib/components → components}/TextLink/TextLink.jsx +1 -1
- /package/src/{lib/components → components}/TextLink/TextLink.scss +0 -0
- /package/src/{lib/components → components}/TextLink/_theme.scss +0 -0
- /package/src/{lib/components → components}/TextLink/index.js +0 -0
- /package/src/{lib/components → components}/Toggle/Toggle.jsx +0 -0
- /package/src/{lib/components → components}/Toggle/Toggle.scss +0 -0
- /package/src/{lib/components → components}/Toggle/index.js +0 -0
- /package/src/{lib/components → components}/Toolbar/Toolbar.jsx +0 -0
- /package/src/{lib/components → components}/Toolbar/Toolbar.scss +0 -0
- /package/src/{lib/components → components}/Toolbar/ToolbarGroup.jsx +0 -0
- /package/src/{lib/components → components}/Toolbar/ToolbarItem.jsx +0 -0
- /package/src/{lib/components → components}/Toolbar/_helpers/getJustifyClassName.js +0 -0
- /package/src/{lib/components → components}/Toolbar/_theme.scss +0 -0
- /package/src/{lib/components → components}/Toolbar/index.js +0 -0
- /package/src/{lib/components → components}/_helpers/getRootColorClassName.js +0 -0
- /package/src/{lib/components → components}/_helpers/getRootSizeClassName.js +0 -0
- /package/src/{lib/components → components}/_helpers/getRootValidationStateClassName.js +0 -0
- /package/src/{lib/components → components}/_helpers/isChildrenEmpty.js +0 -0
- /package/src/{lib/components → components}/_helpers/resolveContextOrProp.js +0 -0
- /package/src/{lib/components → components}/_helpers/transferProps.js +0 -0
- /package/src/{lib/foundation.scss → foundation.scss} +0 -0
- /package/src/{lib/helpers.scss → helpers.scss} +0 -0
- /package/src/{lib/provider → provider}/RUIContext.jsx +0 -0
- /package/src/{lib/provider → provider}/index.js +0 -0
- /package/src/{lib/provider → provider}/withGlobalProps.jsx +0 -0
- /package/src/{lib/styles → styles}/_utilities.scss +0 -0
- /package/src/{lib/styles → styles}/elements/_code.scss +0 -0
- /package/src/{lib/styles → styles}/elements/_links.scss +0 -0
- /package/src/{lib/styles → styles}/elements/_lists.scss +0 -0
- /package/src/{lib/styles → styles}/elements/_page.scss +0 -0
- /package/src/{lib/styles → styles}/elements/_rulers.scss +0 -0
- /package/src/{lib/styles → styles}/elements/_small.scss +0 -0
- /package/src/{lib/styles → styles}/generic/_box-sizing.scss +0 -0
- /package/src/{lib/styles → styles}/generic/_focus.scss +0 -0
- /package/src/{lib/styles → styles}/generic/_forms.scss +0 -0
- /package/src/{lib/styles → styles}/generic/_reset.scss +0 -0
- /package/src/{lib/styles → styles}/generic/_shared.scss +0 -0
- /package/src/{lib/styles → styles}/helpers/_animation.scss +0 -0
- /package/src/{lib/styles → styles}/settings/_animations.scss +0 -0
- /package/src/{lib/styles → styles}/settings/_breakpoints.scss +0 -0
- /package/src/{lib/styles → styles}/settings/_escaped-characters.scss +0 -0
- /package/src/{lib/styles → styles}/settings/_form-fields.scss +0 -0
- /package/src/{lib/styles → styles}/settings/_forms.scss +0 -0
- /package/src/{lib/styles → styles}/settings/_utilities.scss +0 -0
- /package/src/{lib/styles → styles}/settings/_z-indexes.scss +0 -0
- /package/src/{lib/styles → styles}/theme/_accessibility.scss +0 -0
- /package/src/{lib/styles → styles}/theme/_borders.scss +0 -0
- /package/src/{lib/styles → styles}/theme/_code.scss +0 -0
- /package/src/{lib/styles → styles}/theme/_form-fields.scss +0 -0
- /package/src/{lib/styles → styles}/theme/_links.scss +0 -0
- /package/src/{lib/styles → styles}/theme/_lists.scss +0 -0
- /package/src/{lib/styles → styles}/theme/_page.scss +0 -0
- /package/src/{lib/styles → styles}/theme/_spacing.scss +0 -0
- /package/src/{lib/styles → styles}/theme/_typography.scss +0 -0
- /package/src/{lib/styles → styles}/theme-constants/_breakpoints.scss +0 -0
- /package/src/{lib/styles → styles}/theme-constants/_colors.scss +0 -0
- /package/src/{lib/styles → styles}/theme-constants/_svg.scss +0 -0
- /package/src/{lib/styles → styles}/tools/_accessibility.scss +0 -0
- /package/src/{lib/styles → styles}/tools/_breakpoint.scss +0 -0
- /package/src/{lib/styles → styles}/tools/_colors.scss +0 -0
- /package/src/{lib/styles → styles}/tools/_reset.scss +0 -0
- /package/src/{lib/styles → styles}/tools/_scrollbar.scss +0 -0
- /package/src/{lib/styles → styles}/tools/_spacing.scss +0 -0
- /package/src/{lib/styles → styles}/tools/_string.scss +0 -0
- /package/src/{lib/styles → styles}/tools/_svg.scss +0 -0
- /package/src/{lib/styles → styles}/tools/_transition.scss +0 -0
- /package/src/{lib/styles → styles}/tools/_utilities.scss +0 -0
- /package/src/{lib/styles → styles}/tools/form-fields/_box-field-layout.scss +0 -0
- /package/src/{lib/styles → styles}/tools/form-fields/_box-field-sizes.scss +0 -0
- /package/src/{lib/styles → styles}/tools/form-fields/_foundation.scss +0 -0
- /package/src/{lib/styles → styles}/tools/form-fields/_inline-field-layout.scss +0 -0
- /package/src/{lib/styles → styles}/tools/form-fields/_variants.scss +0 -0
- /package/src/{lib/translations → translations}/en.js +0 -0
- /package/src/{lib/utils → utils}/classNames.js +0 -0
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
# FormLayout
|
|
2
|
+
|
|
3
|
+
The FormLayout aligns form fields into an organized grid.
|
|
4
|
+
|
|
5
|
+
## Basic Usage
|
|
6
|
+
|
|
7
|
+
To implement the FormLayout component, you need to import it first:
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
import { FormLayout } from '@react-ui-org/react-ui';
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
And use it:
|
|
14
|
+
|
|
15
|
+
```docoff-react-preview
|
|
16
|
+
<FormLayout>
|
|
17
|
+
<TextField label="A form element" />
|
|
18
|
+
</FormLayout>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
See [API](#api) for all available options.
|
|
22
|
+
|
|
23
|
+
## General Guidelines
|
|
24
|
+
|
|
25
|
+
Since all form fields in React UI are styled as inline blocks, they **queue up
|
|
26
|
+
one after another in a row by default.** The FormLayout component is there to
|
|
27
|
+
make building **vertical and horizontal forms** easy. It uses the right tool for
|
|
28
|
+
the job: the [CSS grid layout][grid].
|
|
29
|
+
|
|
30
|
+
- Put **only form field components** from React UI inside the FormLayout and
|
|
31
|
+
make sure they are **direct descendants** of it (React [fragments] are
|
|
32
|
+
supported!). All React UI form components are ready for this use case and
|
|
33
|
+
don't need to be wrapped in any `div`s. Namely, the FormLayout supports the
|
|
34
|
+
following React UI components:
|
|
35
|
+
[CheckboxField](/components/CheckboxField),
|
|
36
|
+
[Radio](/components/Radio), [SelectField](/components/SelectField),
|
|
37
|
+
[TextArea](/components/TextArea), [TextField](/components/TextField),
|
|
38
|
+
and [Toggle](/components/Toggle).
|
|
39
|
+
|
|
40
|
+
- Use the [FormLayoutCustomField](#custom-fields) component when you need to
|
|
41
|
+
place any **custom content** inside the FormLayout. This layout helper ensures
|
|
42
|
+
your content is properly spaced and aligned with other FormLayout elements.
|
|
43
|
+
Do **not** try to put any custom HTML or React components directly into
|
|
44
|
+
FormLayout without wrapping it with the FormLayoutCustomField first.
|
|
45
|
+
|
|
46
|
+
👉 For usage in auto-width Modal, you may need to turn on the `autoWidth` option
|
|
47
|
+
for your FormLayout. This prevents FormLayout from unexpectedly growing in
|
|
48
|
+
browsers that [don't support][rui-232] [CSS subgrid][subgrid] in cases when
|
|
49
|
+
there are longer validation messages or help texts.
|
|
50
|
+
|
|
51
|
+
## Vertical Layout
|
|
52
|
+
|
|
53
|
+
Vertical FormLayout works similar to single-column [Grid](/components/Grid)
|
|
54
|
+
layout while it also forces vertical layout mode on form fields. To use this
|
|
55
|
+
layout, simply wrap your form fields with the FormLayout component:
|
|
56
|
+
|
|
57
|
+
```docoff-react-preview
|
|
58
|
+
<FormLayout>
|
|
59
|
+
<TextField label="A form element" />
|
|
60
|
+
<TextField label="Another form element" />
|
|
61
|
+
<TextField label="Yet another one" />
|
|
62
|
+
</FormLayout>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Horizontal Layout
|
|
66
|
+
|
|
67
|
+
Horizontal FormLayout is designed for horizontal form fields: it nicely **aligns
|
|
68
|
+
labels and inputs in an organized grid.** It is applied starting from the `md`
|
|
69
|
+
viewport size onward and it forces the horizontal layout on the fields.
|
|
70
|
+
|
|
71
|
+
```docoff-react-preview
|
|
72
|
+
<FormLayout fieldLayout="horizontal">
|
|
73
|
+
<TextField label="A form element" />
|
|
74
|
+
<TextField label="Another form element" />
|
|
75
|
+
<TextField label="Yet another one" />
|
|
76
|
+
</FormLayout>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Label Width
|
|
80
|
+
|
|
81
|
+
In the horizontal layout mode, it's possible to fine-tune the way how the form
|
|
82
|
+
will be aligned through the `labelWidth` option to cover various design
|
|
83
|
+
requirements. It comes with **three globally shared options:** default width,
|
|
84
|
+
auto width, and limited width. For cases where an individual manual width works
|
|
85
|
+
better, there is the **local custom width mode** which enables setting a width
|
|
86
|
+
that is applied just for the current FormLayout.
|
|
87
|
+
|
|
88
|
+
👉 All global label width options can be easily [customized](/docs/customize/theming/overview)
|
|
89
|
+
with CSS custom properties.
|
|
90
|
+
|
|
91
|
+
#### Label Width Options
|
|
92
|
+
|
|
93
|
+
- The `default` mode (global) sets the width of all labels to a **global default
|
|
94
|
+
value** which is 10 em.
|
|
95
|
+
|
|
96
|
+
- The `auto` mode (global) aligns the form **according to the longest label.**
|
|
97
|
+
|
|
98
|
+
- The `limited` mode (global) works as `auto` except it's intended for values
|
|
99
|
+
that **set a limit for the label width.** Its default value is
|
|
100
|
+
`fitcontent(50%)` which also aligns the form according to the longest label
|
|
101
|
+
like `auto`, but with the difference that the labels cannot be wider than
|
|
102
|
+
50 % of the FormLayout.
|
|
103
|
+
|
|
104
|
+
- The `custom` mode (local) allows you to enter any **custom label width for
|
|
105
|
+
individual FormLayouts.**
|
|
106
|
+
|
|
107
|
+
```docoff-react-preview
|
|
108
|
+
React.createElement(() => {
|
|
109
|
+
const [labelWidth, setLabelWidth] = React.useState('default');
|
|
110
|
+
const [customLabelWidth, setCustomLabelWidth] = React.useState('20em');
|
|
111
|
+
return (
|
|
112
|
+
<div>
|
|
113
|
+
<Toolbar align="baseline">
|
|
114
|
+
<ToolbarItem>
|
|
115
|
+
<span id="label-width-options-label">Label width:</span>
|
|
116
|
+
</ToolbarItem>
|
|
117
|
+
<ToolbarItem>
|
|
118
|
+
<ButtonGroup aria-labelledby="label-width-options-label">
|
|
119
|
+
<Button
|
|
120
|
+
color={labelWidth === 'default' ? 'selected' : 'secondary'}
|
|
121
|
+
label="default"
|
|
122
|
+
onClick={() => setLabelWidth('default')}
|
|
123
|
+
/>
|
|
124
|
+
<Button
|
|
125
|
+
color={labelWidth === 'auto' ? 'selected' : 'secondary'}
|
|
126
|
+
label="auto"
|
|
127
|
+
onClick={() => setLabelWidth('auto')}
|
|
128
|
+
/>
|
|
129
|
+
<Button
|
|
130
|
+
color={labelWidth === 'limited' ? 'selected' : 'secondary'}
|
|
131
|
+
label="limited"
|
|
132
|
+
onClick={() => setLabelWidth('limited')}
|
|
133
|
+
/>
|
|
134
|
+
<Button
|
|
135
|
+
color={labelWidth === 'custom' ? 'selected' : 'secondary'}
|
|
136
|
+
label="custom"
|
|
137
|
+
onClick={() => setLabelWidth('custom')}
|
|
138
|
+
/>
|
|
139
|
+
</ButtonGroup>
|
|
140
|
+
</ToolbarItem>
|
|
141
|
+
{labelWidth === 'custom' && (
|
|
142
|
+
<ToolbarItem>
|
|
143
|
+
<TextField
|
|
144
|
+
inputSize={5}
|
|
145
|
+
isLabelVisible={false}
|
|
146
|
+
label="Custom label width"
|
|
147
|
+
layout="horizontal"
|
|
148
|
+
onChange={(e) => setCustomLabelWidth(e.target.value)}
|
|
149
|
+
value={customLabelWidth}
|
|
150
|
+
/>
|
|
151
|
+
</ToolbarItem>
|
|
152
|
+
)}
|
|
153
|
+
</Toolbar>
|
|
154
|
+
<FormLayout
|
|
155
|
+
fieldLayout="horizontal"
|
|
156
|
+
labelWidth={labelWidth === 'custom' ? customLabelWidth : labelWidth}
|
|
157
|
+
>
|
|
158
|
+
<TextField label="A form element" />
|
|
159
|
+
<TextField
|
|
160
|
+
label={'Another form element with a very long label that is so '
|
|
161
|
+
+ 'long that in the auto mode, it should make the label column '
|
|
162
|
+
+ 'grow until the inputs reach the end of the line, but it will '
|
|
163
|
+
+ 'not exceed 50 % of the FormLayout width in the limited label '
|
|
164
|
+
+ 'width mode'}
|
|
165
|
+
/>
|
|
166
|
+
<TextField label="Yet another one" />
|
|
167
|
+
</FormLayout>
|
|
168
|
+
</div>
|
|
169
|
+
);
|
|
170
|
+
});
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Limitations
|
|
174
|
+
|
|
175
|
+
#### Label Position
|
|
176
|
+
|
|
177
|
+
Label position of inline form fields (CheckboxField, Toggle) is ignored in
|
|
178
|
+
horizontal FormLayout.
|
|
179
|
+
|
|
180
|
+
#### Modals
|
|
181
|
+
|
|
182
|
+
Please note the `auto` and `limited` label width options may not function
|
|
183
|
+
correctly in combination with other auto layout mechanisms, e.g. the auto-width
|
|
184
|
+
[Modal](/components/Modal). It's just too much of magic that does not quite
|
|
185
|
+
work together yet 🎩.
|
|
186
|
+
|
|
187
|
+
## Custom Fields
|
|
188
|
+
|
|
189
|
+
You can even place any content you need into the FormLayout — just wrap it with
|
|
190
|
+
the FormLayoutCustomField component. This layout
|
|
191
|
+
helper ensures your content is properly spaced and aligned with to other
|
|
192
|
+
FormLayout elements. FormLayoutCustomFields are designed to work solely inside
|
|
193
|
+
the FormLayout component.
|
|
194
|
+
|
|
195
|
+
```docoff-react-preview
|
|
196
|
+
<FormLayout fieldLayout="horizontal" labelWidth="auto">
|
|
197
|
+
<TextField label="A form element" />
|
|
198
|
+
<FormLayoutCustomField label="Optional custom field label">
|
|
199
|
+
<docoff-placeholder bordered>Custom field content</docoff-placeholder>
|
|
200
|
+
</FormLayoutCustomField>
|
|
201
|
+
<TextField label="Another form element" />
|
|
202
|
+
</FormLayout>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
👉 While you can set FormLayoutCustomField as `disabled`, `valid` or `required`
|
|
206
|
+
and its styles may affect contained form fields through CSS cascade, don't
|
|
207
|
+
forget to mirror the aforementioned properties to the contained form fields too
|
|
208
|
+
as API options as such are **not** inherited.
|
|
209
|
+
|
|
210
|
+
### Label Alignment
|
|
211
|
+
|
|
212
|
+
If you are in a situation with one or more box form fields inside your
|
|
213
|
+
FormLayoutCustomField, you may want to have its label aligned with the fields
|
|
214
|
+
inside. Since it's [not quite possible to do this automatically][rui-265] due to
|
|
215
|
+
limited browser support, there is `innerFieldSize` option which accepts any of
|
|
216
|
+
existing box field sizes (small, medium, or large) and is intended right for
|
|
217
|
+
this task.
|
|
218
|
+
|
|
219
|
+
```docoff-react-preview
|
|
220
|
+
<FormLayout fieldLayout="horizontal" labelWidth="auto">
|
|
221
|
+
<TextField label="A form element" />
|
|
222
|
+
<FormLayoutCustomField
|
|
223
|
+
innerFieldSize="medium"
|
|
224
|
+
label="Custom field label aligned to inner text input"
|
|
225
|
+
>
|
|
226
|
+
<TextField
|
|
227
|
+
isLabelVisible={false}
|
|
228
|
+
label="A form element"
|
|
229
|
+
placeholder="Text field with invisible label"
|
|
230
|
+
/>
|
|
231
|
+
</FormLayoutCustomField>
|
|
232
|
+
<TextField label="Another form element" />
|
|
233
|
+
</FormLayout>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Validation States
|
|
237
|
+
|
|
238
|
+
Custom fields support the same validation states as regular form fields to
|
|
239
|
+
provide labels with optional feedback style.
|
|
240
|
+
|
|
241
|
+
```docoff-react-preview
|
|
242
|
+
<FormLayout fieldLayout="horizontal" labelWidth="auto">
|
|
243
|
+
<TextField label="A form element" />
|
|
244
|
+
<FormLayoutCustomField
|
|
245
|
+
label="Custom field label in valid state"
|
|
246
|
+
validationState="valid"
|
|
247
|
+
>
|
|
248
|
+
<docoff-placeholder bordered>Custom field content</docoff-placeholder>
|
|
249
|
+
</FormLayoutCustomField>
|
|
250
|
+
<TextField label="Another form element" />
|
|
251
|
+
</FormLayout>
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Accessibility
|
|
255
|
+
|
|
256
|
+
If possible, use the `labelForId` option to provide ID of contained form field
|
|
257
|
+
so the field remains accessible via custom field label.
|
|
258
|
+
|
|
259
|
+
You can also specify size of contained form field so custom field label is
|
|
260
|
+
properly vertically aligned.
|
|
261
|
+
|
|
262
|
+
```docoff-react-preview
|
|
263
|
+
React.createElement(() => {
|
|
264
|
+
const [isChecked, setIsChecked] = React.useState(false);
|
|
265
|
+
return (
|
|
266
|
+
<FormLayout fieldLayout="horizontal" labelWidth="auto">
|
|
267
|
+
<TextField label="A form element" />
|
|
268
|
+
<FormLayoutCustomField
|
|
269
|
+
fullWidth
|
|
270
|
+
label="Custom field label aligned with medium form field"
|
|
271
|
+
labelForId="my-text-field-custom-accessibility-2"
|
|
272
|
+
innerFieldSize="medium"
|
|
273
|
+
>
|
|
274
|
+
<Toolbar align="middle" dense>
|
|
275
|
+
<ToolbarItem>
|
|
276
|
+
<TextField
|
|
277
|
+
isLabelVisible={false}
|
|
278
|
+
label="A form element"
|
|
279
|
+
placeholder="Text field with invisible label"
|
|
280
|
+
/>
|
|
281
|
+
</ToolbarItem>
|
|
282
|
+
<ToolbarItem>
|
|
283
|
+
<CheckboxField
|
|
284
|
+
checked={isChecked}
|
|
285
|
+
label="Another form field"
|
|
286
|
+
onChange={() => setIsChecked(!isChecked)}
|
|
287
|
+
/>
|
|
288
|
+
</ToolbarItem>
|
|
289
|
+
</Toolbar>
|
|
290
|
+
</FormLayoutCustomField>
|
|
291
|
+
<TextField label="Another form element" />
|
|
292
|
+
</FormLayout>
|
|
293
|
+
)
|
|
294
|
+
});
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## Full Example
|
|
298
|
+
|
|
299
|
+
This is a demo of all components supported by FormLayout.
|
|
300
|
+
|
|
301
|
+
```docoff-react-preview
|
|
302
|
+
React.createElement(() => {
|
|
303
|
+
const [fieldLayout, setFieldLayout] = React.useState('vertical');
|
|
304
|
+
const [fruit, setFruit] = React.useState('apple');
|
|
305
|
+
const [isDeliveryAddress, setIsDeliveryAddress] = React.useState(true);
|
|
306
|
+
const [receiveNewsletter, setReceiveNewsletter] = React.useState(true);
|
|
307
|
+
const options = [
|
|
308
|
+
{
|
|
309
|
+
label: 'Apple',
|
|
310
|
+
value: 'apple',
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
label: 'Banana',
|
|
314
|
+
value: 'banana',
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
label: 'Grapefruit',
|
|
318
|
+
value: 'grapefruit',
|
|
319
|
+
},
|
|
320
|
+
];
|
|
321
|
+
return (
|
|
322
|
+
<div>
|
|
323
|
+
<Toolbar>
|
|
324
|
+
<ToolbarItem>
|
|
325
|
+
<ButtonGroup>
|
|
326
|
+
<Button
|
|
327
|
+
color={fieldLayout === 'vertical' ? 'selected' : 'secondary'}
|
|
328
|
+
label="Vertical layout"
|
|
329
|
+
onClick={() => setFieldLayout('vertical')}
|
|
330
|
+
/>
|
|
331
|
+
<Button
|
|
332
|
+
color={fieldLayout === 'horizontal' ? 'selected' : 'secondary'}
|
|
333
|
+
label="Horizontal layout"
|
|
334
|
+
onClick={() => setFieldLayout('horizontal')}
|
|
335
|
+
/>
|
|
336
|
+
</ButtonGroup>
|
|
337
|
+
</ToolbarItem>
|
|
338
|
+
</Toolbar>
|
|
339
|
+
<FormLayout fieldLayout={fieldLayout} labelWidth="auto">
|
|
340
|
+
<>
|
|
341
|
+
<TextField
|
|
342
|
+
label="First Name"
|
|
343
|
+
/>
|
|
344
|
+
<TextField
|
|
345
|
+
label="Last Name"
|
|
346
|
+
/>
|
|
347
|
+
</>
|
|
348
|
+
<TextField
|
|
349
|
+
helpText="Optional"
|
|
350
|
+
label="Email address"
|
|
351
|
+
type="email"
|
|
352
|
+
/>
|
|
353
|
+
<>
|
|
354
|
+
<TextField
|
|
355
|
+
label="Address"
|
|
356
|
+
placeholder="Address line 1"
|
|
357
|
+
/>
|
|
358
|
+
<TextField
|
|
359
|
+
isLabelVisible={false}
|
|
360
|
+
label="Address 2"
|
|
361
|
+
placeholder="Address line 2"
|
|
362
|
+
/>
|
|
363
|
+
<TextField
|
|
364
|
+
inputSize={6}
|
|
365
|
+
label="ZIP"
|
|
366
|
+
validationState="invalid"
|
|
367
|
+
validationText="ZIP should be 5 to 6 digits long code."
|
|
368
|
+
/>
|
|
369
|
+
<FormLayoutCustomField label="Country">
|
|
370
|
+
<span>Czech Republic</span>
|
|
371
|
+
</FormLayoutCustomField>
|
|
372
|
+
<CheckboxField
|
|
373
|
+
checked={isDeliveryAddress}
|
|
374
|
+
helpText="Uncheck if you wish to deliver to a different address."
|
|
375
|
+
label="This is my delivery address"
|
|
376
|
+
onChange={() => setIsDeliveryAddress(!isDeliveryAddress)}
|
|
377
|
+
/>
|
|
378
|
+
</>
|
|
379
|
+
<SelectField
|
|
380
|
+
label="Your favourite fruit"
|
|
381
|
+
onChange={(e) => setFruit(e.target.value)}
|
|
382
|
+
options={options}
|
|
383
|
+
value={fruit}
|
|
384
|
+
/>
|
|
385
|
+
<TextArea
|
|
386
|
+
fullWidth
|
|
387
|
+
label="Message"
|
|
388
|
+
rows={3}
|
|
389
|
+
/>
|
|
390
|
+
<FileInputField
|
|
391
|
+
label="Attachment"
|
|
392
|
+
/>
|
|
393
|
+
<Toggle
|
|
394
|
+
checked={receiveNewsletter}
|
|
395
|
+
helpText="Only once per week!"
|
|
396
|
+
label="Receive weekly newsletter"
|
|
397
|
+
onChange={() => setReceiveNewsletter(!receiveNewsletter)}
|
|
398
|
+
required
|
|
399
|
+
/>
|
|
400
|
+
<Radio
|
|
401
|
+
label="And fruit again!"
|
|
402
|
+
onChange={(e) => setFruit(e.target.value)}
|
|
403
|
+
options={options}
|
|
404
|
+
value={fruit}
|
|
405
|
+
/>
|
|
406
|
+
<InputGroup label="Promo code">
|
|
407
|
+
<TextField label="Code" />
|
|
408
|
+
<Button label="Apply" color="secondary" priority="outline" />
|
|
409
|
+
</InputGroup>
|
|
410
|
+
</FormLayout>
|
|
411
|
+
</div>
|
|
412
|
+
)
|
|
413
|
+
});
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
## Forwarding HTML Attributes
|
|
417
|
+
|
|
418
|
+
In addition to the options below in the [component's API](#api) section, you
|
|
419
|
+
can specify [React synthetic events] or **any HTML attribute you like.** All
|
|
420
|
+
attributes that don't interfere with the API are forwarded to the root `<div>`
|
|
421
|
+
HTML element. This enables making the component interactive and helps to improve
|
|
422
|
+
its accessibility.
|
|
423
|
+
|
|
424
|
+
👉 Refer to the MDN reference for the full list of supported attributes of the
|
|
425
|
+
[div] element.
|
|
426
|
+
|
|
427
|
+
## API
|
|
428
|
+
|
|
429
|
+
<docoff-react-props src="/components/FormLayout/FormLayout.jsx"></docoff-react-props>
|
|
430
|
+
|
|
431
|
+
### FormLayoutCustomField API
|
|
432
|
+
|
|
433
|
+
A place for custom content inside FormLayout.
|
|
434
|
+
|
|
435
|
+
<docoff-react-props src="/components/FormLayout/FormLayoutCustomField.jsx"></docoff-react-props>
|
|
436
|
+
|
|
437
|
+
## Theming
|
|
438
|
+
|
|
439
|
+
| Custom Property | Description |
|
|
440
|
+
|------------------------------------------------------|--------------------------------------------------------------|
|
|
441
|
+
| `--rui-FormLayout__row-gap` | Gap between individual rows |
|
|
442
|
+
| `--rui-FormLayout--horizontal__label__width` | Default label width |
|
|
443
|
+
| `--rui-FormLayout--horizontal__label__width--auto` | Label width in automatic layout |
|
|
444
|
+
| `--rui-FormLayout--horizontal__label__width--limited` | Label width in limited-width layout |
|
|
445
|
+
|
|
446
|
+
### FormLayoutCustomField Theming
|
|
447
|
+
|
|
448
|
+
FormLayoutCustomField can be styled using a small subset of
|
|
449
|
+
[other form fields theming options](/docs/customize/theming/forms).
|
|
450
|
+
|
|
451
|
+
| Custom Property | Description |
|
|
452
|
+
|------------------------------------------------------|--------------------------------------------------------------|
|
|
453
|
+
| `--rui-FormField--custom--default__surrounding-text-color` | Custom field label color in default state |
|
|
454
|
+
| `--rui-FormField--custom--disabled__surrounding-text-color` | Custom field label color in disabled-like state |
|
|
455
|
+
|
|
456
|
+
[grid]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout
|
|
457
|
+
[subgrid]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Subgrid
|
|
458
|
+
[fragments]: https://reactjs.org/docs/fragments.html
|
|
459
|
+
[rui-232]: https://github.com/react-ui-org/react-ui/issues/232
|
|
460
|
+
[rui-265]: https://github.com/react-ui-org/react-ui/issues/265
|
|
461
|
+
[React synthetic events]: https://reactjs.org/docs/events.html
|
|
462
|
+
[div]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes
|
|
@@ -118,7 +118,7 @@ Grid.propTypes = {
|
|
|
118
118
|
*/
|
|
119
119
|
children: PropTypes.node,
|
|
120
120
|
/**
|
|
121
|
-
* Gap between columns. Accepts any of [spacing values](/foundation/spacing-values) as number.
|
|
121
|
+
* Gap between columns. Accepts any of [spacing values](/docs/foundation/spacing-values) as number.
|
|
122
122
|
* See [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/column-gap) for more about `column-gap`.
|
|
123
123
|
*/
|
|
124
124
|
columnGap: PropTypes.oneOfType([
|
|
@@ -182,7 +182,7 @@ Grid.propTypes = {
|
|
|
182
182
|
}),
|
|
183
183
|
]),
|
|
184
184
|
/**
|
|
185
|
-
* Gap between rows. Accepts any of [spacing values](/foundation/spacing-values) as number.
|
|
185
|
+
* Gap between rows. Accepts any of [spacing values](/docs/foundation/spacing-values) as number.
|
|
186
186
|
* See [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/row-gap) for more about `row-gap`.
|
|
187
187
|
*/
|
|
188
188
|
rowGap: PropTypes.oneOfType([
|