rtsao / csjs Goto Github PK
View Code? Open in Web Editor NEW:sparkles: Modular, scoped CSS with ES6
License: MIT License
:sparkles: Modular, scoped CSS with ES6
License: MIT License
Hello @rtsao I just wanted to check in and see what the general plan and direction for CSJS is. We've noticed that it's been some time since the last release and there hasn't been any major new additions or developments into CSJS itself for some time.
Asking mainly from the perspective of react-csjs, one of the options we've have been looking into is shipping CSJS internally along with that package to make things like automatically including extended styles a bit easier (since we can wrap the CSJS instance in a singleton and control that interface for the user) just to name an example. There's a handful of other things we're thinking about for the future of react-csjs that this combination would enable.
@wKovacs64 @drcmda and I would like to get your thoughts and see if you think this makes sense, etc.
Warning: Failed prop type: Invalid prop
className
of typeobject
supplied toActiveComponent
, expectedstring
.
Have to type style.css_class_name + ''
all the time...
I understand that that's some kind of React's limitations, because the object generated from csjs
string has toString()
method and should be treated by React as real string too.
What I doing wrong because I can't find the same issues from other people?
Would it make sense to standardize on a particular code style to make contribution easier? Here are results from running semistandard on master
.
csjs|master ⇒ ./node_modules/.bin/semistandard | wc -l
semistandard: Semicolons For All! (https://github.com/Flet/semistandard)
semistandard: Run `semistandard --fix` to automatically fix some problems.
69
csjs|master ⇒ ./node_modules/.bin/semistandard
semistandard: Semicolons For All! (https://github.com/Flet/semistandard)
semistandard: Run `semistandard --fix` to automatically fix some problems.
/Users/scott/Documents/sites/csjs/lib/base62-encode.js:10:33: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/build-exports.js:5:40: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/build-exports.js:6:60: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/build-exports.js:12:53: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/build-exports.js:17:43: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/build-exports.js:25:2: Missing semicolon.
/Users/scott/Documents/sites/csjs/lib/build-exports.js:27:23: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/build-exports.js:28:3: Split initialized 'var' declarations into multiple statements.
/Users/scott/Documents/sites/csjs/lib/build-exports.js:30:20: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/build-exports.js:31:45: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/composition.js:15:25: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/composition.js:37:37: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/composition.js:45:22: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/composition.js:60:23: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/composition.js:64:27: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/composition.js:65:32: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/composition.js:67:38: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/composition.js:78:21: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/csjs.js:12:39: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/csjs.js:16:30: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/csjs.js:18:9: 'values' is already defined.
/Users/scott/Documents/sites/csjs/lib/csjs.js:45:4: Missing semicolon.
/Users/scott/Documents/sites/csjs/lib/csjs.js:46:2: Missing semicolon.
/Users/scott/Documents/sites/csjs/lib/csjs.js:53:21: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/csjs.js:63:16: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/csjs.js:64:30: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/csjs.js:75:17: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/csjs.js:76:42: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/css-extract-extends.js:3:5: 'makeComposition' is defined but never used.
/Users/scott/Documents/sites/csjs/lib/css-extract-extends.js:7:41: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/css-extract-extends.js:8:3: Split initialized 'var' declarations into multiple statements.
/Users/scott/Documents/sites/csjs/lib/css-extract-extends.js:9:10: Expected a conditional expression and instead saw an assignment.
/Users/scott/Documents/sites/csjs/lib/css-extract-extends.js:13:31: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/css-extract-extends.js:21:41: Strings must use singlequote.
/Users/scott/Documents/sites/csjs/lib/css-extract-extends.js:25:37: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/css-extract-extends.js:42:1: Block must not be padded by blank lines.
/Users/scott/Documents/sites/csjs/lib/css-extract-extends.js:44:18: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/css-extract-extends.js:48:22: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/extract-exports.js:10:24: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/extract-exports.js:18:19: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/extract-exports.js:21:3: Expected space(s) after "while".
/Users/scott/Documents/sites/csjs/lib/get-css.js:5:33: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/hash-string.js:8:34: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/hash-string.js:13:45: Missing semicolon.
/Users/scott/Documents/sites/csjs/lib/regex.js:13:33: Unexpected trailing comma.
/Users/scott/Documents/sites/csjs/lib/replace-animations.js:5:27: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/replace-animations.js:6:65: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/replace-animations.js:14:8: '+' should be placed at the end of the line.
/Users/scott/Documents/sites/csjs/lib/replace-animations.js:17:54: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/replace-animations.js:25:6: Missing semicolon.
/Users/scott/Documents/sites/csjs/lib/scoped-name.js:6:37: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/scoped-name.js:9:29: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/scoped-name.js:11:4: Missing semicolon.
/Users/scott/Documents/sites/csjs/lib/scopeify.js:11:17: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/scopeify.js:18:20: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/lib/scopeify.js:20:23: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/test/index.js:34:23: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/test/index.js:40:22: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/test/index.js:45:17: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/test/index.js:46:34: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/test/index.js:53:21: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/test/index.js:64:4: Missing semicolon.
/Users/scott/Documents/sites/csjs/test/index.js:67:10: 'moduleExists' is defined but never used.
/Users/scott/Documents/sites/csjs/test/index.js:67:22: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/test/index.js:70:5: Expected space(s) after "catch".
/Users/scott/Documents/sites/csjs/test/index.js:75:10: 'fixturePath' is defined but never used.
/Users/scott/Documents/sites/csjs/test/index.js:75:21: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/test/index.js:79:23: Missing space before function parentheses.
/Users/scott/Documents/sites/csjs/test/index.js:80:42: Missing space before function parentheses.
How would this work with csjs/csjs-inject? Doesn't look like anyone has tried this yet.
I don't know if this is helpful or not, but in comparing the various CSS in JS techniques, I stumbled across csjs, Aphrodite and JSS. I liked the interface that react-jss
allows and noticed there wasn't an equivalent HoC for csjs.
So I've written one: react-csjs.
The initial implementation is admittedly very basic and bare-bones, but it provided enough utility for me that I figured it may help others and I decided to publish it. Let me know your thoughts -- happy to improve/change things around in any way you see fit.
Thanks!
Object.assign()
is not supported even in IE11 and in iOS 7 and 8 (I know they are very buggy but they exist yet).
Line 27 in 695d782
Please, rewrite that into something more supported.
Any thoughts on syntax highlighting?
Related:
Hi, I have a problem with scoped, multi-valued animations. Looks like it doesn't work as expected for me. For example the following code
.foo {
animation: keyframe-1 1s ease-in-out, keyframe-2 .5s linear;
}
.bar {
animation-name: keyframe-1, keyframe-2;
}
@keyframes keyframe-1 {}
@keyframes keyframe-2 {}
will result in
.foo_4y20Hz {
animation: keyframe-1 1s ease-in-out, keyframe-2_4y20Hz .5s linear;
}
.bar_4y20Hz {
animation-name: keyframe-1, keyframe-2_4y20Hz;
}
@keyframes keyframe-1_4y20Hz {}
@keyframes keyframe-2_4y20Hz {}
Only the last animation-name is prefixed within a declaration value.
Just need to copy this setup probably https://github.com/rtsao/scope-styles/tree/master/test
Like these:
.my-nav-tabs li .active {
...
}
when .active
is in global scope or is an another class defined in the same csjs
literal or imported from another csjs variable..
hey, i'm using this in an electron app but want to write components that work in both electron and the browser
given code like this:
var csjs = require('csjs-inject')
module.exports = csjs`
.foo { color: salmon }
`
in electron, since no bundling is required, csjs-inject
is the only way to use csjs. but in a browser I would want to change it to use csjs
instead. maybe if you use the browser
field of package.json and override csjs-inject with a no-op if it's being bundled with browserify then the same code would work for both use cases?
Like here: http://www.snaptrax.org/assets/scss/_component-examples.scss
.bd-example-row {
.row {
margin-bottom: 1rem;
> [class^="col-"] {
padding-top: .75rem;
padding-bottom: .75rem;
background-color: rgba(86,61,124,.15);
border: 1px solid rgba(86,61,124,.2);
}
}
}
With CSJS syntax, how do you use tools such as emmet to expand your CSS code?
Do you use something in particular?
Current way of parsing extends is way too slow. It takes up most of my (small) app's load time. Here is a screenshot from Chrome's Timeline. Looks like it takes 95%+ of the whole script eval.
Wrapping regex parse in
if (css.indexOf('extends') > 0) {
while (found = regex.exec(css)) {
matches.unshift(found);
}
}
reduced page load time by about 1.3 seconds. I tried removing every single extends
from my scss, it doesn't really matter, the pattern is just slow by itself.
Just so they show up in releases
Example:
csjs|develop⚡ ⇒ node -v
v5.4.0
csjs|develop⚡ ⇒ node
> var csjs = require('.');
undefined
> var a = csjs`.foo { width: 10.5px; }`;
undefined
> a
{ foo:
Composition {
classNames: [ 'foo_11OMB8' ],
unscoped: [ 'foo' ],
className: 'foo_11OMB8',
selector: 'foo_11OMB8' },
'5px;':
Composition {
classNames: [ '5px;_11OMB8' ],
unscoped: [ '5px;' ],
className: '5px;_11OMB8',
selector: '5px;_11OMB8' } }
>
This is an issue with var classRegex = /(\.)([^\s\.,{\[>+~#:]*)/g;
because it performs a global search. Something like /^\s*(\.)([^\s\.,{\[>+~#:]*)/
could work, but ONLY if input is split into nice lines before replacing. Example:
var a = csjs`.foo { width: 10.5px; } .bar { width: 11.5px; }`
// this would have to internally changed to the "split up" version
// .foo {
// width: 10.5px;
// }
// .bar {
// width: 11.5px;
// }
I love how standard css seems to "just work" with csjs but I've noticed an ambiguity surrounding the extends syntax and css selector grouping, due to the use of commas to separate both selectors and extend targets.
.styleA,
.styleB {
background: red;
}
.styleA extends .baseStyle,
.styleB {
background: red;
}
If we don't use a class, can we eliminate it from the injectify/extractify output?
Some sample cases and benchmark tooling will make identifying performance improvements easier.
Hi guys,
thanks for a finally nice approach to CSS-in-JS.
I've created an issue to add improved tagged literal injected language support to IntelliJ IDEA.
Please vote there
https://youtrack.jetbrains.com/issue/WEB-22106
if you'd like to get it done.
Feel free to delete this issue if it bothers your flow.
Thanks.
Hi.I wrote the following style with csjs v.1.0.3
module.exports = csjs`
@media screen and (min-width: 769px) {
.columns:not(.is-desktop) {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
}
`
But it is expanded as follows
module.exports = csjs`
@media screen and (min-width: 769px) {
.columns_2B2Wm:not(.is-desktop)_2B2Wm {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
}
`
The .toString()
technique employed by csjs can be problematic when used in conjunction with React.PropTypes.string
.
Rather than requiring string coercion on behalf of the user, a helper method to return an object of true strings may be convenient.
Context: #56
Something like:
const green = '#33aa22';
const styles = csjs`
color: #333;
.panel {
border: 1px solid black;
background-color: ${green};
}
.title {
padding: 4px;
font-size: 15px;
}
`;
console.log(styles.componentClass);
Where all of the styles inside are nested under this parent, making this much more useful for
components since a component usually has a parent class.
Although, looking back, it wouldn't be as verbose or clear as the current approach. Guess I could use postcss for nesting.
Perhaps something like:
const csjs = require('csjs/unscoped');
// or
import csjs from 'csjs/unscoped';
Related issue: #12 (benchmarks)
Some ideas:
ignoreComments
regexI've been studying the csjs-extractify, but I don't know how I could approach it with the webpack loader model.
Thoughts? @rtsao
This project has been perfect so far, i can't believe it solves pretty much all the major issues with React and styles.
The only gripe left is that the minified endbuild has lots of needless holes in it taking space due to the string literals. And since postCSS/cssnano doesn't work with babel-plugin-csjs-postcss there's no obvious solution.
Is there any alternative to compress it?
I'm not sure if I'm doing something wrong or if this is just expected behavior, but given the following:
const labelBase = csjs`
.boldBase {
font-weight: bold;
}
`;
const styles = csjs`
.button {
background-color: yellow;
}
.label extends ${labelBase.boldBase} {
color: blue;
}
`;
csjs.getCss(styles);
returns:
.button_4oyuOD {
background-color: yellow;
}
.label_4oyuOD {
color: blue;
}
Notice the missing value that we otherwise get from csjs.getCss(labelBase);
.boldBase_3DZseH {
font-weight: bold;
}
I would expect csjs.getCss(styles)
would return all CSS including those from extended styles. Is there another way to do so, or am I just fundamentally not understanding how getCss is intended to work?
Note that styles.label
correctly returns the expected "label_4oyuOD boldBase_3DZseH"
The optional extension syntactic sugar could trivially be switched to something like below (à la CSS Modules):
csjs`
.foo {
color: green;
}
.bar {
composes: foo, ${otherClass};
padding: 4px;
}
`
Current syntax:
csjs`
.foo {
color: green;
}
.bar extends .foo, ${otherClass} {
padding: 4px;
}
`
Current syntax pros:
Current syntax cons:
Overall, I think the choice is mostly arbitrary and there isn't much reason for one over the other beyond aesthetic preference.
So It would be really great if I could just export all the CSS for the entire app.
Not sure if this is the right approach, but a getAllCss would be awesome.
Hi,
When I use csjs on
var style = csjs`
.a { float: right }
`
I get the result
var _templateObject = _taggedTemplateLiteral(["\n.a { float: right }\n"], ["\n.a { float: right }\n"]);
function _taggedTemplateLiteral(strings, raw) {
return Object.freeze(Object.defineProperties(strings, {
raw: {
value: Object.freeze(raw)
}
}));
}
var style = csjs(_templateObject);
I'm not sure if it's only me.
Do you have any ideas on when the noScope merge will make it into a release? Thanks for a great module!
How should I write to apply multiple classname?
I want to apply multi classname to single element.
module.exports = csjs`
.foo {
font-size: '20px';
}
.bar {
color: red;
}
import React, { Component, PropTypes } from 'react';
import csjs from 'csjs';
import styles from './styles';
import insertCss from 'insert-css';
insertCss(csjs.getCss(styles));
export default class Foo extends Component {
render() {
return (
<div className={styles.foo styles.bar}>
{ this.props.children }
</div>
);
}
}
tl;dr are there plans to support autoprefixer or do you suggest a seperate module that can be combined with csjs
to achieve this?
Maybe there is a smart way to just add the vendor prefixes necessary by the current browser. I bookmarked two related projects:
Wow, I just revisted https://github.com/MicheleBertoli/css-in-js to check if there are any new projects and stumbled across yours :-) Currently I'm using jss
because even though it seems a bit big and clunky it has support for all the featuers and comes with a css2jss
thing that i used to translate css written in an es6 template string into jss. It kind of works, but this project of yours looks very very promising and seems to be the only one that goes straight for es6 templates which i feel are the way to go, because javascript objects are too clunky to really write css with them. But in real world projects it's pretty important to have some kind of autoprefixer working, otherwise what i save in work using this very awesome css-in-js technique, i pay by manually prefixing all the things with the appropriate vendor prefixes...
I also tried csjs-extractify
but it creates a blank CSS file. Is there a way to get it to work?
I thought it would be cool if you could do this syntax:
https://github.com/substack/meowave/blob/894e01d75da152d72f96e222a0b4f0f848364184/main.js#L42-L48
but instead of having to do inline styles, csjs would give you a unique classname that you could set.
the idea is to be able to style a single class in a template string, similar to the simplicity of module.exports = function () {}
Hi, I think it would make sense for this project and for jss. I have also created issue about it some time ago cssinjs/jss#220
I think csjs should should focus on compilation of tagged string template to json. And give rendering away to jss.
For example:
const one = csjs`
.foo {}
`;
const two = csjs`
.bar extends ${one.foo} {}
`;
const three = csjs`
.baz extends ${two.bar} {}
`;
and
const one = csjs`
.foo {}
.bar extends .foo {}
.baz extends .bar {}
`;
don't work quite right.
However, the following works correctly (already tested in https://github.com/rtsao/csjs/blob/master/test/multiple-extensions.source.js):
const one = csjs`
.foo {}
.bar extends .foo {}
`;
const two = csjs`
.baz extends ${one.bar} {}
`;
I just saw #61 and I like that #15 might be supported.
Do I understand correctly, that #61 might add some kind of runtime css parsing?
I'm not sure if necessary, but I was thinking, maybe some kind of runtime css parsing could help to add some form of "observable" primitiv, so that a css property would be auto-updated, whenever the observable variable changes.
The idea would be, that - maybe similar to a minimal version of styletron
, every part of the stylesheet that uses an "observable" is put into a <style>
tag that is as minimal as possible and internally, csjs
subscribes generated functions to changes of all "observables" to update those <style>
tags.
example:
function o (value) { // or something else
var subscribers = []
return function variable (val) {
if (typeof val === 'function') subscribers.push(val)
else if (val === undefined) return value
else (value = val, subscribers.forEach(fn => fn(value)))
}
}
var color = 'red'
var color$ = o()
color$(function(x){ // observe the value
console.log('color$ changed to', x)
})
color$('green') //set the value
color$() //get the value - e.g. can be used when initializing css
var css = csjs`
.title {
color: ${color};
background-color: ${color$};
}
`
color$('blue') // update the value
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.