-
Notifications
You must be signed in to change notification settings - Fork 863
[EuiForm] specify default fullWidth with root component #6229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 9 commits
564e188
f538077
e590265
7376450
50b8c8d
fa97aa7
251ab99
53950f9
301afc4
bca771e
1dafc38
303968c
814de11
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| import React from 'react'; | ||
|
|
||
| import { | ||
| EuiForm, | ||
| EuiFieldSearch, | ||
| EuiRange, | ||
| EuiTextArea, | ||
| EuiFormRow, | ||
| EuiFlexGroup, | ||
| EuiFlexItem, | ||
| EuiSpacer, | ||
| EuiDescribedFormGroup, | ||
| EuiSelect, | ||
| EuiFilePicker, | ||
| EuiButton, | ||
| } from '../../../../src/components'; | ||
|
|
||
| export default () => { | ||
| const [range, setRange] = React.useState(42); | ||
|
|
||
| return ( | ||
| <EuiForm | ||
| fullWidth | ||
| onSubmit={(e) => { | ||
| e.preventDefault(); | ||
| }} | ||
| > | ||
| <EuiFlexGroup> | ||
| <EuiFlexItem> | ||
| <EuiFieldSearch | ||
| placeholder="Search..." | ||
| aria-label="An example of search with fullWidth" | ||
| /> | ||
| </EuiFlexItem> | ||
| <EuiFlexItem grow={false}> | ||
| <EuiButton>Search</EuiButton> | ||
| </EuiFlexItem> | ||
| </EuiFlexGroup> | ||
|
|
||
| <EuiSpacer size="l" /> | ||
|
|
||
| <EuiFormRow | ||
| label="Works on form rows too" | ||
| helpText="Note that the fullWidth prop is not passed to any of these elements, it's read from the parent <EuiForm> component." | ||
| > | ||
| <EuiRange | ||
| min={0} | ||
| max={100} | ||
| name="range" | ||
| value={range} | ||
| onChange={(e) => { | ||
| if (e.target instanceof HTMLInputElement) { | ||
| setRange(Number.parseInt(e.target.value, 10)); | ||
| } | ||
| }} | ||
| /> | ||
| </EuiFormRow> | ||
|
|
||
| <EuiSpacer /> | ||
|
|
||
| <EuiDescribedFormGroup | ||
| title={<h3>Works with all form controls and layout components</h3>} | ||
| description={ | ||
| <> | ||
| <p> | ||
| Any component that supports the <code>fullWidth</code> prop that | ||
| is. | ||
| </p> | ||
| <p> | ||
| Make sure it is appropriate at all of the widths that the | ||
| container can take. There are many situations where a full-width | ||
| form is inappropriate. | ||
| </p> | ||
| </> | ||
| } | ||
| > | ||
| <EuiFormRow label="Text area"> | ||
| <EuiTextArea placeholder="" /> | ||
| </EuiFormRow> | ||
| </EuiDescribedFormGroup> | ||
|
|
||
| <EuiFormRow label="Works on EuiSelect"> | ||
| <EuiSelect | ||
| options={[ | ||
| { | ||
| value: 'option_one', | ||
| text: | ||
| 'Option one is very long in order to try justifying the use of fullWidth on a select box', | ||
| }, | ||
| { value: 'option_two', text: 'Option two' }, | ||
| { value: 'option_three', text: 'Option three' }, | ||
| ]} | ||
| /> | ||
| </EuiFormRow> | ||
|
|
||
| <EuiFormRow label="Works on EuiFilePicker"> | ||
| <EuiFilePicker display="default" /> | ||
| </EuiFormRow> | ||
| </EuiForm> | ||
| ); | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,6 +20,7 @@ import { | |
| EuiFlexGroupGutterSize, | ||
| EuiFlexItemProps, | ||
| } from '../../flex'; | ||
| import { useFormContext } from '../eui_form_context'; | ||
|
|
||
| export type EuiDescribedFormGroupProps = CommonProps & | ||
| Omit<HTMLAttributes<HTMLDivElement>, 'title'> & { | ||
|
|
@@ -29,17 +30,21 @@ export type EuiDescribedFormGroupProps = CommonProps & | |
| children?: ReactNode; | ||
| /** | ||
| * Passed to `EuiFlexGroup`. | ||
| * @default l | ||
| */ | ||
| gutterSize?: EuiFlexGroupGutterSize; | ||
| /** | ||
| * Expand to fill 100% of the parent. | ||
| * Defaults to `fullWidth` prop of `<EuiForm>`. | ||
| * Default max-width is 800px. | ||
| * @default false | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So... one downside about pulling defaults out of context is that
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Super awesome workaround/find on this! Totally agreed we could stand to use more |
||
| */ | ||
| fullWidth?: boolean; | ||
| /** | ||
| * Width ratio of description column compared to field column. | ||
| * Can be used in conjunction with `fullWidth` and | ||
| * may require `fullWidth` to be applied to child elements. | ||
| * @default half | ||
| */ | ||
| ratio?: 'half' | 'third' | 'quarter'; | ||
| /** | ||
|
|
@@ -48,6 +53,7 @@ export type EuiDescribedFormGroupProps = CommonProps & | |
| title: EuiTitleProps['children']; | ||
| /** | ||
| * Adjust the visual `size` of the EuiTitle that wraps `title`. | ||
| * @default xs | ||
| */ | ||
| titleSize?: EuiTitleSize; | ||
| /** | ||
|
|
@@ -64,19 +70,24 @@ export type EuiDescribedFormGroupProps = CommonProps & | |
| fieldFlexItemProps?: PropsOf<typeof EuiFlexItem>; | ||
| }; | ||
|
|
||
| export const EuiDescribedFormGroup: FunctionComponent<EuiDescribedFormGroupProps> = ({ | ||
| children, | ||
| className, | ||
| gutterSize = 'l', | ||
| fullWidth = false, | ||
| ratio = 'half', | ||
| titleSize = 'xs', | ||
| title, | ||
| description, | ||
| descriptionFlexItemProps, | ||
| fieldFlexItemProps, | ||
| ...rest | ||
| }) => { | ||
| export const EuiDescribedFormGroup: FunctionComponent<EuiDescribedFormGroupProps> = ( | ||
| props | ||
| ) => { | ||
| const { defaultFullWidth } = useFormContext(); | ||
|
|
||
| const { | ||
| children, | ||
| className, | ||
| gutterSize = 'l', | ||
| fullWidth = defaultFullWidth, | ||
| ratio = 'half', | ||
| titleSize = 'xs', | ||
| title, | ||
| description, | ||
| descriptionFlexItemProps, | ||
| fieldFlexItemProps, | ||
| ...rest | ||
| } = props; | ||
| const classes = classNames( | ||
| 'euiDescribedFormGroup', | ||
| { | ||
|
|
@@ -93,18 +104,16 @@ export const EuiDescribedFormGroup: FunctionComponent<EuiDescribedFormGroupProps | |
| let renderedDescription: ReactNode; | ||
|
|
||
| if (description) { | ||
| // If the description is just a string, wrap it in a paragraph element | ||
| if (typeof description === 'string') { | ||
| description = <p>{description}</p>; | ||
| } | ||
|
|
||
| renderedDescription = ( | ||
| <EuiText | ||
| size="s" | ||
| color="subdued" | ||
| className="euiDescribedFormGroup__description" | ||
| > | ||
| {description} | ||
| { | ||
| // If the description is just a string, wrap it in a paragraph element | ||
| typeof description === 'string' ? <p>{description}</p> : description | ||
| } | ||
| </EuiText> | ||
| ); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License | ||
| * 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
| * in compliance with, at your election, the Elastic License 2.0 or the Server | ||
| * Side Public License, v 1. | ||
| */ | ||
|
|
||
| import React from 'react'; | ||
|
|
||
| export interface FormContextValue { | ||
| defaultFullWidth: boolean; | ||
| } | ||
|
|
||
| export const FormContext = React.createContext<FormContextValue>({ | ||
| defaultFullWidth: false, | ||
| }); | ||
|
|
||
| export function useFormContext() { | ||
| return React.useContext(FormContext); | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you've got opinions about better docs/example please feel free to re-write anything 😅 Just wanted to make sure we had an example of this actually working in several of the components.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me! I think my only comment would be to make the title have sentence casing, per our copy guidelines
After looking at it a bit more closely, I'm not totally sure if we should just combine the Full-width and Global full-width examples into 1 single example though - @miukimiu, any thoughts here? We can definitely address that after this PR merges though TBH