Skip to content
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

Make sure that select has multiple attribute set to appropriate state before appending options #13270

Merged
merged 7 commits into from Aug 3, 2018
19 changes: 19 additions & 0 deletions fixtures/dom/src/components/fixtures/selects/index.js
Expand Up @@ -158,6 +158,25 @@ class SelectFixture extends React.Component {
</form>
</div>
</TestCase>

<TestCase title="A multiple selec being scrolled to first selected option">
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: selec

<TestCase.ExpectedResult>
First selected option should be visible
</TestCase.ExpectedResult>

<div className="test-fixture">
<form ref={n => (this._multipleFormDOMNode = n)}>
<select multiple defaultValue={['tiger']}>
<option value="gorilla">gorilla</option>
<option value="giraffe">giraffe</option>
<option value="monkey">monkey</option>
<option value="lion">lion</option>
<option value="mongoose">mongoose</option>
<option value="tiger">tiget</option>
</select>
</form>
</div>
</TestCase>
</FixtureSet>
);
}
Expand Down
6 changes: 6 additions & 0 deletions packages/react-dom/src/client/ReactDOMFiberComponent.js
Expand Up @@ -378,6 +378,12 @@ export function createElement(
// See discussion in https://github.com/facebook/react/pull/6896
// and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
domElement = ownerDocument.createElement(type);
// Make sure that `select` has `multiple` attribute set to appropriate state before appending options
// To prevent first option be initialy made selected
// see more details in https://github.com/facebook/react/issues/13222
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't perfect, but could you update this comment to read like:

// Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple`
// attribute on `select`s needs to be added before `option`s are inserted. This prevents 
// a bug where the `select` does not scroll to the correct option because singular 
// `select` elements automatically pick the first item.
// See https://github.com/facebook/react/issues/13222

@gaearon Could this be clearer?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change the comment to the suggestion in the discussion thread

if (type === 'select' && !!props.multiple) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this context !! is redundant. You can drop it.

domElement.setAttribute('multiple', 'true');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use property assignment in the postMountWrapper, could you do the same here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

postMountWrapper attempts to update options, but as at this moment select doesn't have any child appended, it makes no sense, it will iterate over empty options collection. However it should not cause any problems so if you think it is better approach I can do this change.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for consistence with ReactDOMFiberSelect, can you assign this as a property, like:

domElement.multiple = true

}
}
} else {
domElement = ownerDocument.createElementNS(namespaceURI, type);
Expand Down