Skip to content

Instantly share code, notes, and snippets.

@burdiuz
Last active December 29, 2019 19:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save burdiuz/9d6bd463f73ee476de6d1cb3432eac4a to your computer and use it in GitHub Desktop.
Save burdiuz/9d6bd463f73ee476de6d1cb3432eac4a to your computer and use it in GitHub Desktop.
@actualwave/react-native-with-style -- HoC to provide base style for a component that merges with style provided via props

@actualwave/react-native-with-style

withStyle() HoC to provide base style for a component that merges with style provided via props

import React, { useMemo } from 'react';
import PropTypes from 'prop-types';
import getComponentName from '@actualwave/react-component-name';
import callIfFunction from '@actualwave/call-if-function';
const WrapperPropTypes = {
style: PropTypes.any,
};
const WrapperDefaultProps = {
style: undefined,
};
const withStyle = (Component, baseStyleParam, displayName = '') => {
const Wrapper = (props) => {
const { style } = props;
const baseStyle = callIfFunction(baseStyleParam, props);
const computedStyle = useMemo(() => (style ? [baseStyle, style] : baseStyle), [style]);
return <Component {...props} style={computedStyle} />;
};
Wrapper.propTypes = {
...WrapperPropTypes,
...Component.propTypes,
};
Wrapper.defaultProps = {
...WrapperDefaultProps,
...Component.defaultProps,
};
Wrapper.displayName = displayName || `withStyle(${getComponentName(Component)})`;
return Wrapper;
};
export const withStyles = (Component, styles = {}, displayName = '') => {
const styleKeys = Object.keys(styles);
const Wrapper = (props) => {
const combinedStyles = useMemo(
() => {
const styleProps = {};
styleKeys.forEach((key) => {
const defaultStyle = callIfFunction(styles[key], props);
const { [key]: style } = props;
if (defaultStyle) {
styleProps[key] = style ? [defaultStyle, style] : defaultStyle;
}
});
return styleProps;
},
styleKeys.map((name) => props[name]),
);
return <Component {...props} {...combinedStyles} />;
};
Wrapper.propTypes = {
...WrapperPropTypes,
...Component.propTypes,
};
Wrapper.defaultProps = {
...WrapperDefaultProps,
...Component.defaultProps,
};
Wrapper.displayName = displayName || `withStyles(${getComponentName(Component)}, "${styleKeys.join('", "')}")`;
return Wrapper;
};
export default withStyle;
{
"name": "@actualwave/react-native-with-style",
"description": "withStyle() HoC to provide base style for a component that merges with style provided via props",
"version": "0.0.1",
"main": "index.js",
"keywords": [
"js",
"javascript",
"react",
"react-native",
"component",
"style"
],
"homepage": "https://github.com/burdiuz/9d6bd463f73ee476de6d1cb3432eac4a",
"bugs": {
"url": "https://github.com/burdiuz/9d6bd463f73ee476de6d1cb3432eac4a",
"email": "burdiuz@gmail.com"
},
"author": {
"name": "Oleg Galaburda",
"email": "burdiuz@gmail.com",
"url": "http://actualwave.com/"
},
"dependencies": {
"@actualwave/call-if-function": "^0.0.1",
"@actualwave/react-component-name": "^0.0.1"
},
"peerDependencies": {
"prop-types": "*",
"react": "*"
},
"license": "MIT"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment