Comments (20)
Here comes another suggestion which is inspired by the hover/focus/active API which is implemented already.
First off you need to define your breakpoints in some global(?) register. We could use GlobalStylesheets.injection
since this seems to be the place to customise jsxstyle from the user perspective right as of now. So let's assume we do it like this:
GlobalStylesheets.injection.registerMediaQueries({
sm: "only screen and max-width:767px",
md: "only screen and min-width:768px",
lg: "only screen and min-width:1200px",
print: "only print"
})
now we can use the media
-prefix to target the registered media queries:
<Flex width="320px" mediaSmWidth="100%">
While this solution might not be as powerful as some of the ideas above, it plays quite well with the existing api and also works when rendered on the server :)
What do you think? I'm happy to start a PR if you feel it's worth exploring this further.
from jsxstyle.
I’ve thought about this quite a bit over the past few months and I’m going to be revisiting this in the near future. The API I like the best right now:
<Block
mediaQueries={{ sm: 'screen and (max-width: 640px)' }}
color="blue"
smColor="red"
/>
Feels like a natural extension of the jsxstyle API to me. Opinions/feedback appreciated.
from jsxstyle.
@meyer maybe you can add a little note on README showing how people can implement media query support using react-media
.
from jsxstyle.
@hnordt @rchanou I’m doing some README updates at the moment. I’ll add a section mentioning media/container query libraries while I’m at it.
from jsxstyle.
In many cases it would be better to look at component width instead of the global window width. Maybe there is a way to encourage that instead of traditional css media queries.
from jsxstyle.
@tpreusse inline styles do give you that flexibility, we just can't optimize it with the static analyzer (it will transparently work, just won't appear in the static css file). This also gets into "build a layout engine" territory which I'll leave to @vjeux :)
from jsxstyle.
Makes sense - I just wanted to point out that it would be a huge boost to reusability if components were to use a scoped size instead of the global window size.
For supporting media queries generically:
window.matchMedia("(min-width: 640px)").matches
Arguably not something a JS dev would think of straight away but would give the developers who know what they are doing the power to use media queries.
from jsxstyle.
from jsxstyle.
Could there be a hack (for the moment) where components specify their own size breakpoints (as props) and media queries are written out to force the component's width
and height
?
This is very rough, but:
Avatar.breakPoints: {
'mobile query': [120, 60],
'desktop query: [800, 600]
}
and the resulting css:
@media "mobile query" {
.component-x {
width: 120px; height: 60px;
}
}
@media "desktop query" {
.component-x {
width: 800px; height: 600px;
}
}
from jsxstyle.
How about this:
<StyleDefinition marginLeft={Theme.GRID_UNIT} color={Theme.primaryColor} background={hovered && rgb(255, 0, 0)} ref="blockStyle">
<MediaQuery match="max-width: 600px" fontSize="10px"/>
<!-- Because we can! - declare ':hover' pseudo selectors in here as well. -->
<Hover color="red"/>
</StyleDefinition>
<Block styles={this.refs.blockStyle}>
<InlineBlock fontWeight="bold">Username here</InlineBlock>
subtitle here
</Block>
In particular this idea:
- Defines the style definitions on a new
<StyleDefinition .../>
tag, which allows
to have child elements - The child elements of the
StyleDefinition
can then define how the styles
change e.g. when using media queries or hovering over the element using the
styles - Because the styles are now defined as a separate entity, it is possible to get
a reference to these<StyleDefinition />
. In particular, this allows to define
a style definition and pass it as prop value to a child element of the current
component.
I can imagine the last point is also helpful to solve issue #4 as changing the theme
is then nothing else as passing a set of different style definitions from a
root Style Container (similar to the Relay Container) into the component
hierarchy.
Let me know what you think and I am more than happy to expand on the idea further :)
from jsxstyle.
@jviereck, @chrislloyd: I think what @petehunt is trying to say is that we should use the AST to our advantage and look for certain patterns. When finding these patterns, we already know the affected CSS property. Instead of bailing completely and saying "oh no, this is not a static value", we transform an expression like <Block width={window.innerWidth > 640 ? '100%' : 320} />
to a media query.
@tpreusse: regarding element queries, I played around with it a little and came up with this naive solution. https://jsfiddle.net/ksmth/2prs8x5o/4/
from jsxstyle.
@danielberndt ooooh, I really like this idea. I’m not super crazy about the media
prefix and resulting case change for the specified key, but that’s super minor. It’s a really solid concept that makes sense to me.
from jsxstyle.
Cool @meyer, I'm really glad you like it :)
In the meantime I've discovered that glamor introduced a jsxstyle clone which solves the media query issue with an API like this:
<Flex width="320px" media={['(min-width: 400px)', {width: "100%"}]}/>
I quite like this approach as well as it's much more low-level. And based on this API it's also fairly straight forward to create custom wrapper components enabling the API I described in the post above.
The issue of the glamor approach is that it's kinda conflicting with the jsxstyle's hover/focus API, i.e. hoverWidth="20px"
is quite different from media={[query, {width: "20px"}]}
.
from jsxstyle.
@meyer I agree with @danielberndt 's initial idea for responsiveness. For non-React projects (i.e. wordpress mostly), I've had a tremendous success with Buzzfeed's Solid CSS framework. It borrows a lot from Tachyons / Basscss, championing atomic immutable CSS classes. In that sense, it is quite similar to jsxstyle. Probably Solid's best feature is the way it supports responsive styles using breakpoint prefixes: xs-
, sm-
, md-
, lg-
before certain atomic immutable classes for things like padding, margin, text-size, display, etc.
<!-- example of Solid in practice-->
<div class="xs-my1 xs-text-4 sm-inline-block sm-my2 sm-text-3 lg-hide">
Thing
</div>
Like @danielberndt, I'd love to see <Block xsColor="red" smColor="blue" />
land in jsxstyle, but I'm not sure I want global injections, unless you could do it without having to pass around a jsxstyle singleton. I would be satisfied with a hoc that wraps the primitives...
import { Block, withBreakpoints } from 'jsxstyle'
const RBlock = withBreakpoints({ sm: '600px', lg: '1000px' }, Block)
export default () => (
<RBlock color="red" smColor="blue" lgColor="green">Hello</RBlock>
)
My biggest concern is how to support this feature, and still leave the door open for server rendering.
from jsxstyle.
@jaredpalmer if breakpoints are defined as a prop or props, the existing curry
function would function exactly like withBreakpoints
in your example.
I’ve been thinking about this for a while now, and I think there are a few options we can go with.
Option A: curry
+ breakpoints
prop
import {curry, Block} from 'jsxstyle'
const RBlock = curry(Block, {
breakpoints: {
sm: 'only screen and (min-width: 600px)',
},
})
// or
export default function RBlock(props) {
return (
<Block {...props} breakpoints={{
sm: 'only screen and (min-width: 600px)',
}} />
)
}
Defining a breakpoints
prop directly on the component is more verbose and less magical than using global registration, but I personally tend to err on the side of verbosity.
My main concern with this option is that prop merges become a bit tougher due to the second-level breakpoints
prop. I’m not sure if that would be a problem in practice though. Depends on if people want to merge breakpoints more often than overwrite them.
That brings us to…
Option B: top-level prefixed breakpoint props
We could define breakpoints at the top level by utilising the existing prefix pattern:
export default function RBlock(props) {
return (
<Block
mediaSm="only screen and (min-width: 600px)"
color="blue"
smColor="red"
{...props}
/>
)
}
The main thing that sucks with this option is the case difference between Small
and small
.
Option C: context magic
I already don’t like this idea but I’m going to write it down anyway.
<Block breakpoints={{
sm: 'only screen and (min-width: 600px)'
}}>
<Block
color="blue"
smColor="red"
/>
</Block>
I like that breakpoint definition is defined at a higher level, but it is guaranteed to cause some weirdness when expected breakpoints aren’t in the context.
Whatever option we go with would ideally also be a step in the direction of animation
support too.
from jsxstyle.
I'm using react-media, works pretty well with jsxstyle
:
<Media query="(min-width: 600px)">
{matches => <Block color={matches ? 'blue' : 'red'} />}
</Media>
from jsxstyle.
I’m going to close this issue, as media query support is not a high priority for us at the moment.
from jsxstyle.
react-container-query
also looks pretty cool, though I haven't had the chance to use it myself yet.
from jsxstyle.
@rchanou pretty cool, but I think react-media
integrates better with the "jsxstyle world", with react-media
you still pass props using jsxstyle elements.
from jsxstyle.
@meyer +1 i like this API 10x better than the way glamor-jsxstyle handles it.
from jsxstyle.
Related Issues (20)
- export JsxstyleProps from jsxstyle.d.ts HOT 1
- Break with typescript's generic component HOT 4
- React 15 and `componentWillMount` HOT 3
- Break with using thread-loader on production HOT 2
- Replace most of the AST traversal in `extractStyles` with the TypeScript type checker HOT 2
- TS2503: Cannot find namespace 'JSX'. HOT 2
- RFC: Default `alignItems` to `center` for `Row` component
- React Native (react-native-web) HOT 3
- Question about useMatchMedia HOT 2
- RFC: Adjacent sibling selector API
- Add a `Styled` component HOT 2
- Clean up the server rendering API HOT 1
- Color helpers HOT 1
- Ideas for a jsxstyle 3.0 HOT 2
- React native web support HOT 3
- jsxstyle doesn’t have flow types HOT 1
- CSS custom properties and jsxstyle
- New top-level component prop: disabled HOT 1
- Proposal: combine jsxstyle and webpack plugin HOT 1
- Compatibility with [email protected] HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from jsxstyle.