Skip to content

CSS-in-JS Support? #90

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
shadowtime2000 opened this issue Jan 16, 2021 · 10 comments
Open

CSS-in-JS Support? #90

shadowtime2000 opened this issue Jan 16, 2021 · 10 comments
Labels
∆ feature New feature 🅝 npm package NPM package support

Comments

@shadowtime2000
Copy link
Member

shadowtime2000 commented Jan 16, 2021

A ton of people like CSS-in-JS and I think we should add support for it. We have to figure out how we will do it. I see 2 options:

  1. Write our own using SWC macros once released SWC Macro #78
  2. Add support for something like styled-components, though we would have to write our own SSR compiler thing
@shadowtime2000 shadowtime2000 added ∆ feature New feature 🅝 npm package NPM package support labels Jan 16, 2021
@shadowtime2000
Copy link
Member Author

An example of it with macros:

// macro source

export default function Styled(initialCSS, ...values) {
	return "";
}

Styled.macro = {
	transform(initialCSS, ...values) {
		let outputCSS = "";
		let valueCounter = 0;
		const id = Math.random().toString(36).slice(2);
		initialCSS.forEach(intial => {
			outputCSS += initial;
			outputCSS += values[valueCounter];
			valueCounter++;
		});
		return `
		(() => {
			const styleElem = document.createElement("style");
			styleElem.textContent = ".styled-${id}{${intialCSS}}";
			document.head.appendChild(styleElem);
			return "styled-${id}";
		})();
		`
	}
}
// source code

const className = styled`
	color: red;
	background-color: grey;
`;
// compiled code

const className = (() => {
	const styleElem = document.createElement("style");
	styleElem.textContent = ".styled-asdfi4788837{color: red;background-color:grey;}";
	document.head.appendChild(styleElem);
	return "styled-asdfi4788837";
})();

@shadowtime2000
Copy link
Member Author

@ije
Copy link
Member

ije commented Jan 21, 2021

0.3 will support inline css like:

export default function App() {
  return (
    <>
      <h1>Hello World</h1>
      <style>{`
        h1 {
          color: #d63369;
        }
      `}</style>
    </>
  )
}

@shadowtime2000
Copy link
Member Author

@ije Cool, but as far as I am aware that is very basic CSS-in-JS. Most CSS-in-JS frameworks support stuff like theming and dynamic styles too.

@thegaryroberts
Copy link

thegaryroberts commented Feb 5, 2021

I'm using the framework agonistic version of Emotion (CSS-in-JS) in Aleph.js without any effort: https://emotion.sh/docs/@emotion/css

using the esm.sh import in my import_map.json:

{
    "imports": {
     ...
      "@emotion/css": "https://esm.sh/@emotion/[email protected]",
     ...
    }
}

then in my calling code:

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

const ulStyles = css`
  display: flex;
  list-style-type: none;
  margin: 0;
  padding: 10px 0 0 10px;

  li {
    margin: 0 10px 10px 0;
    padding: 5px 8px;

    a {
        color: hsl(214, 100%, 71%);
        text-decoration: none;
    }

    &:hover {
        background-color: hsl(210, 0%, 90%);
    }
  }
`;

export const MainNav = () => {
  return (
    <ul className={ulStyles}>
       <li><a>
    ....

also the global css in the app.tsx file:

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

injectGlobal`
  * {
    box-sizing: border-box;
    font-family: 'Open Sans', sans-serif;
  }
`;

export default function App(
...

Didn't know where to begin with getting the react version working (https://emotion.sh/docs/@emotion/react) and it's custom jsx transform, without babel. Not sure if the new JSX transform in React will help or hinder this: https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html

In any case this framework agnostic CSS-in-JS solution is already a massive improvement for me over SASS/LESS/CSS.

@shadowtime2000
Copy link
Member Author

@thegaryroberts Thanks for sharing how you do it, I think Emotions React pkg has out of the box support with renderToString and other React SSR stuff. We should probably add support for /** @jsx */, though it is also possible to just call jsx because it is compatible with React.createElement.

@thegaryroberts
Copy link

So the main hurdle i faced without @jsx directive support, is when I tried this (as per emotion documented example):

/** @jsx jsx */
import { jsx, css, Global, ClassNames } from '@emotion/react'

the jsx value gets clean up/removed from the import by the deno fmt as it assumes it is not referenced.

@shadowtime2000
Copy link
Member Author

@thegaryroberts I think you could open an issue for that because afaik deno fmt is for formatting, not stuff like this which could fit deno lint more.

@thegaryroberts
Copy link

It turns out it was my IDE (VS Code) removing it. The directive is not removed if it is the very first line in the file. However this just led onto other issues getting emotion/react to work. Tried using the esm.sh import bundle options, but is still delivering emotion with inbuilt react version which leads to multiple react version warnings (and probable errors). Anyway giving up and sticking to emotion/css for now.

(A shame as emotion/react is a true component based approach to CSS. In my opinion modern projects should consider it as the starting point for CSS integration, instead of separate file css/sass approaches. We benefit from a consolidated componentisation approach to JS & HTML, e.g. React. Why exclude CSS from the componentisation paradigm).

@nkia-christoph
Copy link

nkia-christoph commented Jun 12, 2021

Hey @thegaryroberts,

I've been trying to get emotion to work but keep running into the same error when calling css:

const navbar = css`
  color: red;
  background-color: hotpink;
  font-size: 20rem;
  text
`
Error: document is not defined

ReferenceError: document is not defined
    at createCache2 (file:///D:/70_research/deno/resume/app/.aleph/development/-/cdn.esm.sh/v41/@emotion/[email protected]/deno/cache.development.js:132:25)
    at createEmotion2 (file:///D:/70_research/deno/resume/app/.aleph/development/-/cdn.esm.sh/v41/@emotion/[email protected]/deno/css.development.js:53:18)
    at file:///D:/70_research/deno/resume/app/.aleph/development/-/cdn.esm.sh/v41/@emotion/[email protected]/deno/css.development.js:155:22

using deno 1.11 and aleph 0.3.0-alpha.33

Is it still working for you?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
∆ feature New feature 🅝 npm package NPM package support
Projects
None yet
Development

No branches or pull requests

4 participants