DEV Community

Cover image for Super flexible container
Carlos Andrés Mora González
Carlos Andrés Mora González

Posted on

Super flexible container

SitoContainer

Super flexible container, very similar to @mui's Box

First!

1 - Create a new react app

If you are using yarn (I recommended it)

yarn create react-app <container-name>

or if you like to use npm

npx create-react-app <container-name>

if everything goes fine you will have a page like this one at localhost:3000 (if port 3000 is not busy):

Image description

Next!

2 - Install @emotion

Emotion is a library designed for writing css styles with JavaScript. It provides powerful and predictable style composition in addition to a great developer experience with features such as source maps, labels, and testing utilities. Both string and object styles are supported.

dependencies:

yarn add @emotion/css @emotion/react @emotion/styled

or with npm:

npm install @emotion/css @emotion/react @emotion/styled

Time to CODE!

3 - Create your container component

You can remove other files in /src folder, all but index.js and App.js

Go to your App.js file at /src directory, in this file you will find this one:

import logo from "./logo.svg";
import "./App.css";

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

We will remove all of these and will create your new component, in this case your container component, in this tutorial will be SitoContainer:

function SitoContainer() {
  return <div></div>;
}

export default SitoContainer;
Enter fullscreen mode Exit fullscreen mode

Well now our container should render its children, so let's import PropTypes from prop-types

import PropTypes from "prop-types";

function SitoContainer(props) {

  const { children } = props;

  return <div>{children}</div>;
}

SitoContainer.defaultProps = {
  children: <></>,
};

SitoContainer.propTypes = {
  children: PropTypes.node,
};

export default SitoContainer;
Enter fullscreen mode Exit fullscreen mode

Ok, now we should allow our future users to customize our component with their CSS rules, so let's add other props, like:

  • sx (styled-components like MUI)
  • style (inline-style)
  • className (css classname)
import PropTypes from "prop-types";

import { css } from "@emotion/css";

function SitoContainer(props) {
  const { children, className, sx, style } = props;

  // IMPORTANT!!!
  // this is for turn your styled-components rules as dynamic 
  // @emotion/css class
  const newSx = css({sx});

  return (
    <div className={`${className} ${newSx}`} style={style}>
      {children}
    </div>
  );
}

SitoContainer.defaultProps = {
  className: "",
  sx: {},
  style: {},
  children: <></>,
};

SitoContainer.propTypes = {
  children: PropTypes.node,
  className: PropTypes.string,
  sx: PropTypes.oneOfType([
    PropTypes.arrayOf(
      PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])
    ),
    PropTypes.func,
    PropTypes.object,
  ]),
  style: PropTypes.oneOfType([
    PropTypes.arrayOf(
      PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])
    ),
    PropTypes.func,
    PropTypes.object,
  ]),
};

export default SitoContainer;
Enter fullscreen mode Exit fullscreen mode

Note that PropTypes of style and sx props are really tedious, this is because these props can be almost anything

Well our container is almost done, we can add other props like:

  • id (html identification)
  • display (flex, block, etc.) In my case I added:
  • background (string)
  • fullWidth (boolean)
  • flexDirection (row, column, etc)

You can check in my github repo

Finally!

4 - Bundle your container and publish it

Create a file with the name .babelrc containing:

{
  "presets": [
    [
      "@babel/preset-react",
      {
        "runtime": "automatic"
      }
    ]
  ]
}
Enter fullscreen mode Exit fullscreen mode

This is for support for the experimental syntax jsx, if you want to look futher, read here

Install two dev dependencies:

yarn add @babel/cli @babel/preset-react

or with npm:

npm install @babel/cli @babel/preset-react

Add this script to your package.json:

"publish:npm": "babel src/ -d dist --copy-files"

and this line, also to your package.json:

"main":"dist/App.js"

This last part is for tell to npm, or yarn, where to look your modules when a user install them
Use for local test npm install my-package where my-package is the root folder of your package, in this case our container

If everything goes fine, on the command line, navigate to the root directory of your package and run to publish your package:

npm publish

for more instructions read here

If you want to try my container, you can check here sito-container

Top comments (0)