Suggestion: Move component identifiers to common constants
See original GitHub issueDescription
Going through v1-alpha branch code I’ve noticed that in some places (like a few, but I’m sure this will grow with time) there are ‘hardcoded’ component names/identifiers, which in my opinion don’t scale well. To improve that I suggest to move all component identifiers (values assigned as muiName
) to a separate file as importable constants (eg. in src/internal/identifiers.js
or constants.js
).
Alternative approach would be to export them directly from components, but I feel it’s more handy to just
import { identifier1, identifier2 } from '../internal/identifiers';
rather than
import { identifier1 } from '../Component1';
import { identifier2 } from '../Component2/SubComponent';
Also muiName
itself could be stored there:
import { MUI_NAME_PROP, MY_COMPONENT } from '../internal/identifiers';
// ...
MyComponent[MUI_NAME_PROP] = MY_COMPONENT;
Or event abstracted away to helpers:
import { setMuiName, MY_COMPONENT } from '../internal/identifiers';
// sets static property on MyComponent
setMuiName(MyComponent, MY_COMPONENT);
import { isMuiComponent, OTHER_COMPONENT } from '../internal/identifiers';
// isMuiComponent could be something simple as:
const isMuiComponent = (component, type) =>
component && component.type && component.type.muiName === type;
if (isMuiComponent(component, OTHER_COMPONENT)) {
// do magic
}
Same approach could/should be most likely used for default style sheet names (eg. MuiCard
, MuiListItem
etc.) as currently these keys are duplicated in component file (createStyleSheet
) as well as in src/styles/muiThemeProviderFactory.js
. I’d suggest something storing them in src/internal
directory as jssIdentifiers.js
or styleSheetIdentifiers.js
, but to me it’s not as important as clearing component logic (muiName
s).
References
Current code:
// material-ui/src/List/ListItem.js
// line ~138
const hasAvatar = children.some(value => {
return value.type && value.type.muiName === 'ListItemAvatar';
});
// line ~168
if (
children.length &&
children[children.length - 1].type &&
children[children.length - 1].type.muiName === 'ListItemSecondaryAction'
) {
Suggestion:
import { LIST_ITEM_AVATAR, LIST_ITEM_SECONDARY_ACTION } from '../internal/identifiers';
const hasAvatar = children.some(value => {
return value.type && value.type.muiName === LIST_ITEM_AVATAR;
});
if (
children.length &&
children[children.length - 1].type &&
children[children.length - 1].type.muiName === LIST_ITEM_SECONDARY_ACTION
) {
// or
const childrenLength = children.length;
if (childrenLength && isMuiComponent(children[childrenLength - 1], LIST_ITEM_SECONDARY_ACTION)) {
–
Current:
// src/IconButton/IconButton.js
if (child.type && child.type.muiName === 'Icon') {
return cloneElement(child, {
className: classNames(classes.icon, child.props.className),
});
}
Suggestion:
if (isMuiComponent(child, ICON)) {
return cloneElement(child, {
className: classNames(classes.icon, child.props.className),
});
}
–
Current:
// src/form/FormControl.js
Children.forEach(this.props.children, child => {
if (child && child.type && child.type.muiName === 'Input' && isDirty(child.props, true)) {
this.setState({ dirty: true });
}
});
Suggestion:
import { isMuiComponent, INPUT } from '../internal/identifiers';
Children.forEach(this.props.children, child => {
if (isMuiComponent(child, INPUT) && isDirty(child.props, true)) {
this.setState({ dirty: true });
}
});
–
I’d love to submit a PR, but first I wanted to make sure this is something you guys see useful as well 😃
Thanks!
Issue Analytics
- State:
- Created 6 years ago
- Comments:10 (10 by maintainers)
+1 for the
isMuiComponent
.Hmm. I couldn’t think of any valid use case, I guess I slightly misunderstood your previous comment (
The property is already prefixed with mui in order to avoid that issue, isn't that enough?
).