Giter VIP home page Giter VIP logo

cxs's People

Contributors

aaronyo avatar andykog avatar asvny avatar johno avatar jxnblk avatar lachlanjc avatar lukebrooker avatar marudor avatar mihalik avatar ooflorent avatar posgarou avatar richard-lopes avatar timolins 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

cxs's Issues

transpile pain pile

var cxs = require('cxs').default
Otherwise folks who write JavaScript get an error:

csx is not a function

plugin system

Since you've moved away from glamor, I was curious if you would be willing to support a plugin system similar to theirs?

I do something similar to your styled-system library with glamor's plugin system right now:

const designSystemPlugins = [
  flex,
  position,
  size,
  space,
  border,
  typography,
  color,
  elevation,
  misc,
  fixVerticalRhythm,
]

designSystemPlugins.forEach(func => {
  glamor.plugins.add(({ selector, style }) => ({
    selector,
    style: func(style),
  }))
})

It would be awesome if we could do something like this with CXS, where any value I pass like cxs({ elevation: 2 }) would know how to get resolved. This would be similar to something like PostCSS where you can parse styles in one spot and not have to import them every time. I think this could also help with vendor prefixing and being able to handle this in one spot as well.

Using css keyframes

Hello, guys!

The lib is great. I like it

But, can you, please, explain how to use css animations in cxs function?

Pseudo elements don't work?

So a style like this doesn't appear to correctly produce any pseudo elements:

const style = {
  ':before': { 
    content: 'wat',
    color: 'red' 
  },
  ':after': { 
    content: 'dafuq',
    color: 'blue'
  }
}

Specificity woes with border styles

There are cases where a border declaration to specify color is overridden if the base border style ends up later in the included styles. Here is an example of output (via axs):

<style type="text/css">
.m-0{margin:0px}.box-sizing-border-box{box-sizing:border-box}.bc-6872e0{background-color:#6872e0}.c-fff{color:#fff}.p-8{padding:8px}@media screen and (min-width:40em){._19tr68s{padding:8px}}@media screen and (min-width:52em){._eov9nk{padding:16px}}@media screen and (min-width:64em){._1ikqg2r{padding:32px}}.fs-24{font-size:24px}@media screen and (min-width:40em){._1wdkpsw{font-size:32px}}@media screen and (min-width:52em){._1ry5oku{font-size:48px}}@media screen and (min-width:64em){._kl9u05{font-size:64px}}.h-6{height:6px}.bc-fff{background-color:#fff}.w-64{width:64px}.mt-8{margin-top:8px}.mb-16{margin-bottom:16px}.border-color-ebedee{border-color:#ebedee}.border-1px_solid{border:1px solid}.cursor-pointer{cursor:pointer}.text-decoration-none{text-decoration:none}._1hjd5bo{transition:transform .25s ease-in-out}._bpjteq:focus{text-decoration:underline}._k2lktg:focus{transform:scale(1.25)}._atw0tk:hover{text-decoration:underline}._j1mkku:hover{transform:scale(1.25)}.c-6872e0{color:#6872e0}
</style>

The problematic portion is near the end of the above blob:

.border-color-ebedee {
  border-color: #ebedee;
}

.border-1px_solid {
  border: 1px solid;
}

Resulting in the following application of styling (Chrome):

unspecified

I have time later today to dig into getting a PR together, though perhaps I should wait for the monorepo work to complete?

How can I set global styles as well?

I have been using styled-jsx but go interested to convert my little project to cxs.
So far, so good. It looks like everything is working but one thing.

I had the following global styles defined that I can't seem to be able to convert to cxs:

body::before {
    background-color: #5f00a8;
    background: linear-gradient(135deg, #5f00a8 35%, #ed005f 100%);
    content: '';
    display: block;
    height: 3px;

    position: fixed;
    top: 0;
    width: 100%;
    z-index: 1;
  }

  html, body, #root {
    height: 100%;
  }

Is there any way I can apply styles to the html and body tags of the container page ?

CSS animations

Hey guys!
Awesome work on V3, the modes idea is awesome!

I'm having some problems with animations though..
I've tried using animationName and @keyframes but none are outputing css.

cxs({
    animationName: {
        from: {
            background: 'red',
        },
        to: {
            background: 'blue',
        },
    },
});

or

cxs({
    animationName: 'test',
    '@keyframes test': {
        from: {
            background: 'red',
        },
        to: {
            background: 'blue',
        },
    },
});

Can you guys have a look into it?
Thanks in advance!

Add prettier.js to package.json devDependencies

This would allow all contributors to use the same version of prettier.

For a specific example of how not doing this complicates PRs, see #86.

Last time I checked (a few months ago) formatting was still changing a decent bit between updates to prettier. Regardless, there's no guarantee it won't change again.

a better maintained alternative `klick`

Aloha @jxnblk ๐Ÿ‘‹

First off, thanks a lot for putting your ideas together in cxs. In a lot of ways, this package powers some of the nice UI abstractions I am building recently.

However, looking at #98, it seems cxs is not going to be maintained in future. Considering some users (like myself) might still be interested in a small size package that satisfies their styling needs, I started working on a forked version of cxs in klick

While klick, attempts to abstract lot of other things (vdom, state container, etc.), the relevant code for styling solution is here. In general, the dist bundle for klick is tree-shakable, so other features shouldn't be taxing while importing css from klick

Few areas klick differs from cxs

  • klick uses auto incrementing atomic classnames. I've found this to be generating much smaller class names. Specially helpful in SSR scenarios.
  • css portion of klick is framework agnostic. We support all frameworks by supporting none.
  • No dynamic component styling yet - considering klick attempts to be framework agnostic, it does not have dynamic component styling yet. This is however on my roadmap.

Please feel free to close this issue if it seems irrelevant for this repo. I just wanted to get the word out.

Usage with extract-text-webpack-plugin

Hi there ๐Ÿ‘‹. Great module, I love it!

I just wanted to let you know that I've hacked myself a small setup where I'm able to extract the CXS styles into separated CSS files for production builds with webpack. The benefit of this approach is that webpack will generate a CSS file for each chunk with just the styles that are required.

The setup consists of a custom loader (not published yet) and the extract-text-webpack-plugin.

The loader source:

// exportCssLoader.js
const exportCss = `module.exports = ((cxs, oldExports) => {
    const newExports = [[module.id, cxs.getCss()]];

    Object.assign(newExports, oldExports);

    newExports.locals = oldExports;
    cxs.reset();

    return newExports;
})(require("cxs"), module.exports);`;

module.exports = function (source, sourceMaps) {
    this.callback(null, source + ";" + exportCss, sourceMaps);
};

The webpack config:

// webpack.config.js
            ...
            // loader config
            {
                test: /\.css\.js$/,
                use: ExtractTextPlugin.extract([
                    // the babel-loader is only required if you use
                    // ES features that node isn't able to understand
                    {
                        loader: "babel-loader",
                        options: {
                            cacheDirectory: true,
                            sourceMaps: false,
                        },
                    },
                    {
                        loader: require.resolve(
                            "../tools/webpack/exportCssLoader"
                        ),
                    },
                ]),
            },

        ...
        // plugin config
        new ExtractTextPlugin({
            filename: "[name].[contenthash].css",
            disable: isDev,
        }),

There are maybe some edge cases I haven't thought about yet, but that's the gist. What do you think? Should the loader be published separately or together with this repository?

global css creation

Is there any way or any plans to allow global css creation? Sorry, another feature of glamor that I'm missing and think could be beneficial here ๐Ÿ˜‡

I run into some projects where I need to create html or body styles, or even reset CSS. It'd be nice to stay in one place and be able to do that without creating a stylesheet. I was curious if some things could be tweaked to expose some internal helper to do this?

Also, since I'm on the topic of glamor features, I was wondering if things like fontFace and keyframes features could be added for CXS as well? I'd be happy to submit PR's. I think we could get away with separate packages like import fontFace from 'cxs/font-face'.

multiple pseudo selectors

is there a way to do this w/ ::before and ::after on the same line to save writing display: "block" twice?

":hover": {
    "::before": {
      display: "block"
    },
    "::after": {
      display: "block"
    }
  }

Idea: make the class name prefix 'x' a parameter

I have a few components that are built separately as different bundles. They come with their own styles and get merged into an app.
However, I am not sure cxs supports that kind of use case. Since style tags are added to the parent HTML document there are collisions.

in src/cxs/index.js, line 20 we have this: const className = 'x' + (rules.length).toString(36)
'x' is a hardcoded prefix. What if we allow alternative prefixes to be passed? Ideally once at initialization of the library.

That way we could define separate prefixes in different projects and when they get mashed up (at runtime for example), the written styles do not collide.

Rehydration

Hey guys, was wondering why you guys don't implement client rehydration like Aphrodite and Glamor do?

Isn't this a bit wasteful, since all the CSS is already generated?

Are you looking for help to maintain the project?

Hello,

Our team have been an user of cxs for a few months and we like its simplicity and light size. Perfect when shipping simple widgets.

We would love to use it for larger apps and this is why having optional extra features that one could use on top of the library would be great.

I see a few great PRs are waiting to be merged and 2-3 are spot on what we have been looking for.
I do understand that maintaining many open source projects like you do is a super consuming exercise. But instead of having people fork this project to add the bits and pieces they need, it would be great if we could grow this repo. and benefit everybody.

If you are looking for co-maintainers to help out with this library, just give us a shout. As for one would be glad to help out.

Thanks.

Why hash if using singleton styles?

You're using a global cache & stylesheet, so why bother including a hash dependency when you control collisions anyway. Your cache is already a hash table, so you could simply use an auto-incrementing global index (ala cxs-{idx}). An (small) additional benefit beyond the reduced bytes from hash dependency would be the reduced bytes per class name. You could even reset the index via your reset method, for consistent class names when server-side rendering.

Am I missing something?

Great module!!

Sometimes appending `px` to a number breaks a property.

For CSS rules, properties that can take a number, if you give a number a px will be appended automatically. It does work with common properties like height, width... But it adds unwanted px for z-index or flex for example.
We could document that a workaround to this is to use strings instead of numbers like so for those properties: flex: '1' or zIndex: '1' to prevent a px to be appended.

Media Query Grouping of Styles Issue

When using the same media query and style between multiple components the styles are grouped into one media query and class name at the point the first component is rendered. This causes styles in the second component to overwrite the styles used in the media query. In the following example both buttons should be green when the screen width is above 900px:

http://www.webpackbin.com/VJInpkAHf

CSSStyleSheet.insertRule?

Hi there, very cool project! ๐Ÿ˜„

I was just curious what your reasoning was for using insertRule over something like:

styleTag.appendChild(document.createTextNode(css))

I'm guessing insertRule probably has better performance (maybe?), but one possible downside I've noticed is it looks like the styles contained in the stylesheet aren't visible when inspecting the style element.

Font styles aren't working

Here's the DOM node:

<h1 data-component="Heading" data-kind="page" class="ff-'Handlee'__cursive">Lacqueristas</h1>

Here's the styling sheet per Chrome:

element.style {
}
@media (min-width: 550px)
h1 {
  font-size: 5.0rem;
}
h1 {
  font-size: 4.0rem;
  line-height: 1.2;
  letter-spacing: -.1rem;
}
h1, h2, h3, h4, h5, h6 {
  margin-top: 0;
  margin-bottom: 2rem;
  font-weight: 300;
}
h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

Here's the style object:

const headingsStyle = {
  page: {fontFamily: "'Handlee', cursive"},
}

Here's the static CSS generated server side:

.ff-'Handlee'__cursive {
  font-family: 'Handlee', cursive
}

Is this repository dead?

While I really love the idea and all, I see the repository hasn't been updated in a very long time. That is kind of a show stopper.

Media queries not deterministic.

I'm experiencing a lot of issues with media queries and out-of-order/conflicting rules.

Does cxs handle media queries intelligently, ie: are the rules generated in the order provided by the properties? I'm defining these media queries from smallest to largest.

Sometimes it seems adding a property to a media query ends up affecting unrelated things. I haven't been able to pinpoint a specific case, it all feels very arbitrary (although I'm sure there's a good reason as to why it's happening).

Crazy idea: Support class composition

Not sure whether this is possible, but think it would have been great if cxs supported composing of classes. Something like this:

const className = cxs.compose('pa4 code white bg-blue mb2 ba b--black-10')

So that a new class name that will compose all these styles will be created.

CSS vendor prefixing

Hello,

As far as I know cxs doesn't support vendor prefixing. When you use "advanced" CSS features this can become a problem for any older browser.
I was wondering if there was a plan to add support for that (increasing the library size) or if there was a way to maybe post-process the CSS generated by cxs.
In that category I was looking at stylis that styled-jsx uses: it is very fast and does prefixing among a few other things. But integration is likely big changes.
If you know of any solution or workaround to use on top of cxs that we could use today, that would be helpful.

typescript version inside

better editor feedback without being aidsy than pretty much every other style library (at least imo)

import React from 'react'
import { HTMLProps, CSSProperties } from 'react'
const h = React.createElement

//new CSSRuleList() //items, length
//let r = new CSSStyleRule

//was using this like this, jus took context out though idk, deal later
//{theme: defined(context.theme, props.theme, pallete: 'none')}
const defined = (...args) => {
  for (var i = 0; i < args.length; i++) {
    if (args[i] !== undefined) return args[i]
  }
}

let cache = {}
let prefix = 'x'
const rules: CSSStyleRule[] = [] //[]

let insert = (rule: CSSStyleRule) => void rules.push(rule as CSSStyleRule)

const hyph = s => s.replace(/[A-Z]|^ms/g, '-$&').toLowerCase()
const mx = (rule, media) => (media ? `${media}{${rule}}` : rule)
const rx = (cn, prop, val) => `.${cn}{${hyph(prop)}:${val}}`
const noAnd = s => s.replace(/&/g, '')

const parse = (obj, child = '', media?) =>
  Object.keys(obj)
    .map(key => {
      const val = obj[key]
      if (val === null) return ''
      if (typeof val === 'object') {
        const m2 = /^@/.test(key) ? key : null
        const c2 = m2 ? child : child + key
        return parse(val, c2, m2 || media)
      }
      const _key = key + val + child + media
      if (cache[_key]) return cache[_key]
      const className = prefix + rules.length.toString(36)
      insert(mx(rx(className + noAnd(child), key, val), media))
      cache[_key] = className
      return className
    })
    .join(' ')

function cxs(...styles) {
  return styles
    .map(style => parse(style))
    .join(' ')
    .trim()
}

cxs.css = () => rules.sort().join('')

cxs.reset = () => {
  cache = {}
  while (rules.length) rules.pop()
}

cxs.prefix = val => (prefix = val)

if (typeof document !== 'undefined') {
  const sheet = document.head.appendChild(document.createElement('style')).sheet as CSSStyleSheet
  insert = (rule: CSSStyleRule & string) => {
    rules.push(rule as CSSStyleRule)
    sheet.insertRule(rule, sheet.cssRules.length)
  }
}

type DomProps = Partial<HTMLProps<any>>
type CSX = { css?: CSSProperties }
type StyledCSX = DomProps & CSX

type Proptional<P> = CSSProperties | ((...args: P[]) => CSSProperties)

function styled<P>(C) {
  return (...args: Proptional<P>[]) => {
    const Comp = (props: P & StyledCSX) => {
      const stylePropKeys = [...Object.keys({}), 'css']
      //const styleProps = Object.assign({ theme: defined(context.theme, props.theme, {}) }, props)

      const next: any = {}
      for (let key in props) {
        if (stylePropKeys.includes(key)) continue
        next[key] = props[key]
      }
      next.className = [
        next.className,
        ...args
          .map(proptional => (typeof proptional === 'function' ? proptional(props) : proptional))
          .filter(s => !!s)
          .map(s => cxs(s)),
        cxs(props.css || {}),
      ]
        .join(' ')
        .trim()

      return h(C, next)
    }

    return Comp
  }
}

styled.css = cxs.css
styled.reset = cxs.reset

export { cxs }
export { styled }
export default styled

// export function styledComponentWithProps<T, U extends HTMLElement = HTMLElement>(styledFunction: StyledFunction<React.HTMLProps<U>>): StyledFunction<T & React.HTMLProps<U>> {
//   return styledFunction as any;
// }

// thanks microsoft, please teach our youth how to read, i think you've got it figured out
// type Unpacked<T> = T extends (infer U)[]
//   ? U
//   : T extends (...args: any[]) => infer U
//   ? U
//   : T extends Promise<infer U>
//   ? U
//   : T

// type T0 = Unpacked<string> // string
// type T1 = Unpacked<string[]> // string
// type T2 = Unpacked<() => string> // string

// type Foo<T> = T extends { a: infer U; b: infer U } ? U : never
// type T10 = Foo<{ a: string; b: string }> // string
// type T11 = Foo<{ a: string; b: number }> // string | number

//type CC = (...args: CSSProperties[]) => infer R ? R : CSSProperties

//type ReturnType<T> = (...args) => T ? T : CSSProperties
// im going to space mountain charley fml

// function styled1(C) {
//   return (...args) => {
//     const Comp = (props, context: any = {}) => {
//       const stylePropKeys = [...Object.keys({}), 'css']
//       const styleProps = Object.assign({ theme: defined(context.theme, props.theme, {}) }, props)

//       const next: any = {}
//       for (let key in props) {
//         if (stylePropKeys.includes(key)) continue
//         next[key] = props[key]
//       }
//       next.className = [
//         next.className,
//         ...args
//           .map(a => (typeof a === 'function' ? a(styleProps) : a))
//           .filter(s => !!s)
//           .map(s => cxs(s)),
//         cxs(props.css || {}),
//       ]
//         .join(' ')
//         .trim()

//       return h(C, next)
//     }

//     return Comp
//   }
// }

usage

import React from 'react'
import { styled } from './styled'

type Props = {
  color: 'green' | 'black'
}

let MyButton = styled<Props>('button')(props => ({
  backgroundColor: (props.color && props.color) || 'green',
}))

let NoPropsButton = styled('button')({
  backgroundColor: 'green',
})

export { MyButton, NoPropsButton }


let Demo = props => <MyButton onClick={e => console.log('hi')} color={'black'}/>

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.