Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
mui-styling
Advanced tools
Utilities for building sustainable React Material-UI components
Material-UI is a great react-component library. it has a lot of base components and styling pattern is all about javascript. Jss means you don't need to write .css, .scss or do the compiling stuffs (it is the part I love the most). But! there will be the day that you need customized components or very specific ones. Theses are problems that I found.
I spend a lot of time solving these questions, and the solution lies in mui-styling
mui-styling
will help you
unleash the potential of Material-UI without external library (because it is based on @material-ui/styles
)
npm install mui-styling
// or
yarn add mui-styling
withStyles(styleCreator: fn, options?: object)
this is the same withStyles
from @material-ui/styles
. it is exported here for convenient.
Example
import React from 'react';
import { withStyles } from 'mui-styling';
const createStyles = () => ({
childRoot: {},
childDot: { fontSize: 32, lineHeight: 1 },
});
const Child = withStyles(createStyles)(({ classes }) => {
// withStyles will inject an object(named "classes") as props
// classes = { childRoot: '{autogen className}', childDot: '{autogen className}' }
return (
<div className={css.childRoot}>
<span className={css.childDot}>•</span>
</div>
);
});
expot default Child;
attachStylingParams(Component: React.Component, styleCreator: fn, options: object)
This fn will attach these properties stylesAttrs
, pickClasses
and getOverrides
to the Component
Example;
import React from 'react';
import PropTypes from 'prop-types';
import { attachStylingParams, withStyles } from 'mui-styling';
const createStyles = () => ({
childRoot: {},
childDot: { fontSize: 32, lineHeight: 1 },
});
const options = { name: 'Child' };
const Child = withStyles(createStyles, options)(({ classes, overrides }) => {
const css = overrides || classes;
return (
<div className={css.childRoot}>
<span className={css.childDot}>•</span>
</div>
);
});
Child.propTypes = {
overrides: PropTypes.shape({}),
classes: PropTypes.shape({}),
};
Child.defaultProps = {
overrides: undefined,
classes: undefined,
};
attachStylingParams(Child, createStyles, options);
// Now 'Child' have these properties that will be used in other components
// Child.styleAttrs: ['childRoot', 'childDot'];
// Child.pickClasses: fn;
// Child.getOverrides: fn;
export default Child;
styleAttrs
is an array of attributes that come from createStyles resultpickClasses
is a fn that will pick only attributes that are defined in styleAttrsgetOverrides
is a fn that return overrides props to the componentmergeStyleCreators(...creators: arrayOf(styleCreator))
This fn is used when you create complex component that consist of multiple components it returns a new styleCreator
Example
import { mergeStyleCreators } from 'mui-styling';
const createChildStyles = () => ({
childRoot: {
color: 'red',
},
})
const createParentStyles = mergeStyleCreators(
createChildStyles,
() => ({
parentRoot: {
display: 'flex',
},
})
)
** The benefit of this fn is that it **warns** you when it find attributes collision.
Example of attributes collision
import { mergeStyleCreators } from 'mui-styling';
const createChildStyles = () => ({
childRoot: {
color: 'red',
},
general: { fontSize: 16 },
})
const createParentStyles = mergeStyleCreators(
createChildStyles,
() => ({
parentRoot: {
display: 'flex',
},
general: { fontSize: 16 },
})
)
In console
> mui-styling: Styles collision alert! attributes: [general]. This might cause bugs in styling, please check these style attributes
this example show how to create nested components with mui-styling
Child.styles.js
export default () => ({
childRoot: {},
childDot: { fontSize: 32, lineHeight: 1 },
});
Child.js
import React from 'react';
import PropTypes from 'prop-types';
import { attachStylingParams, withStyles } from 'mui-styling';
import createStyles from './Child.styles';
const options = { name: 'Child' };
const Child = withStyles(createStyles, options)(({ classes, overrides }) => {
const css = overrides || classes;
return (
<div className={css.childRoot}>
<span className={css.childDot}>•</span>
</div>
);
});
attachStylingParams(Child, createStyles, options);
export default Child;
Parent.styles.js
import { mergeStyleCreators } from 'mui-styling';
import { createStyles as createChildStyles } from '../Child';
export default mergeStyleCreators(createChildStyles, () => ({
parentRoot: {
display: 'flex',
alignItems: 'center',
minHeight: 32,
padding: '0 16px',
'&:hover': {
backgroundColor: '#f7f7f7',
},
},
parentLabel: {
margin: '0 auto 0 0',
},
}));
Parent.js
import React from 'react';
import PropTypes from 'prop-types';
import Child from './Child';
import { attachStylingParams, withStyles } from 'mui-styling';
import createStyles from './Parent.styles';
const options = { name: 'Parent' };
const Parent = withStyles(createStyles, options)(props => {
const { classes, overrides, label } = props;
const css = overrides || classes;
return (
<div className={css.parentRoot}>
<p className={css.parentLabel}>{label}</p>
<Child {...Child.getOverrides(css, props)} />
</div>
);
});
attachStylingParams(Parent, createStyles, options);
export default Parent;
Root.styles.js
import { mergeStyleCreators } from 'mui-styling';
import { createStyles as createParentStyles } from '../Parent';
export default mergeStyleCreators(createParentStyles, () => ({
root: {},
}));
Root.js
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Parent from './Parent';
import { attachStylingParams } from 'mui-styling';
import createStyles from './Root.styles';
const options = { name: 'Root' };
const Root = withStyles(createStyles, options)(props => {
const { items, classes, overrides, childOverrides } = props;
const css = overrides || classes;
return (
<div className={css.root}>
{items.map(label => (
<Parent
key={label}
label={label}
childOverrides={childOverrides}
{...Parent.getOverrides(css, props)}
/>
))}
</div>
);
});
Root.displayName = 'Root';
attachStylingParams(Root, createStyles, options);
export default Root;
Page.js
This is where we use the Root component and try to customize it
import { makeStyles } from '@material-ui/styles';
import Root from './Root';
import Parent from './Parent';
import createParentStyles from './Parent.styles';
const useCustomStyles = makeStyles(({ palette }) => ({
// as you can see, we can access every css api of the components
// there is no magic, I just found the way to make it works
// my code is easy as it looks, see in my repo
parentRoot: {
'&:hover': {
'& $parentLabel, $childDot': {
color: palette.primary.main,
},
},
},
parentLabel: {},
childDot: {},
}));
const useOverrideStyles = makeStyles(theme => ({
root: {
boxShadow: '0 0 4px 0 rgba(0,0,0,0.32)',
},
parentRoot: {
...createParentStyles(theme).parentRoot,
'&:hover': {
backgroundColor: theme.palette.primary.main,
'& $parentLabel, $childDot': {
// as you can see, you can override nested component with this approach
color: '#fff',
},
},
},
parentLabel: {},
childRoot: {
marginLeft: 'auto',
},
childDot: {},
test: {}, // this will not effect styling since it is not related to style attrs defined in Root
}));
const ITEMS = ['Siriwat', 'Kotchakorn', 'Hello World', 'Programming'];
const CustomRoot1 = () => {
const styles = useCustomStyles();
return <Root items={ITEMS} classes={styles} />;
};
const OverrideRoot1 = () => {
const styles = useOverrideStyles();
return <Root items={ITEMS} overrides={styles} />;
};
use jest & enzyme
yarn test
MIT
FAQs
Utilities for building reusable & sustainable Material-UI components
The npm package mui-styling receives a total of 0 weekly downloads. As such, mui-styling popularity was classified as not popular.
We found that mui-styling demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.