GithubHelp home page GithubHelp logo

Media query support about jsxstyle HOT 20 CLOSED

jsxstyle avatar jsxstyle commented on May 16, 2024
Media query support

from jsxstyle.

Comments (20)

danielberndt avatar danielberndt commented on May 16, 2024 3

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.

meyer avatar meyer commented on May 16, 2024 3

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.

hnordt avatar hnordt commented on May 16, 2024 1

@meyer maybe you can add a little note on README showing how people can implement media query support using react-media.

from jsxstyle.

meyer avatar meyer commented on May 16, 2024 1

@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.

tpreusse avatar tpreusse commented on May 16, 2024

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.

petehunt avatar petehunt commented on May 16, 2024

@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.

tpreusse avatar tpreusse commented on May 16, 2024

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.

skahack avatar skahack commented on May 16, 2024

ref: reactjs/react-future#8

from jsxstyle.

chrislloyd avatar chrislloyd commented on May 16, 2024

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.

jviereck avatar jviereck commented on May 16, 2024

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:

  1. Defines the style definitions on a new <StyleDefinition .../> tag, which allows
    to have child elements
  2. 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
  3. 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.

ksmth avatar ksmth commented on May 16, 2024

@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.

meyer avatar meyer commented on May 16, 2024

@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.

danielberndt avatar danielberndt commented on May 16, 2024

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.

jaredpalmer avatar jaredpalmer commented on May 16, 2024

@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.

meyer avatar meyer commented on May 16, 2024

@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.

hnordt avatar hnordt commented on May 16, 2024

I'm using react-media, works pretty well with jsxstyle:

<Media query="(min-width: 600px)">
  {matches => <Block color={matches ? 'blue' : 'red'} />}
</Media>

from jsxstyle.

meyer avatar meyer commented on May 16, 2024

I’m going to close this issue, as media query support is not a high priority for us at the moment.

from jsxstyle.

rchanou avatar rchanou commented on May 16, 2024

react-container-query also looks pretty cool, though I haven't had the chance to use it myself yet.

from jsxstyle.

hnordt avatar hnordt commented on May 16, 2024

@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.

jaredpalmer avatar jaredpalmer commented on May 16, 2024

@meyer +1 i like this API 10x better than the way glamor-jsxstyle handles it.

from jsxstyle.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.