GithubHelp home page GithubHelp logo

cssinjs / styled-jss Goto Github PK

View Code? Open in Web Editor NEW
217.0 13.0 25.0 297 KB

Styled Components on top of JSS.

Home Page: http://cssinjs.org/styled-jss

License: MIT License

JavaScript 100.00%
js css jss stylesheets styled-jss styled-components react

styled-jss's Introduction

styled-jss

Styled Components on top of JSS

Travis branch Coverage Status branch npm version npm license

Styled-JSS implements a styled-primitives interface on top of JSS. Its API is similar to styled-components but thanks to the JSS core, it supports all features and plugins JSS does. For e.g. you can use full JSON Syntax inside.

Try it out on playground.

Default styled function

import styled from 'styled-jss'

const Button = styled('button')({
  fontSize: 12,
  color: (props) => props.theme.textColor
})

// You can also use curried interface this way.
const div = styled('div')

const Container = div({
  padding: 20
})

// Composition.
const PrimaryButton = styled(Button)({
  color: 'red'
})

// Composition with unstyled React Components too.
const Button = styled(UnstyledButton)({
  color: 'blue'
})

// Component Selectors.
const ButtonContainer = styled(Container)({
  [`& ${PrimaryButton}`]: {
    color: 'green'
  }
})

Theming

styled-jss has out of the box support for theme customization with the unified theming package.

import styled, {ThemeProvider} from 'styled-jss'

const Button = styled('button')(({margin, theme}) => ({
  margin,
  color: theme.color,
  backgroundColor: theme.backgroundColor,
}))

const themes = {
  light: {
    color: 'black',
    backgroundColor: 'yellow',
  },
}

const App = () => (
  <ThemeProvider theme={themes.light}>
    <Button margin={20}>This is themed Button</Button>
  </ThemeProvider>
)

export default App

Composable styles

Example on the CodeSandbox

You can compose your style-objects and style-functions.

Let's say this is our mods.js:

export const theme = ({ theme }) => ({
  color: theme.colors.primary,
  backgroundColor: theme.colors.secondary,
})

export const font = ({ bold }) => ({
  font: {
    weight: bold ? 'bold' : 'normal',
    family: 'Arial',
  },
})

export const size = ({ size = 'm' }) => ({
  s: {
    fontSize: 12,
    lineHeight: 1.2,
  },
  m: {
    fontSize: 16,
    lineHeight: 1.5
  }
})[size]

export const rounded = ({ rounded }) => rounded && { borderRadius: 5 }

Now we can mix them to our Button Component:

import styled from 'styled-jss'
import {theme, font, size, rounded} from 'mods'

const Button = styled('button')(
  {
    border: 0,
    padding: [5, 10],
    display: 'inline-block',
  },
  theme,
  font,
  size,
  rounded,
)

export default Button

And Usage:

import {ThemeProvider} from 'styled-jss'
import Button from './components/Button'

const theme = {
  dark: {
    colors: {
      primary: 'white',
      secondary: 'purple'
    }
  }
}

export default () => (
  <ThemeProvider theme={theme.dark}>
    <Button>normal button</Button>
    <Button bold>bold button</Button>
    <Button size="s">small button</Button>
    <Button rounded>rounded button</Button>
  </ThemeProvider>
)

Base Style Sheet

Using base Style Sheet we can reuse classes in the render function and inside of a styled component.

import { Styled, injectStyled } from 'styled-jss'

// Base styles, like a regular jss object.
const styled = Styled({
  root: {
    margin: 10,
    '& $baseButton': {
      fontSize: 16
    }
  },
  baseButton: {
    padding: 10,
    '& + &': {
      marginLeft: 10
    }
  }
})

const NormalButton = styled('button')({
  composes: '$baseButton',
  border: [1, 'solid', 'grey'],
  color: 'black'
})

// Composition - same way.
const PrimaryButton = styled(NormalButton)({
  color: 'red'
})

// One can use classes AND styled primitives.
const MyComponent = ({classes}) => (
  <div className={classes.root}>
    <NormalButton>normal button</NormalButton>
    <PrimaryButton>primary button</PrimaryButton>
  </div>
)

const MyStyledComponent = injectStyled(styled)(MyComponent)

Custom JSS setup

Styled-JSS uses jss-preset-default by default. You can require createStyled function and provide your custom JSS instance.

import { create as createJss } from 'jss'
import vendorPrefixer from 'jss-vendor-prefixer'
import createStyled from 'styled-jss/createStyled'

const jss = createJss()
jss.use(vendorPrefixer())

// Create a custom Styled function, that allows to set BaseStyles.
export const Styled = createStyled(jss)

// Create a custom styled function that allows to create styled components.
const styled = Styled()

export default styled

Install

npm install --save styled-jss

Install peer dependencies react and react-dom in your project.

License

MIT

styled-jss's People

Contributors

aleshaoleg avatar aloker avatar kof avatar lttb avatar matteofigus avatar tuchk4 avatar wellguimaraes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

styled-jss's Issues

Code Style: express acronyms in capital space

Basic requirements:

  • Keep source code as documentation - lexically and grammarly correct.
  • Keep signatures and API compliant with general (native) API.
  • Express acronyms in capital spaces, e.g. encodeURIComponent, SIMD, decodeURI,
    JSON, NaN, URIError, cipher:setAAD and so on.
  • Keep API predictable - you just know if some part in a name is acronym then write it in capital case. You should not remember where is to write acronyms in lower case, etc. That's why we've updated this pull request.

Current state:

  • README:

    const jss = createJss()
    
  • Probably other places (did not explored the source code deeply yet).

babel-plugin-styled-jss

We can provide babel plugin with prejss under the hood, that would transform

const Button = styled.button`
  color: red;
`

to

const Button = styled('button', {color: 'red'})

for better performance

Set styled object as a whole based on props

Is it possible / would you accept a pull request that could accomplish something of the following:

const CaseOne = {
  color: red
};

const CaseTwo = {
  color: blue
};

const MyStyledComponent = styled('button')(
  props => props.caseOne ? CaseOne : CaseTwo
);

I know currently you can set CSS properties individually based on props, but the library doesn't support replacing the whole styled object based on props.

This is a trivial example case, but I've had a number of use cases using this library where the styled objects were so different that I'd rather just swap them in and out as a whole.

I've also had a few cases where the styled objects are coming from different node modules and it's not sensible to override them one by one; I also don't want to know what the styled object looks like because it's coming from a different node module.

SSR Support for styled-jss

I couldn't find anything about server-rendering support for styled-jss. There is the react-jss package but even when using JssProvider from react-jss it doesn't work. I keep getting a mismatch of classes between the server and the client every time I refresh.

image

Will there be any server-rendering support for styled-jss?
I made a sample repo here: https://github.com/stoikerty/styled-jss-ssr-example

Currying interface

Lets add or even replace the current interface with the currying one:

const Button = styled('div')({
  color: 'red'
})

The nice thing about it is:

const div = styled('div')

const Button = div({
  color: 'red'
})

const AnotherButton = div({
  color: 'green'
})

Extend doesn't seem to work

Extend preset plugin doesn't seem to be working.

export const button = {
  display: `inline-block`,
  fontSize: `1.2em`
};

export const primary = {
  extend: 'button',
  color: `white`
};

And usage:

import styled from 'styled-jss';

const Button = styled('button')(button);

export const PrimaryButton = styled('button')(primary);

Docs, docs and docs

  1. Add more examples, explain all points styled-components explains
  2. Explain whats the difference to styled-components
  3. Explain whats the difference to glamorous (second popular sc interface, more direct competitor)
  4. Explain everything that JSS has in the docs but might be not obvious with styled-jss API.

SSR Support

Not exactly the same issue as #62 , so I created a new issue.

I am also having difficulty with getting SSR to work with styled-jss. Using createStyled, I create a new styled using an existing jss instance. Though the styles render client-side, they aren't making it into the registry, and therefore not getting injected into the critical CSS. Is the jss instance supposed to handle the insertion of styles into the registry? Or this is something styled-jss is supposed to handle that hasn't been implemented yet?

SC v2

They changed composition to use .extend. I think styled(StyledButton) means now a different thing over there.

React 16 compatibility

This package is dependent on is-react-prop which isn't (currently) compatible with React 16. Do you have plans to remediate this? Is there a timeframe for this?

Lets add an example with PreJSS

As this api adds styled primitives similar to styled-components, people often expect it to work with template string literals as well, we should add an example how to use them all together.

How to install styled-jss when used in a library

When we use styled-jss inside a library/package, should we install them as peerDependencies or regular dependencies?

Is there something to watch out for, regarding multiple instances or versions conflict when a library use styled-jss as well as the consumer?

Media queries don't work when using theming function

When I provide a literal style object, media queries are considered.

const ResponsiveOk = styled("div")({
  color: "green",
  "@media screen and (min-width: 400px)": {
    color: "red"
  }
});

If I use a theme callback instead, media queries do not work anymore:

const ResponsiveNotOk = styled("div")(({ theme }) => ({
  color: "green",
  "@media screen and (min-width: 400px)": {
    color: "red"
  }
}));

Demo: https://codesandbox.io/s/m9v69xvo3x
Resize the output window above/below 400 pixel to see the difference: the top row switches between red and green, the bottom row doesn't.

Am I missing something conceptually here or is this supposed to work?

Dynamic import styled-jss

I want to dynamic import "styled-jss" and able to do that so styled-jss become a chunk and only loaded when one of my styled components loaded. For simple case, it works (see sandbox link below)

Expected behavior:
+Component selector should work.
+Style should cached somehow.

The bug:
+Component selector doens't work:

image

+Similar classes generated multiple times:
image

Codesandbox:
https://codesandbox.io/s/styled-jss-playground-9f5j0?file=/index.js

Versions (please complete the following information):__

  • jss: 10.3.0
  • styled-jss: 2.2.3
  • Browser: Chrome
  • OS: Windows

Maybe the way i wrapped components is incorrect, if so, could you point me the way so i can fix it.

Functions do not work with arrays

It works:

const MyComp = styled('div')({
  border: [2, 'solid', 'white'],
});

This does not work:

const MyComp = styled('div')({
  border: ({ children }) => !children && [2, 'solid', 'white'],
});

Works:

const MyComp = styled('div')({
  border: ({ children }) => !children && ['2px', 'solid', 'white'].join(' '),
});

@global is not working

demo: https://codesandbox.io/s/async-sky-5xyhv

body doesn't have a lightblue background as expected

import React from "react";
import ReactDOM from "react-dom";

import styled from 'styled-jss';

function App(props) {
  return (
    <div {...props}>
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}


const StyledApp = styled(App)({
  border: '1px solid red',
  '@global': {
    body: {
      backgroundColor: 'lightblue'
    }
  }
})

const rootElement = document.getElementById("root");
ReactDOM.render(<StyledApp />, rootElement);

styled-jss: 2.2.3

Styled-jss component not passing props down

Should this work?

import React from 'react';
import styled from 'styled-jss';
import styles from 'my-styles';

const Input = styled('input')(styles.input);

export const TextInput = () => (
  <Input type='text' />
);

react-jss vs styled-jss recommendations

Please direct me elsewhere for this question if this is not an appropriate place... I've used react-jss for a while and it's great (good job to you all !!). I just discovered styled-jss in the process of evaluating styled-components and styled-jsx. styled-jss seems like an excellent alternative to styled-components for the jss ecosystem. What I'm trying to understand is when to use react-jss vs styled-jss and any differences/gotchas that I should be aware of. When authoring a component I completely understand the difference.... but is it OK/recommended to use both together? react-jss auto attaches/detaches where styled-jss appears to inject one big stylesheet during bootstrap... If I'm writing a shared component library is there anything I should be aware of using one vs the other.... My desire is probably to use both together and that appears to work fine.. but I'm curious if there are any "best practices" or "recommendations" on how best to think about using them and when to use one vs. the other.

react-jss and styled-jss in the same app

Moving discussion from react-jss..... I've been using both react-jss and styled-jss in the same app. This has worked fine until upgrading to the most recent versions of jss, react-jss, and styled-jss. Everything works fine during development but when I bundle my app with NODE_ENV=production I end of with duplicate className conflicts.

After some investigation I concluded that styled-jss does not honor anything in context put there by react-jss's JssProvider. Most of my styled-jss use is in a separate, sharable package. styled-jss does not declare react-jss as a dependency so I"m not sure this is technically a bug. However, my expectation was that they'd work together -- especially since they both target react apps. More importantly.... for the benefit of the jss ecosystem... and getting stuff to "just work" I wonder if styled-jss should honor what JssProvider puts there and I guess make react-jss and dependency?

I'm going to explore a "custom JSS" setup and try to share a className generator between the 2... but this seems like a lot of friction for 2 packages that I would expect to work well together. Curious what your thoughts are ?

@kof mentioned "Initially they were not meant to be be used together, but I think in theory they should do so if they turn out to be complementary. I think we are not aware right now of complementarity." They're a different approach to styling your app. I tend to use styled-jss for structural components (flexbox layouts and stuff like that) and react-jss for more component centric styling. It's arguable whether that's complimentary or not... but I'm struggling to understand why they wouldn't be designed to work well together so it's up to the end-user to decide when to use which. Since they're part of the same cssinjs org and both target React apps my expectation was that they'd work together.

Components selectors

Is this possible with styled-jss?

const AuthorName = styled('div')({...})
const Avatar = styled('img')({...})

const Message = styled('div')({
  [`&:not(:first-child) ${AuthorName}`]: {
    display: 'none'
  },
  [`&:not(:last-child) ${Avatar}`]: {
    visibility: 'hidden'
  }
})

Overriding component style

Can u add something like 'css' prop in glamorous? I think it might be useful when u want specify just a margin.

<MyStyledComponent css={{ marginBottom: 8 }}/>

Implement injectStyled

We need to implement injectStyled that acts like injectSheet from react-jss, but provides sharable scope with styled components.

For example:

import Styled, { injectStyled } from 'styled-jss'

const styled = Styled({
  root: {
    margin: 10,
    '& $baseButton': {
      fontSize: 15,
    },
  },
  baseButton: {
    padding: 10
  }
})

const NormalButton = styled('button', {
  composes: '$baseButton',
  border: [1, 'solid', 'grey'],
  color: 'black'
})

const MyComponent = ({classes}) => (
  <div className={classes.root}>
    {/* this would have font-size: 15 then */}
    <NormalButton />
  </div>
)

const MyStyledComponent = injectSheet(styled)(MyComponent)

Bug: Nested composition causes invalid tag to be rendered

Consider this example:

const C1 = ({ children }) => <div>{children}</div>;
const C2 = styled(C1)({});
const C3 = styled(C2)({});

const App = () => <C3>Test</C3>

That is, styled element C3 extends styled element C2 which by itself extends component C1.

This causes a wrong DOM element to be rendered (notice the c1 tag):
<c1 class="C1-2-0-1">Test</c1>

Online example

If I replace C1 with a styled element by itself (const C1 = styled('div')({...})), the generated DOM is correct.

Remove isObservable checks

Styled-JSS should be able to remove the isObservable check, because jss now removes observables from style object, subscribes to it and sets the value directly.

Higher order component name

If component have displayName like this hoc(Component) JSS can't insert rule into css

Warning: [JSS] Can not insert an unsupported rule 

.withStyles(Typography)-6-0-1 {
  flex: 1;
}

Type Definitions

Any pointers on using this in a typescript project? Anyone using this library with an internal type file?

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.