Skip to content

Commit

Permalink
Add forceFocus prop to <FormControl />
Browse files Browse the repository at this point in the history
  • Loading branch information
dmtrKovalenko committed Mar 25, 2020
1 parent 6d62842 commit 970d9a0
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 3 deletions.
1 change: 1 addition & 0 deletions docs/pages/api-docs/form-control.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ You can find one composition example below and more going to [the demos](/compon
| <span class="prop-name">component</span> | <span class="prop-type">elementType</span> | <span class="prop-default">'div'</span> | The component used for the root node. Either a string to use a DOM element or a component. |
| <span class="prop-name">disabled</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the label, input and helper text should be displayed in a disabled state. |
| <span class="prop-name">error</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the label should be displayed in an error state. |
| <span class="prop-name">forceFocus</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | Force displaying input in focused state |
| <span class="prop-name">fullWidth</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the component will take up the full width of its container. |
| <span class="prop-name">hiddenLabel</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the label will be hidden. This is used to increase density for a `FilledInput`. Be sure to add `aria-label` to the `input` element. |
| <span class="prop-name">margin</span> | <span class="prop-type">'none'<br>&#124;&nbsp;'dense'<br>&#124;&nbsp;'normal'</span> | <span class="prop-default">'none'</span> | If `dense` or `normal`, will adjust vertical spacing of this and contained components. |
Expand Down
1 change: 1 addition & 0 deletions packages/material-ui/src/FormControl/FormControl.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export interface FormControlTypeMap<P = {}, D extends React.ElementType = 'div'>
disabled?: boolean;
error?: boolean;
fullWidth?: boolean;
forceFocus?: boolean;
hiddenLabel?: boolean;
margin?: PropTypes.Margin;
required?: boolean;
Expand Down
12 changes: 9 additions & 3 deletions packages/material-ui/src/FormControl/FormControl.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const FormControl = React.forwardRef(function FormControl(props, ref) {
disabled = false,
error = false,
fullWidth = false,
forceFocus = false,
hiddenLabel = false,
margin = 'none',
required = false,
Expand All @@ -83,7 +84,7 @@ const FormControl = React.forwardRef(function FormControl(props, ref) {
let initialAdornedStart = false;

if (children) {
React.Children.forEach(children, (child) => {
React.Children.forEach(children, child => {
if (!isMuiElement(child, ['Input', 'Select'])) {
return;
}
Expand All @@ -104,7 +105,7 @@ const FormControl = React.forwardRef(function FormControl(props, ref) {
let initialFilled = false;

if (children) {
React.Children.forEach(children, (child) => {
React.Children.forEach(children, child => {
if (!isMuiElement(child, ['Input', 'Select'])) {
return;
}
Expand All @@ -118,7 +119,8 @@ const FormControl = React.forwardRef(function FormControl(props, ref) {
return initialFilled;
});

const [focused, setFocused] = React.useState(false);
const [_focused, setFocused] = React.useState(false);
const focused = forceFocus || _focused;

if (disabled && focused) {
setFocused(false);
Expand Down Expand Up @@ -229,6 +231,10 @@ FormControl.propTypes = {
* If `true`, the label should be displayed in an error state.
*/
error: PropTypes.bool,
/**
* If `true`, the component will be displayed in focused state.
*/
forceFocus: PropTypes.bool,
/**
* If `true`, the component will take up the full width of its container.
*/
Expand Down
16 changes: 16 additions & 0 deletions packages/material-ui/src/FormControl/FormControl.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,22 @@ describe('<FormControl />', () => {
});
});

describe.only('prop: forceFocus', () => {
it('should display input in focused state', () => {
const readContext = spy();
const { container } = render(
<FormControl forceFocus>
<Input />
<TestComponent contextCallback={readContext} />
</FormControl>,
);

expect(readContext.args[0][0]).to.have.property('focused', true);
container.querySelector('input').blur();
expect(readContext.args[0][0]).to.have.property('focused', true);
});
});

describe('input', () => {
it('should be filled when a value is set', () => {
const readContext = spy();
Expand Down

0 comments on commit 970d9a0

Please sign in to comment.