Open shadowtime2000 opened 3 years ago
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";
})();
0.3 will support inline css like:
export default function App() {
return (
<>
<h1>Hello World</h1>
<style>{`
h1 {
color: #d63369;
}
`}</style>
</>
)
}
@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.
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/css@11.1.3",
...
}
}
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.
@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
.
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.
@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.
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).
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/cache@11.1.3/deno/cache.development.js:132:25)
at createEmotion2 (file:///D:/70_research/deno/resume/app/.aleph/development/-/cdn.esm.sh/v41/@emotion/css@11.1.3/deno/css.development.js:53:18)
at file:///D:/70_research/deno/resume/app/.aleph/development/-/cdn.esm.sh/v41/@emotion/css@11.1.3/deno/css.development.js:155:22
using deno 1.11 and aleph 0.3.0-alpha.33
Is it still working for you?
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:
styled-components
, though we would have to write our own SSR compiler thing