Git Product home page Git Product logo

astroturf's People

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  avatar  avatar  avatar  avatar  avatar  avatar

astroturf's Issues

Incompatible with css-loader 2.0.0

New major version of css-loader has been released 2 days ago. Upon trying it out with astroturf I was getting the following error:
image

Looks like the option importLoader that astroturf is passing to css-loader has been renamed.

astroturf is passing:

image

But the expected options schema has importModules:

image

Fixing css-loader to 1.0.1 fixes the problem.

Interpolating components produces incorrect selectors

The following code

// styles.js

const Title = styled('div')`
  font-size: 20px;
`
const Item = styled('div')`
  ${Title} {
    margin-right: 32px;
  }
`

produces css

.styles-Title\.module__cls1___3mrVE {
font-size: 20px;
}
.styles-Item\.module__cls1___29Xnj .styles-Title.module__cls1___3mrVE {
margin-right: 32px;
}

As you can see .styles-Item\.module__cls1___29Xnj .styles-Title.module__cls1___3mrVE selector only escapes . in its first part while the interpolated part has it unescaped (while it's still escaped when directly referenced on the first line)

Component API props are passed to DOM element

Hi!

Thanks for the best css-in-js library! We're using Component API in our application, and I noticed odd behaviour in a new version: all props matching css classes are passed to DOM elements. As far as I remember astroturf filtered props earlier.

Example:

let Base = styled.div`
  position: relative;

  &.isBig {
    size: 32px;
  }
`


return React.createElement(Base, { isBig }, )

And now I'm getting:

Warning: React does not recognize the `isBig` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `isbig` instead. If you accidentally passed it from a parent component, remove it from the DOM element.

Is it correct behaviour and we have to filter props manually?

Thanks!

Get template literal expression output

Is it possible to access the template literal expression value?
In this case, I was trying to log plain css to the console, so that the following code:

const margin = 10;
const height = 50;

const styles = css.box { height: ${height}px; margin-bottom: ${margin}px; };

console.log(cssOutput)

would output

.box {
height: 50px;
margin-bottom: 10px;
}

Where cssOutput is the expression I'm looking for.

Question: is it possible to use astroturf without react?

I was under impression that css api simply produces a bunch of class names that can be used with any (or none) js framework. But looks like there is a hard dependency on React. Why is that? Is there a tool similar to astroturf that is not exclusive to react?

Thanks!

[Question] use with storybook

Thank you for such a wonderful tool. There was a need to use it together with the storybook, but I can not understand what the problem is. I use custom settings for webpack

Screen Shot 2019-07-23 at 01 49 42

Module not found: Error: Cannot find module '…/node_modules/astroturf/loader.js!/…/node_modules/babel-loader/lib/index.js!/…/node_modules/astroturf/loader.js!/…/node_modules/core-js/modules/web.timers.js'

API musings

Since we've got a lot of new-ish api surface area i thought it would be helpful to maybe talk through a more unified vision and approach. Below are a few API options I think are feasible technically but obviously have some tradeoffs

Unified style to props direction

with the following constraints

  • don't require css parsing (beyond simple regexes) at compile time;
  • minimal runtime
  • Just Works with css-loader, extract-css, webpack, et all

decss style

Pros

  • simple "auto" api
  • easiest to read, just css
  • broad browser support
  • can determine which props should not be passed through

Cons

  • least dynamic, class scoped styling
  • bad typescript support for css prop
const Button = styled.button`
  display: inline-block;

  &.busy {
    background-image: url(...);
  }

  &.variant-primary {
    color: white;
    background-color: blue;
  }
  &.variant-secondary {
    color: black;
    background-color: palegray;
  }
`;

css prop

function Button({ variant, ...props }) {
  return (
    <button
      variant={variant}
      css={css`
        display: inline-block;

        &.variant-primary {
          color: white;
          background-color: blue;
        }
        &.variant-secondary {
          color: black;
          background-color: palegray;
        }
      `}
      {...props}
    />
  );
}

decss with custom props

Pros

  • fully dynamic values from js
  • simple "auto" api
  • easier to read than SC/emotion version

Cons

  • can't fully determine which props should not be passed through
  • no ie11 support for interpolations
const Button = styled.button`
  display: ${p => p.display || 'inline-block'};

  &.busy {
    background-image: url(...);
  }

  &.variant-primary {
    color: white;
    background-color: blue;
  }

  &.variant-secondary {
    color: black;
    background-color: palegray;
  }
`;

css prop

same as above

styled components/emotion

Pros

  • Most dynamic
  • css prop version is workable in typescript
  • easier to read than SC/emotion version

Cons

  • can't determine any of the props should be not passed through
  • no ie11 support
  • no conventions around prop structure and api's
const Button = styled.button`
  display: inline-block;

  /* this would use css props, but doesn't technically need to. hard to optimize tho*/
  background-image: ${p => p.busy && 'url(...)'};

  ${p =>
    p.primary &&
    css`
      color: white;
      background-color: blue;
    `}

  ${p =>
    p.secondary &&
    css`
      color: black;
      background-color: palegray;
    `}
`;

css prop

function Button({ variant, ...props }) {
  return (
    <button
      css={css`
        display: inline-block;

        ${variant === 'primary' &&
          css`
            color: white;
            background-color: blue;
          `}

        ${variant === 'secondary' &&
          css`
            color: black;
            background-color: palegray;
          `}
      `}
      {...props}
    />
  );
}

more doc?

amazing work!

i want use this loader in a side project, but just can't make it work right.
would the doc be more specifically?

install && usage? theme? best practice ...

What are advantages towards linaria? It may be nice to have some comparison with other libs.

Hi, it would be nice to have comparison with other zero-runtime css-in-js libs.
Maybe even in README.md.
For example, I have tried linaria — on trivial cases it feels the same. More or less.
But I think there will be differences in big projects, in complex cases;
Why use astroturf? Better performance, better support, some core differences that are invisible from the start? This information may help alot.

Regards.

Consider changing the default extension to .module.css

This is the covention most frameworks seem to be adapting for differentiating css module files nowadays. Using this as the default extension would mean there is no additional css-loader setup for uses in Gatsby, CRA, etc

Rewrite first paragraph

The first paragraph is critical for open source tool promotion. We spend few days in rewriting main thee first sentence in PostCSS docs.

The current first paragraph is good, but we can do it better:

  1. Explain what is a difference. Most styled-components users don’t know how it works inside.
  2. Use simple English since most of the developers are not English native speakers.
  3. Talk to users of non-CSS-in-JS solutions

My first draft (it definitely should be changes, at least English should be fixed):

astroturf is zero-runtime CSS-in-JS. In contrast to styled-components it doesn’t compile CSS in brower. astroturf use Babel to compile styled to static CSS once on deploy for better perfomance. It’s just works with CSS, PostCSS, Less, Sass, or any other css preprocessor, and plays nicely with existing style tooling like mini-css-extract-plugin.

[code example]

astroturf allows you to write CSS in JS files, so have the whole component in the single file. Like CSS Modules it has built-in CSS isolation for better code maintainability.

Add Preact support

Preact is a great React alternative for many use cases. It will be nice to have out-of-box support for styled API.

decss

What do you think about decss project? (syntax sugar over CSS Modules with styled-component’s like React components).

How can I combine decss and css-literar-loader?

Add keyframes and injectGlobal support

I am trying to move my project to your awesome tool. And I miss two methods from styled-components API:

keyframes should return @keyframes with unique name. injectGlobal should allow to pass CSS without added unique classes.

Statically analyzable base64 strings

On a previous project I used https://github.com/TrySound/postcss-inline-svg to inline SVGs.
It would make sense (IMO) for the following to work:

import dropdownIcon from 'url-loader!./assets/icons/dropdown.svg';

css`
.dropdown {
    background-image: url(${dropdownIcon});
}
`

Is there any way to make it work? Or have I gotten the definition of "statically analyzable" completely wrong?

[Feature Request] Adapting based on props

I think that we can support Adapting based on props by compiling it to style prop.

// input
const Color = styled('span')`
  color: ${(props) => props.color};
`;

// output
const Color = (props) => {
  return (
    <span className={...} style={{ color: props.color }}>
      {props.children}
    </span>
  );
}

Sourcemaps?

Hi there 👋
I've been looking through the code (because I want to make something similar to this). Good work here! I'm wondering whether you're handling sourcemaps. Just unsure whether I missed it somewhere or if it isn't supported yet. If it's not, then I may be able to contribute back sometime :)

Broken CSS if using &:hover and etc

Project created with CRA, config-overrides setup:

config.module.rules.push({
    test: /\.(js|mjs|jsx|ts|tsx)$/,
    use: [
        {
	     loader: 'astroturf/loader',
             options: { extension: '.module.css' },
        },
    ],
})

Components code:

export const OptionElement = styled('li')`
    padding: 8px 10px;
    list-style-type: none;

    &:hover {
        background-color: red;
    }
`

Result CSS:

.OptionElement_option-element__3KySt {
    padding: 8px 10px;
    list-style-type: none;
    (!) &: hover {;
    (!) background-color: red;
    (!)}: ;
}

AstroTurfLoaderError: Cannot use the decorators and decorators-legacy plugin together

I'm looking for css-in-js library for my project, linaria and astroturf are in my preference.
astroturf looks better for me because we already use css modules using .less.

The problem is when I use { legacy: true } for @babel/plugin-proposal-decorators build will crash with error message: AstroTurfLoaderError: Cannot use the decorators and decorators-legacy plugin together.

My babel config is:

{
    presets: [
        ['@babel/preset-env', {
            loose: true,
        }],
        '@babel/preset-react',
    ],
    plugins: [
        '@babel/plugin-syntax-dynamic-import',
        [
            '@babel/plugin-proposal-decorators',
            { legacy: true },
        ],
        '@babel/plugin-proposal-object-rest-spread',
        ['@babel/plugin-proposal-class-properties', { loose: true }],
        [
            '@babel/plugin-transform-runtime',
            {
                corejs: false,
                helpers: true,
                regenerator: true,
                useESModules: false,
            },
        ],
    ],
}

What i do wrong?

SSR and code-splitting examples

First off I'd like to say great work on this library.

Has anyone got the library working with an SSR setup? I'm particularly interested in extracting the CSS for a component into <style> tags in the HTML document.

Additionally does anyone know of an example of code splitting with this library?

Css specificity

Hi! I like you library and have one question:
How I can make css specificity for elements?
For example, I have semantic-ui component with .ui.menu {color: red} in library css.

If I do something like this, it's don't replace color:

const styles = css`
.replaceColor {
   color: green;
}`

.headerMenu-styles_replaceColor__lrgNe specificity less that .ui.menu

I use little hack for that, add pseudo-class .replaceColor::nth-child(n) or use repeated class .replaceColor.replaceColor

Maybe you know more elegant solution? Thanks! :)

Add Rollup support

It would be great to see rollup plugin/loader or example in the docs if it's already possible.

New name

This has grow past a simple webpack loader! We should pick a proper name any suggestions?

Source map support

I found good feature in linaria. Source map support should not be so hard if Babel gives you a position for a literal node.

We need:

  1. Take source-map (0.7 use async API, if it is a problem, using 0.6 is OK. I still use 0.6 in PostCSS, because we can’t use async API in few places)
  2. For every literal tag generator.addMapping.
  3. In the end, generate source map, encode it to data:uri and add to CSS file.

0.8: Cannot read property 'node' of null

I updated astroturf and got this error during test:

    TypeError: Cannot read property 'node' of null

      at importNodes.forEach.path (node_modules/astroturf/plugin.js:180:18)
          at Array.forEach (<anonymous>)
      at PluginPass.post (node_modules/astroturf/plugin.js:175:19)
      at transformFile (node_modules/@babel/core/lib/transformation/index.js:94:27)
      at runSync (node_modules/@babel/core/lib/transformation/index.js:45:3)
      at transformSync (node_modules/@babel/core/lib/transform.js:43:38)
      at transform (node_modules/@babel/core/lib/transform.js:22:38)

My Babel config:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "loose": true
      }
    ]
  ],
  "plugins": [
    "./builder/auto-import",
    "babel-plugin-transform-typograf",
    [
      "@babel/plugin-proposal-decorators",
      {
        "legacy": true
      }
    ],
    "@babel/plugin-syntax-dynamic-import",
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-proposal-object-rest-spread"
  ],
  "env": {
    "test": {
      "plugins": [
        "babel-plugin-dynamic-import-node",
        [
          "astroturf/plugin",
          {
            "allowGlobal": true,
            "writeFiles": false
          }
        ],
        [
          "babel-plugin-transform-rename-import",
          {
            "replacements": [
              {
                "original": "^.*\\.(css|less|sss)$",
                "replacement": "identity-obj-proxy"
              }
            ]
          }
        ]
      ]
    }
  }
}

Better onbording for styled-components users

There is very popular API in Emotion and Styled Components styled.div instead of styled('div').

I pretty sure, that most of Styled Components user will make the mistake and write styled.div.

Maybe we should improve error message for them? Like:

if (process.env.NODE_ENV !== 'production') {
  styled.div = () => {
    throw new Error('Use styled("div") instead')
  }
}

With process.env.NODE_ENV !== 'production' we will not increase runtime size in production.

TypeScript support

Hi,

I discovered astrotruf via twitter some hours ago and Im very impressed! Great work! 👍

I wonder what would be the best way to add TypeScript definitions. Its somehow different compared to styled-components.

I guess for the component API something like this would be fine:

const Button = styled<{primary?: boolean; color: 'green'}>('button')`
  color: black;
  border: 1px solid black;
  background-color: white;

  &.primary {
    color: blue;
    border: 1px solid blue;
  }

  &.color-green {
    color: green;
  }
` // JSX.IntrinsicElements.button & {primary?: boolean; color: 'green'};

But the css API gives me a headache:

const styles = css<{box: string; footer: string}>`
  .box {
    height: ${height}px;
    margin-bottom: ${margin}px;
  }

  .footer {
    position: absolute;
    top: ${bottom}px;
  }
`;

Both way are somehow error prone (what is if I forgot to rename the class inside the tagged string literal?)....

Would be great to start some discussion here :)

Any ideas?

Reference to other components

Hi! Can I use reference to other components like in styled-components?

For example:

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

const Icon = styled.span`
  color: yellow;

  ${Button}:hover & {
    color: green;
  }
`;

Need help with jest

Hi! When I run test I recive this error:

 FAIL  src/Button/tests/Button.test.tsx
  ● Test suite failed to run

    `css` template literal evaluated at runtime!

       6 | };
       7 |
    >  8 | const styles = css`
         |             ^
       9 |   .button{
      10 |     color: red;
      11 |

      at css (node_modules/astroturf/runtime/styled.js:98:9)
      at Object.<anonymous> (src/Button/Button.tsx:8:13)
      at Object.<anonymous> (src/Button/tests/Button.test.tsx:3:1)

I think I need to configure transform prop in jest config or modify babel config with test env, but I don't know exactly how. Any ideas?

React Native support

One of the biggest reason to use styled-components is RN support.

It definitely, should be some CSS→RN loader for webpack. We need only show some example in the docs.

Empty style object

import { css } from 'css-literal-loader/styled'

let styles = css`
  .bold {
    font-weight: bold;
  }
  .list {
    padding: 8px 0;
  }
  .item {
    padding: 2px 0;
    margin-left: 15px;
    color: var(--dangerous);
    list-style: disc;
  }
`

console.log(Object.keys(styles))

Prints [].

It could be environment or config problem. But I have no idea where I shouls look at.

Toggle visible state pure css

How to toggle visible ? Like sass example

.parent {
  color: red;
 
  .child {
    display: none
  }
  
  &:hover {
    .child {
      display: block
    }
  }
}

webpack 4 support

Thank you for this!

Any plans to make it support webpack 4? Currently it throws:

ERROR in ./src/components/app.jsx
Module not found: Error: Can't resolve './app__css_literal_loader_0.css'

Issue with README

See 'as' prop example & code example below there seem to be syntax errors & missing code

Component property not working with composes

const mixins = css`
   .show {
      display: block;
   }
`;

const Block = <BlockStyled active={false} />

const BlockStyled = styled.div`
    &.active {
       composes: ${mixins.show};
    }
`;

Styles from mixins apply regardless of active property.

CSS Tricks article

New step in tool promotion is to write an article.

CSS Tricks is a good platform for the first article.

How I see the content:

  1. Compare different types of CSS-in-JS: inline styles, runtime, zero-runtime.
  2. Explain why zero-runtime CSS-in-JS is good for CSS-out-JS users
  3. Show a simple example of how to add it to a new project.
  4. Show a bigger example of adding CSS-in-JS with the existed project. How to migrate (keep old components with CSS-out-JS, move CSS into JS in new components). How to add Autoprefixer, Sass, etc support.

Unfortunately, I can’t help with writing because I am not native.

boolean props are stripped

If you have styled component that accepts bool modifiers, it will strip any boolean prop, not just the relevant ones.

const Foo =({ grow }) => <div>{String(grow)</div>

const StyledFoo = styled(Foo)`
  &.bar {
     color: red;
   }
`

Does not work with stylelint

I am using the postcss-loader with the stylelint plugin. When I'm using css-literal-loader I get the following error:

ERROR in ./~/css-loader?modules&camelcase&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!./~/postcss-loader!./src/App__css_literal_loader_0.css
Module build failed: Error: ENOENT: no such file or directory, stat '/css-experiments/src/App__css_literal_loader_0.css'
    at Error (native)
 @ ./src/App__css_literal_loader_0.css 4:14-221 13:2-17:4 13:2-17:4 14:20-227

This could be due to how stylelint works. But it would be a killer feature. This could be considered a feature request. Maybe this can be used as inspiration: https://github.com/styled-components/stylelint-processor-styled-components

Are BEM-style class names possible?

Hi.
I want to get classes like Card and Card--large.
In the documentation I found an example like this:

const Card = styled('form')`
width: 150px;
height: 120px;
&.large {
  width: 300px;
  height: 240px;
}
`;
// …
return (<Card large />);

It will generate somethins like this:

<form class="UserCard-Card--3mYhX UserCard-Card--2O_am"></form>

with webpack config

    module: {
      rules: [
        {
          test: /\.css$/,
          use: [
            { 
              loader: "style-loader",
            },
            { 
              loader: "astroturf/css-loader",
              options: {
                modules: true,
                localIdentName: '[name]--[hash:base64:5]',
              },
            }
          ],
        },
        {
          test: /\.jsx?$/,
          exclude: /node_modules/,
          use: ['babel-loader', 'astroturf/loader'],
        }
      ]
    },

But is there any way to get canonical BEM .Card and .Card--large classes?

<form class="Card__3mYhX Card--large__3mYhX"></form>

Regards. Anton.

Using in a shared component library

A major sticking point for people with zero-runtime CSS-in-JS solutions (e.g. css-modules) has been around code-sharing. The import styles from './styles.css'; is problematic since its not a standard node module.

Currently, I see a few (unideal) options:

  1. Pre-compile the styles before publishing the shared component, and distribute the component JS and namespaced CSS separately.
  2. Distribute the component as-as, requiring consumers to deal with transforming the CSS Module imports.

The benefit of #1 is that your consumers don't have to use css-loader. The downside is they have to manually import your pre-build css file.

@ai and I discussed and a good solution might be a babel version of style-loader. More context: https://twitter.com/lunde_andrews/status/1034116264774516737.

Import variables from other files?

How can I import variables from other files?

I would have something like theme.js:

export default {
  primary: '#fff'
}

Then I would import it using import theme from './theme'

and use it with ${theme.primary} inside my css-literal.

But I always get CssLiteralLoaderError: Could not evaluate css. inline css must be statically analyzable, if I import the css from another file.
Within the same file it works but I would like to share a theme across many css-literal definitions.
Every help is gladly appreciated.

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.