@vitus-labs/rocketstyle
Version:
Rocketstyle is ultra powerful and extensible styling system for building React components blazingly fast, easily and make them easily extensible and reusable.
767 lines (744 loc) • 30 kB
JavaScript
import { context as context$1, Provider as Provider$1, isEmpty, render, set, get, merge, config, pick, omit, compose } from '@vitus-labs/core';
export { context } from '@vitus-labs/core';
import React, { createContext, useContext, useState, useCallback, useRef, useImperativeHandle, forwardRef, useMemo } from 'react';
import hoistNonReactStatics from 'hoist-non-react-statics';
const MODE_DEFAULT = 'light';
const PSEUDO_KEYS = ['hover', 'active', 'focus', 'pressed'];
const PSEUDO_META_KEYS = ['disabled', 'readOnly'];
const THEME_MODES = {
light: true,
dark: true,
};
const THEME_MODES_INVERSED = {
dark: 'light',
light: 'dark',
};
const CONFIG_KEYS = [
'provider',
'consumer',
'DEBUG',
'name',
'component',
'inversed',
'passProps',
'styled',
];
const STYLING_KEYS = ['theme', 'styles'];
const STATIC_KEYS = [...STYLING_KEYS, 'compose'];
const ALL_RESERVED_KEYS = [
...Object.keys(THEME_MODES),
...CONFIG_KEYS,
...STATIC_KEYS,
'attrs',
];
const context = createContext({});
const useLocalContext = (consumer) => {
const ctx = consumer ? useContext(context) : {};
const result = consumer ? consumer((callback) => callback(ctx)) : {};
return { pseudo: {}, ...result };
};
const LocalProvider = context.Provider;
const usePseudoState = ({ onBlur, onFocus, onMouseDown, onMouseEnter, onMouseLeave, onMouseUp, }) => {
const [hover, setHover] = useState(false);
const [focus, setFocus] = useState(false);
const [pressed, setPressed] = useState(false);
const handleOnMouseEnter = useCallback((e) => {
setHover(true);
if (onMouseEnter)
onMouseEnter(e);
}, [onMouseEnter]);
const handleOnMouseLeave = useCallback((e) => {
setHover(false);
setPressed(false);
if (onMouseLeave)
onMouseLeave(e);
}, [onMouseLeave]);
const handleOnMouseDown = useCallback((e) => {
setPressed(true);
if (onMouseDown)
onMouseDown(e);
}, [onMouseDown]);
const handleOnMouseUp = useCallback((e) => {
setPressed(false);
if (onMouseUp)
onMouseUp(e);
}, [onMouseUp]);
const handleOnFocus = useCallback((e) => {
setFocus(true);
if (onFocus)
onFocus(e);
}, [onFocus]);
const handleOnBlur = useCallback((e) => {
setFocus(false);
if (onBlur)
onBlur(e);
}, [onBlur]);
return {
state: {
hover,
focus,
pressed,
},
events: {
onMouseEnter: handleOnMouseEnter,
onMouseLeave: handleOnMouseLeave,
onMouseDown: handleOnMouseDown,
onMouseUp: handleOnMouseUp,
onFocus: handleOnFocus,
onBlur: handleOnBlur,
},
};
};
const useRocketstyleRef = ({ $rocketstyleRef, ref }) => {
const internalRef = useRef(null);
useImperativeHandle($rocketstyleRef, () => internalRef.current);
useImperativeHandle(ref, () => internalRef.current);
return internalRef;
};
const Provider = ({ provider = Provider$1, inversed, ...props }) => {
const ctx = useContext(context$1);
const { theme, mode, provider: RocketstyleProvider, children, } = { ...ctx, ...props, provider };
let newMode = MODE_DEFAULT;
if (mode) {
newMode = inversed ? THEME_MODES_INVERSED[mode] : mode;
}
return (React.createElement(RocketstyleProvider, { mode: newMode, isDark: newMode === 'dark', isLight: newMode === 'light', theme: theme, provider: provider }, children));
};
const useThemeAttrs = ({ inversed }) => {
const { theme = {}, mode: ctxMode = 'light', isDark: ctxDark, } = useContext(context$1) || {};
const mode = inversed ? THEME_MODES_INVERSED[ctxMode] : ctxMode;
const isDark = inversed ? !ctxDark : ctxDark;
const isLight = !isDark;
return { theme, mode, isDark, isLight };
};
const RocketStyleProviderComponent = (WrappedComponent) => forwardRef(({ onMouseEnter, onMouseLeave, onMouseUp, onMouseDown, onFocus, onBlur, $rocketstate, ...props }, ref) => {
// pseudo hook to detect states hover / pressed / focus
const pseudo = usePseudoState({
onMouseEnter,
onMouseLeave,
onMouseUp,
onMouseDown,
onFocus,
onBlur,
});
const updatedState = useMemo(() => ({
...$rocketstate,
pseudo: { ...$rocketstate.pseudo, ...pseudo.state },
}), [$rocketstate, pseudo]);
return (React.createElement(LocalProvider, { value: updatedState },
React.createElement(WrappedComponent, { ...props, ...pseudo.events, ref: ref, "$rocketstate": updatedState })));
});
class ThemeManager {
baseTheme = new WeakMap();
dimensionsThemes = new WeakMap();
modeBaseTheme = { light: new WeakMap(), dark: new WeakMap() };
modeDimensionTheme = { light: new WeakMap(), dark: new WeakMap() };
}
/* eslint-disable no-param-reassign */
const removeUndefinedProps = (props) => Object.keys(props).reduce((acc, key) => {
const currentValue = props[key];
if (currentValue !== undefined)
return { ...acc, [key]: currentValue };
return acc;
}, {});
const pickStyledAttrs = (props, keywords) => Object.keys(props).reduce((acc, key) => {
if (keywords[key] && props[key])
acc[key] = props[key];
return acc;
}, {});
const calculateChainOptions = (options) => (args) => {
const result = {};
if (isEmpty(options))
return result;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return options.reduce((acc, item) => Object.assign(acc, item(...args)), {});
};
const calculateStylingAttrs = ({ useBooleans, multiKeys }) => ({ props, dimensions }) => {
const result = {};
// (1) find dimension keys values & initialize
// object with possible options
Object.keys(dimensions).forEach((item) => {
const pickedProp = props[item];
const valueTypes = ['number', 'string'];
// if the property is multi key, allow assign array as well
if (multiKeys && multiKeys[item] && Array.isArray(pickedProp)) {
result[item] = pickedProp;
}
// assign when it's only a string or number otherwise it's considered
// as invalid param
else if (valueTypes.includes(typeof pickedProp)) {
result[item] = pickedProp;
}
else {
result[item] = undefined;
}
});
// (2) if booleans are being used let's find the rest
if (useBooleans) {
const propsKeys = Object.keys(props).reverse();
Object.entries(result).forEach(([key, value]) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const isMultiKey = multiKeys[key];
// when value in result is not assigned yet
if (!value) {
let newDimensionValue;
const keywords = Object.keys(dimensions[key]);
if (isMultiKey) {
newDimensionValue = propsKeys.filter((key) => keywords.includes(key));
}
else {
// reverse props to guarantee the last one will have
// a priority over previous ones
newDimensionValue = propsKeys.find((key) => {
if (keywords.includes(key) && props[key])
return key;
return false;
});
}
result[key] = newDimensionValue;
}
});
}
return result;
};
/* eslint-disable no-underscore-dangle */
const rocketStyleHOC = ({ inversed, attrs, priorityAttrs }) => {
// --------------------------------------------------
// .attrs(...)
// first we need to calculate final props which are
// being returned by using `attr` chaining method
// --------------------------------------------------
const calculateAttrs = calculateChainOptions(attrs);
const calculatePriorityAttrs = calculateChainOptions(priorityAttrs);
const Enhanced = (WrappedComponent) => forwardRef((props, ref) => {
const { theme, mode, isDark, isLight } = useThemeAttrs({
inversed,
});
const callbackParams = [theme, { render, mode, isDark, isLight }];
// --------------------------------------------------
// remove undefined props not to override potential default props
// only props with value (e.g. `null`) should override default props
// --------------------------------------------------
const filteredProps = removeUndefinedProps(props);
const prioritizedAttrs = calculatePriorityAttrs([
filteredProps,
...callbackParams,
]);
const finalAttrs = calculateAttrs([
{
...prioritizedAttrs,
...filteredProps,
},
...callbackParams,
]);
return (React.createElement(WrappedComponent, { "$rocketstyleRef": ref, ...prioritizedAttrs, ...finalAttrs, ...filteredProps }));
});
return Enhanced;
};
const createStaticsChainingEnhancers = ({ context, dimensionKeys, func, options, }) => {
const keys = [...dimensionKeys, ...STATIC_KEYS];
keys.forEach((item) => {
// eslint-disable-next-line no-param-reassign
context[item] = (props) => func(options, { [item]: props });
});
};
const createStaticsEnhancers = ({ context, options, }) => {
if (!isEmpty(options)) {
Object.assign(context, options);
}
};
/* eslint-disable import/prefer-default-export */
const removeNullableValues = (obj) => Object.entries(obj)
.filter(([, v]) => v != null && v !== false)
.reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {});
// --------------------------------------------------------
// Remove All Empty Values
// --------------------------------------------------------
// type RemoveAllEmptyValues = (obj: Record<string, any>) => Record<string, any>
// export const removeAllEmptyValues: RemoveAllEmptyValues = (obj) =>
// Object.entries(obj)
// .filter(([, v]) => v != null)
// .reduce(
// (acc, [k, v]) => ({
// ...acc,
// [k]: typeof v === 'object' ? removeAllEmptyValues(v) : v,
// }),
// {}
// )
const isValidKey = (value) => value !== undefined && value !== null && value !== false;
const isMultiKey = (value) => {
if (typeof value === 'object' && value !== null)
return [true, get(value, 'propName')];
return [false, value];
};
const getDimensionsMap = ({ themes, useBooleans }) => {
const result = {
keysMap: {},
keywords: {},
};
if (isEmpty(themes))
return result;
return Object.entries(themes).reduce((accumulator, [key, value]) => {
const { keysMap, keywords } = accumulator;
keywords[key] = true;
Object.entries(value).forEach(([itemKey, itemValue]) => {
if (!isValidKey(itemValue))
return;
if (useBooleans) {
keywords[itemKey] = true;
}
set(keysMap, [key, itemKey], true);
});
return accumulator;
}, result);
};
const getKeys = (obj) => Object.keys(obj);
const getValues = (obj) => Object.values(obj);
const getDimensionsValues = (obj) => getValues(obj).map((item) => {
if (typeof item === 'object') {
return item.propName;
}
return item;
});
const getMultipleDimensions = (obj) => getValues(obj).reduce((accumulator, value) => {
if (typeof value === 'object') {
// eslint-disable-next-line no-param-reassign
if (value.multi === true)
accumulator[value.propName] = true;
}
return accumulator;
}, {});
/* eslint-disable no-param-reassign */
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// --------------------------------------------------------
// Theme Mode Callback
// --------------------------------------------------------
const themeModeCallback = (light, dark) => (mode) => {
if (!mode || mode === 'light')
return light;
return dark;
};
const isModeCallback = (value) => typeof value === 'function' &&
//@ts-ignore
value.toString() === themeModeCallback().toString();
const getThemeFromChain = (options, theme) => {
const result = {};
if (!options || isEmpty(options))
return result;
return options.reduce((acc, item) => merge(acc, item(theme, themeModeCallback, config.css)), result);
};
const getDimensionThemes = (theme, options) => {
const result = {};
if (isEmpty(options.dimensions))
return result;
return Object.entries(options.dimensions).reduce((acc, [key, value]) => {
const [, dimension] = isMultiKey(value);
const helper = options[key];
if (Array.isArray(helper) && helper.length > 0) {
const finalDimensionThemes = getThemeFromChain(helper, theme);
// eslint-disable-next-line no-param-reassign
acc[dimension] = removeNullableValues(finalDimensionThemes);
}
return acc;
}, result);
};
const getTheme = ({ rocketstate, themes, baseTheme }) => {
// generate final theme which will be passed to styled component
let finalTheme = { ...baseTheme };
Object.entries(rocketstate).forEach(([key, value]) => {
const keyTheme = themes[key];
if (Array.isArray(value)) {
value.forEach((item) => {
finalTheme = merge({}, finalTheme, keyTheme[item]);
});
}
else {
finalTheme = merge({}, finalTheme, keyTheme[value]);
}
});
return finalTheme;
};
const getThemeByMode = (object, mode) => Object.keys(object).reduce((acc, key) => {
const value = object[key];
if (typeof value === 'object' && value !== null) {
acc[key] = getThemeByMode(value, mode);
}
else if (isModeCallback(value)) {
acc[key] = value(mode);
}
else {
acc[key] = value;
}
return acc;
}, {});
const chainOptions = (opts, defaultOpts = []) => {
const result = [...defaultOpts];
if (typeof opts === 'function')
result.push(opts);
else if (typeof opts === 'object')
result.push(() => opts);
return result;
};
const chainOrOptions = (keys, opts, defaultOpts) => keys.reduce((acc, item) => ({ ...acc, [item]: opts[item] || defaultOpts[item] }), {});
const chainReservedKeyOptions = (keys, opts, defaultOpts) => keys.reduce((acc, item) => ({
...acc,
[item]: chainOptions(opts[item], defaultOpts[item]),
}), {});
const calculateHocsFuncs = (options = {}) => Object.values(options)
.filter((item) => typeof item === 'function')
.reverse();
/* eslint-disable import/prefer-default-export */
const calculateStyles = (styles) => {
if (!styles)
return [];
return styles.map((item) => item(config.css));
};
/* eslint-disable @typescript-eslint/ban-ts-comment */
/* eslint-disable no-underscore-dangle */
const cloneAndEnhance = (defaultOpts, opts) =>
// @ts-ignore
rocketComponent({
...defaultOpts,
attrs: chainOptions(opts.attrs, defaultOpts.attrs),
filterAttrs: [
...(defaultOpts.filterAttrs ?? []),
...(opts.filterAttrs ?? []),
],
priorityAttrs: chainOptions(opts.priorityAttrs, defaultOpts.priorityAttrs),
statics: { ...defaultOpts.statics, ...opts.statics },
compose: { ...defaultOpts.compose, ...opts.compose },
...chainOrOptions(CONFIG_KEYS, opts, defaultOpts),
...chainReservedKeyOptions([...defaultOpts.dimensionKeys, ...STYLING_KEYS], opts, defaultOpts),
});
// --------------------------------------------------------
// styleComponent
// helper function which allows function chaining
// always returns a valid React component with static functions
// assigned, so it can be even rendered as a valid component
// or styles can be extended via its statics
// --------------------------------------------------------
// @ts-ignore
const rocketComponent = (options) => {
const { component, styles, DEBUG } = options;
const { styled } = config;
const _calculateStylingAttrs = calculateStylingAttrs({
multiKeys: options.multiKeys,
useBooleans: options.useBooleans,
});
const componentName = options.name ?? options.component.displayName ?? options.component.name;
// create styled component with all options.styles if available
const STYLED_COMPONENT = component.IS_ROCKETSTYLE ?? options.styled !== true
? component
: styled(component) `
${calculateStyles(styles)};
`;
// --------------------------------------------------------
// COMPONENT - Final component to be rendered
// --------------------------------------------------------
const RenderComponent = options.provider
? RocketStyleProviderComponent(STYLED_COMPONENT)
: STYLED_COMPONENT;
// --------------------------------------------------------
// THEME - Cached & Calculated theme(s)
// --------------------------------------------------------
const ThemeManager$1 = new ThemeManager();
// --------------------------------------------------------
// COMPOSE - high-order components
// --------------------------------------------------------
const hocsFuncs = [
rocketStyleHOC(options),
...calculateHocsFuncs(options.compose),
];
// --------------------------------------------------------
// ENHANCED COMPONENT (returned component)
// --------------------------------------------------------
// .attrs() chaining option is calculated in HOC and passed as props already
// @ts-ignore
// eslint-disable-next-line react/display-name
const EnhancedComponent = forwardRef(({ $rocketstyleRef, // it's forwarded from HOC which is always on top of all hocs
...props }, ref) => {
// --------------------------------------------------
// handle refs
// (1) one is passed from inner HOC - $rocketstyleRef
// (2) second one is used to be used directly (e.g. inside hocs)
// --------------------------------------------------
const internalRef = useRocketstyleRef({ $rocketstyleRef, ref });
// --------------------------------------------------
// hover - focus - pressed state passed via context from parent component
// --------------------------------------------------
const localCtx = useLocalContext(options.consumer);
// --------------------------------------------------
// general theme and theme mode dark / light passed in context
// --------------------------------------------------
const { theme, mode } = useThemeAttrs(options);
// --------------------------------------------------
// calculate themes for all defined styling dimensions
// .theme(...) + defined dimensions like .states(...), .sizes(...), etc.
// --------------------------------------------------
// --------------------------------------------------
// BASE / DEFAULT THEME Object
// --------------------------------------------------
const baseTheme = useMemo(() => {
const helper = ThemeManager$1.baseTheme;
if (!helper.has(theme)) {
helper.set(theme, getThemeFromChain(options.theme, theme));
}
return helper.get(theme);
},
// recalculate this only when theme mode changes dark / light
[theme]);
// --------------------------------------------------
// DIMENSION(S) THEMES Object
// --------------------------------------------------
const themes = useMemo(() => {
const helper = ThemeManager$1.dimensionsThemes;
if (!helper.has(theme)) {
helper.set(theme, getDimensionThemes(theme, options));
}
return helper.get(theme);
},
// recalculate this only when theme object changes
[theme]);
// --------------------------------------------------
// BASE / DEFAULT MODE THEME Object
// --------------------------------------------------
const currentModeBaseTheme = useMemo(() => {
const helper = ThemeManager$1.modeBaseTheme[mode];
if (!helper.has(baseTheme)) {
helper.set(baseTheme, getThemeByMode(baseTheme, mode));
}
return helper.get(baseTheme);
},
// recalculate this only when theme mode changes dark / light
[mode, baseTheme]);
// --------------------------------------------------
// DIMENSION(S) MODE THEMES Object
// --------------------------------------------------
const currentModeThemes = useMemo(() => {
const helper = ThemeManager$1.modeDimensionTheme[mode];
if (!helper.has(themes)) {
helper.set(themes, getThemeByMode(themes, mode));
}
return helper.get(themes);
},
// recalculate this only when theme mode changes dark / light
[mode, themes]);
// --------------------------------------------------
// calculate reserved Keys defined in dimensions as styling keys
// there is no need to calculate this each time - keys are based on
// dimensions definitions
// --------------------------------------------------
const { keysMap: dimensions, keywords: reservedPropNames } = useMemo(() => getDimensionsMap({
themes,
useBooleans: options.useBooleans,
}), [themes]);
const RESERVED_STYLING_PROPS_KEYS = useMemo(() => Object.keys(reservedPropNames), [reservedPropNames]);
// --------------------------------------------------
// get final props which are (latest has the highest priority):
// (1) merged styling from context,
// (2) `attrs` chaining method, and from
// (3) passing them directly to component
// --------------------------------------------------
const { pseudo, ...mergeProps } = {
...localCtx,
...props,
};
// --------------------------------------------------
// pseudo rocket state
// calculate final component pseudo state including pseudo state
// from props and override by pseudo props from context
// --------------------------------------------------
const pseudoRocketstate = {
...pseudo,
...pick(props, [...PSEUDO_KEYS, ...PSEUDO_META_KEYS]),
};
// --------------------------------------------------
// rocketstate
// calculate final component state including pseudo state
// passed as $rocketstate prop
// --------------------------------------------------
const rocketstate = _calculateStylingAttrs({
props: pickStyledAttrs(mergeProps, reservedPropNames),
dimensions,
});
const finalRocketstate = { ...rocketstate, pseudo: pseudoRocketstate };
// --------------------------------------------------
// rocketstyle
// calculated (based on styling props) final theme which will be passed
// to our styled component
// passed as $rocketstyle prop
// --------------------------------------------------
const rocketstyle = getTheme({
rocketstate,
themes: currentModeThemes,
baseTheme: currentModeBaseTheme,
});
// --------------------------------------------------
// final props
// final props passed to WrappedComponent
// excluding: styling props
// including: $rocketstyle, $rocketstate
// --------------------------------------------------
const finalProps = {
// this removes styling state from props and passes its state
// under rocketstate key only
...omit(mergeProps, [
...RESERVED_STYLING_PROPS_KEYS,
...PSEUDO_KEYS,
...options.filterAttrs,
]),
// if enforced to pass styling props, we pass them directly
...(options.passProps ? pick(mergeProps, options.passProps) : {}),
ref: ref ?? $rocketstyleRef ? internalRef : undefined,
// state props passed to styled component only, therefore the `$` symbol
$rocketstyle: rocketstyle,
$rocketstate: finalRocketstate,
};
if (DEBUG && process.env.NODE_ENV !== 'production') {
console.log('[Rocketstyle] Debug mode enabled');
console.log(`component ${componentName}`);
console.log(finalProps);
}
// all the development stuff injected
if (process.env.NODE_ENV !== 'production') {
finalProps['data-rocketstyle'] = componentName;
}
return React.createElement(RenderComponent, { ...finalProps });
});
// ------------------------------------------------------
// This will hoist and generate dynamically next static methods
// for all dimensions available in configuration
// ------------------------------------------------------
const RocketComponent = compose(...hocsFuncs)(EnhancedComponent);
RocketComponent.IS_ROCKETSTYLE = true;
RocketComponent.displayName = componentName;
hoistNonReactStatics(RocketComponent, options.component);
// ------------------------------------------------------
// enhance for chaining methods
// ------------------------------------------------------
createStaticsChainingEnhancers({
context: RocketComponent,
dimensionKeys: options.dimensionKeys,
func: cloneAndEnhance,
options,
});
// ------------------------------------------------------
RocketComponent.IS_ROCKETSTYLE = true;
RocketComponent.displayName = componentName;
RocketComponent.meta = {};
// ------------------------------------------------------
// ------------------------------------------------------
// enhance for statics
// ------------------------------------------------------
createStaticsEnhancers({
context: RocketComponent.meta,
options: options.statics,
});
// @ts-ignore
RocketComponent.attrs = (attrs, { priority, filter } = {}) => {
const result = {};
if (filter) {
result.filterAttrs = filter;
}
if (priority) {
result.priorityAttrs = attrs;
return cloneAndEnhance(options, result);
}
result.attrs = attrs;
return cloneAndEnhance(options, result);
};
// @ts-ignore
RocketComponent.config = (opts = {}) => {
const result = pick(opts, CONFIG_KEYS);
// @ts-ignore
return cloneAndEnhance(options, result);
};
RocketComponent.statics = (opts) =>
// @ts-ignore
cloneAndEnhance(options, { statics: opts });
RocketComponent.getStaticDimensions = (theme) => {
const themes = getDimensionThemes(theme, options);
const { keysMap, keywords } = getDimensionsMap({
themes,
useBooleans: options.useBooleans,
});
return {
dimensions: keysMap,
keywords,
useBooleans: options.useBooleans,
multiKeys: options.multiKeys,
};
};
RocketComponent.getDefaultAttrs = (props, theme, mode) => calculateChainOptions(options.attrs)([
props,
theme,
{
render,
mode,
isDark: mode === 'light',
isLight: mode === 'dark',
},
]);
return RocketComponent;
};
const DEFAULT_DIMENSIONS = {
states: 'state',
sizes: 'size',
variants: 'variant',
multiple: {
propName: 'multiple',
multi: true,
},
};
// @ts-nocheck
const rocketstyle = ({ dimensions = DEFAULT_DIMENSIONS, useBooleans = true } = {}) => ({ name, component }) => {
// --------------------------------------------------------
// handle ERRORS in development mode
// --------------------------------------------------------
if (process.env.NODE_ENV !== 'production') {
const errors = {};
if (!component) {
errors.component = 'Parameter `component` is missing in params!';
}
if (!name) {
errors.name = 'Parameter `name` is missing in params!';
}
if (isEmpty(dimensions)) {
errors.dimensions = 'Parameter `dimensions` is missing in params!';
}
else {
const definedDimensions = getKeys(dimensions);
const invalidDimension = ALL_RESERVED_KEYS.some((item) => definedDimensions.includes(item));
if (invalidDimension) {
errors.invalidDimensions = `Some of your \`dimensions\` is invalid and uses reserved static keys which are
${DEFAULT_DIMENSIONS.toString()}`;
}
}
if (!isEmpty(errors)) {
throw Error(JSON.stringify(errors));
}
}
return rocketComponent({
name,
component,
useBooleans,
dimensions,
dimensionKeys: getKeys(dimensions),
dimensionValues: getDimensionsValues(dimensions),
multiKeys: getMultipleDimensions(dimensions),
styled: true,
});
};
const isRocketComponent = (component) => {
if (component &&
typeof component === 'object' &&
component !== null &&
Object.prototype.hasOwnProperty.call(component, 'IS_ROCKETSTYLE')) {
return true;
}
return false;
};
export { Provider, rocketstyle as default, isRocketComponent, rocketstyle };
//# sourceMappingURL=index.js.map