/filebox

File manager app built with react, firebase and twin.macro

Primary LanguageJavaScript

Table of contents

Getting started

Install the dependencies

Important Mac users need to change the script defined in the package.json file from SET NODE_ENV to NODE_ENV and remove the & between two commands.

React and Babel

npm install react react-dom @babel/core @emotion/babel-plugin-jsx-pragmatic babel-plugin-macros

Twin and Emotion

npm install twin.macro @emotion/react @emotion/styled
Install with Yarn

React and Babel

yarn add react react-dom @babel/core @emotion/babel-plugin-jsx-pragmatic babel-plugin-macros

Twin and Emotion

yarn add twin.macro @emotion/react @emotion/styled

Add the babel config

To use the tw and css props, emotion must first extend jsx with a jsx pragma.

The newest version looks like this and sits at the top of your files:

/** @jsxImportSource @emotion/react */

a) Auto inject the pragma:

You can avoid adding the pragma yourself with the following babel config:

// .babelrc
{
  "plugins": [
    "babel-plugin-macros",
    [
      "@emotion/babel-plugin-jsx-pragmatic",
      {
        "export": "jsx",
        "import": "__cssprop",
        "module": "@emotion/react"
      }
    ],
    [
      "@babel/plugin-transform-react-jsx",
      {
        "pragma": "__cssprop",
        "pragmaFrag": "React.Fragment"
      }
    ]
  ]
}

b) Or manually specify the jsx pragma in each file:

First add these babel plugins:

// .babelrc
{
  "plugins": [
    "babel-plugin-macros",
    ["@babel/plugin-transform-react-jsx", { "runtime": "automatic" }]
  ]
}

Then when styling with the tw or css prop, add the pragma at the top of your file. This also replaces the react import:

/** @jsxImportSource @emotion/react */
import tw from 'twin.macro';

const Input = () => <input tw="bg-black" />;
// or
const Input = () => <input css={tw`bg-black`} />;

Note: After build, if you’re seeing "process is not defined" then npm install and add "babel-plugin-transform-inline-environment-variables" to .babelrc

Complete the TypeScript setup

If you’re using TypeScript, you’ll need to add the remaining types for your chosen css-in-js framework.

Setup instructions

First up, you’ll need to install some types for React:

npm install -D @types/react
// or
yarn add @types/react -D

Then twin needs some type declarations added for your chosen css-in-js library, otherwise you’ll see errors like this:

Module '"../node_modules/twin.macro/types"' has no exported member 'styled'.
// or
Module '"../node_modules/twin.macro/types"' has no exported member 'css'.
// or
Property 'css' does not exist on type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'.

To fix this, create a twin.d.ts file in your project root (src/twin.d.ts with create-react-app) and add these declarations:

// twin.d.ts
import 'twin.macro';
import styledImport from '@emotion/styled';
import { css as cssImport } from '@emotion/react';

// The css prop
// https://emotion.sh/docs/typescript#css-prop
import {} from '@emotion/react/types/css-prop';

declare module 'twin.macro' {
	// The styled and css imports
	const styled: typeof styledImport;
	const css: typeof cssImport;
}

// The 'as' prop on styled components
declare global {
	namespace JSX {
		interface IntrinsicAttributes<T> extends DOMAttributes<T> {
			as?: string;
		}
	}
}

Then add the following in tsconfig.json:

// tsconfig.json
{
  "files": ["twin.d.ts"],
  // or
  // "include": ["twin.d.ts"],
}

Now that you’ve added the definitions, you can use these imports:

import tw, { css, styled, theme } from 'twin.macro';

And these props:

<div tw="">
<div css={}>