twin.macro
twin.macro copied to clipboard
Add Solid.js support
The solid-styled-component
package for Solid is a thin wrapper around Goober.
This patch adds preset: solid
, which loads the Goober wrappers and otherwise behaves as Goober would.
A small site has been written using this PR, as well as this recently merged Solid PR for createGlobalStyles
support. If you edit pages/index/index.jsx
and comment out lines 30 through 95, you can easily play with the client without any server errors in the console.
I'm not sure exactly how you'd like to see these changes implemented and there are currently caveats. At the moment, however, I'd say it's entirely usable as a feature. Whatever you advise is fine.
Here are the current caveats. The following pattern works:
import tw, { styled } from "twin.macro";
export default function App(props) {
const Button = styled("button")`
${() => tw`text-white`}
`;
return <Button {...props} />;
}
The following will not:
import "twin.macro";
export default function App(props) {
return <button {...props} tw="text-white" />;
}
However, the following also works:
export default function App(props) {
const ToggleButton = styled("button")`
${() => (props.active ? tw`text-white` : tw`text-gray-700`)}
`;
return <ToggleButton {...props} />;
}
<ToggleButton active={state.volume > 0} onClick={click}>
<Svg alt="speaker" />
</ToggleButton>
Where Svg
also demonstrates the css
escape hatch:
import tw, { css } from "twin.macro";
export default function App(props) {
const svg = css`
${() => tw`
h-8
w-8
fill-current
stroke-current
inline-block
text-center
bg-cover
`}
`;
return (
<svg {...props} class={svg}>
<use xlink:href={`#svg-${props.alt}`}></use>
</svg>
);
}
And most importantly GlobalStyles works:
import { createGlobalStyles } from "solid-styled-components";
import tw, { GlobalStyles as BaseStyles } from "twin.macro";
export default function App() {
const CustomStyles = createGlobalStyles`
body {
${() => tw`subpixel-antialiased`}
}
video {
${() => tw`h-screen w-full bg-black z-0`}
}
video::-webkit-media-controls {
${() => tw`hidden`}
}
`;
return (
<>
<BaseStyles />
<CustomStyles />
</>
);
}
The only setup needed is package.json
:
{
"babelMacros": {
"twin": {
"preset": "solid"
}
},
"devDependencies": {
"vite": "^2.2.1",
"vite-plugin-babel-macros": "^1.0.5",
"vite-plugin-solid": "^1.5.1"
},
"dependencies": {
"solid-js": "^0.26.1",
"solid-styled-components": "^0.26.1",
"twin.macro": "^2.3.3"
}
}
and vite.config.js
:
import { defineConfig } from "vite";
import solid from "vite-plugin-solid";
import macros from "vite-plugin-babel-macros";
export default defineConfig({
plugins: [ solid(), macros(), ],
build: {
target: "esnext",
polyfillDynamicImport: false,
},
});
Thanks so much for this feature, I haven't heard of the solid-styled-components
goober integration before.
Looks like it adds SSR and a theme provider?
We could probably get that tw prop working with a modified version of babel-plugin-goober-css-prop.
I'll take a closer look and get back to you.
Yes, solid-styled-components
is bundled with Solid.js and its extensions to Goober are roughly for SSR, themes and other bookkeeping related to making it work with Solid.
I had a go with babel-plugin-goober-css-prop
earlier but didn't manage to get props going.
Sadly, I will be going back to working with Vite running PostCSS/Tailwind in JIT-mode for various reasons. However, the twin.macro+goober revision of Live.tv is still available as a reference.
If there's anything I can help with this issue, please let me know!
Thank you so much for making this! I've created an issue before I was aware of this PR.
My issue https://github.com/ben-rogerson/twin.macro/issues/469 is regarding emotion, specifially with my emotion-solid port I made. Is this PR Specific to solid-styled-component
?
Is this PR Specific to
solid-styled-component
?
Absolutely. The PR is just adding an option to use solid-styled-component
as if it was Goober, since it is a Solid-specific wrapper around it. What you would need to do is a similar option for Solid's Emotion wrapper, in which case maybe naming this PR's option solid-goober
instead of solid
would be a better idea, since then you could have a solid-emotion
for your solution.
Good luck!
Hey @ben-rogerson is there any reason why this wasn't merged? I'm happy to take this to the finish line as I want to use twin.macro with Solid :)
I've made some strides in a solid + twin integration, thinking I'll test it some more and release shortly.
@ben-rogerson Awesome! Let me know if I can be of any help.