reshadow
reshadow copied to clipboard
reshadow beta roadmap
The roadmap:
- [ ] finalize the API (almost done)
- [ ] complete the docs
- [ ] describe the usage with different frameworks and libraries
- [ ] React
- [ ] Preact
- [ ] Vue
- [ ] Svelte
- [ ] htm
- [ ] styled-components API
- [ ] describe the runtime usage and usage with plugins:
- [ ] reshadow/babel
- [ ] reshadow/macro
- [ ] reshadow/postcss
- [ ] reshadow/webpack
- [ ] reshadow/prettier
- [ ] reshadow/eslint
- [ ] describe the common use cases
- [x] the transition from
styled-components
- [ ] describe the usage with different frameworks and libraries
- [ ] provide more examples and tutorials
- [ ] provide some benchmarks
@lttb Hello, This project is very interesting!
I have a question regarding use:size={size}
. Is it supported in Svelte? Or React only?
Hi @s0kil, thank you for the feedback!
svelte
has its own use
directive, but with reshadow
it is possible to omit the namespace to set the modifier :name={value}
or with shorthand :{name}
like {value}
that svelte has for attributes.
For example,
<button :size="s" :{variant}>click</button>
this is the same as in React
<button use:size="s" use:variant={variant}>click</button>
I made an example with reshadow, svelte and modifiers here: https://codesandbox.io/s/reshadowsvelte-bup1c
At this moment this is an undocumented reshadow feature and I'm still thinking about the syntax, if you have any other ideas and proposals, I'll be glad for the feedback 🙂
@lttb I'm currently working on a project that requires very dynamic components, and using directives
makes it so much easier.
@lttb Instead of providing a CSS file, are you planning to support component styles?
<style>
/* Styles go here */
button {
padding: 5px 10px;
border-radius: 5px;
font-size: 16px;
}
button[|size="s"] {
font-size: 14px;
}
button[|size="m"] {
font-size: 16px;
}
</style>
<button :size="s">Button</button>
It's also possible to add a lang
attribute to <style>
similar to what svelte-preprocess works:
<style lang="reshadow">
/* Styles go here */
button {
padding: 5px 10px;
border-radius: 5px;
font-size: 16px;
}
button[|size="s"] {
font-size: 14px;
}
button[|size="m"] {
font-size: 16px;
}
</style>
<button :size="s">Button</button>
@s0kil
yeah, it is already possible with reshadow
, you can even use your own language to preprocess before reshadow, for example:
<style reshadow lang="scss">
button {
padding: 5px 10px;
border-radius: 5px;
font-size: 16px;
}
</style>
<button>Button</button>
Moreover, it is possible to use runtime js values in styles with reshadow
by string interpolation:
<script>
import { randomColor } from "./randomColor";
let color = randomColor();
</script>
<style reshadow>
h1 {
color: ${color};
}
</style>
<h1>title</h1>
And you can also use reshadow css function val
to achieve that too:
<script>
import { randomColor } from "./randomColor";
let color = randomColor();
</script>
<style reshadow>
h1 {
color: val(color);
}
</style>
<h1>title</h1>
The API is still WIP, but you can play with it here: https://codesandbox.io/s/reshadowsvelte-5wzt1
And I did not mention, that another one way to use reshadow with svelte is styled
function (https://codesandbox.io/s/bup1c):
<script>
import styled from "reshadow";
/* import just css file, reshadow will process it */
import styles from "./styles.css";
/* css-in-js is available too */
import * as themes from "./themes";
import { randomColor } from "./randomColor";
export let theme = "light";
let color = randomColor();
styled(styles, themes[theme])`
h1 {
color: ${color};
}
`;
</script>
<h1>hello world</h1>
the cool thing about this function is that it is possible to compose different styles together, which is useful for CSS code splitting, styles injection via DI and so on
@lttb Thank you for your quick and detailed response.
I've come across a funny case. If you use css-in-js approach w/ babel plugin assets' paths won't be parsed
example
import styled from 'reshadow';
const Comp = props => styled`
@font-face {
font-family: custom-font;
src: url('../fonts/custom-font.woff2') type('woff2');
}
`(
<name {...props} />
)
If you use this approach the file ../fonts/custom-font.woff2
will not be recognised as a dependency and wont be passed to webpack or whatever bundler you happen to use. This is kind of a corner case. Yet it will also work with background images and other assets you happen to require from your css. I think this should end up somewhere in the docs.
I came across two more cases which eventually should end up in either/or FAQ/gotchas sections on the website
- class name extraction
- workaround for components using React Portal
Class name extraction
Essentially when you use third party libs that provide components which can accept class names in object format. I am aware of two options we can do it
// option one
import React from 'react'
import styled from 'reshadow'
import Comp from 'third-party'
// both our styles and styles for third party components are located together
// in out component
const MyComp = () => styled`
container {/* container styles */}
.wrapper {/* .wrapper styles */}
.inner {/* .inner styles */}
`(
<wrapper>
<Comp classes={{compWrapper: styled.styles.wrapper, compInner: styled.styles.inner}} />
</wrapper>
);
// option two
import React from 'react'
import styled, {css} from 'reshadow'
import Comp from 'third-party'
// our styles and styles for third party components are separated
const style = css`
.wrapper {/* .wrapper styles */}
.inner {/* .inner styles */}
`;
const MyComp = () => styled`
container {/* container styles */}
`(
<wrapper>
<Comp classes={{compWrapper: style.wrapper, compInner: style.inner}} />
</wrapper>
);
React Portal workaround
If you use dynamic values which fallback into css custom properties
import React from 'react'
import styled, {css} from 'reshadow'
import ReactModal from 'react-modal'
const MyComp = ({color, ...props}) => styled`
wrapper {
color: ${color}
}
`(
<wrapper {...props}>
<ReactModal>
<p>lorem ipsum</p>
</ReactModal>
</wrapper>
)
if I did not know how reshadow works I would expect the text inside modal to be the same color
as I pass in the component. Since these values are set as css custom properties on the wrapper
element and React modal are rendered in a different place in the DOM the css custom property for color
will not be accessible inside react modal. To fix it I was suggested a work around which assumes that the component using portal accepts style
prop. It goes smth like so
<ReactModal style={styled.$$style}>
If I have time I am happy with doing a PR for both of the above.
It's been a while, since most work is done in the next branch and what is left is the documentation I would like to propose a way to tackle it. I've copied over the points from the initial issue and commented on each below. I'd like to get some feedback on this idea before getting to work on it.
- [ ] complete the docs
- needs clarification on what is lacking
- [ ] describe the usage with different frameworks and libraries
- let's return the example directory and set up example for reshadow usage with each framework/lib
- [ ] React
- [ ] Preact
- [ ] Vue
- [ ] Svelte
- [ ] htm
- [ ] styled-components API
- [ ] describe the runtime usage and usage with plugins:
- Each package should have a separate section on a
Packages
page on the docs website
- [ ] reshadow/babel
- [ ] reshadow/macro
- [ ] reshadow/postcss
- [ ] reshadow/webpack
- [ ] reshadow/prettier
- [ ] reshadow/eslint
- Each package should have a separate section on a