threepointone / glamor Goto Github PK
View Code? Open in Web Editor NEWinline css for react et al
License: MIT License
inline css for react et al
License: MIT License
not so certain of this one yet, but we'll see. related to #60
via #33, some good feedback on how these selectors depend on their specificity. we should be able to warn users if they get the order wrong.
:active must always be more specific then :hover and so they must be ordered appropriately in the style sheet
[no promises on this, just tracking possible solutions]
glamor used to have a keyed
function that would let you define rules that would be replaced when it was redefined on the same key. this made it possible to 'reclaim' rules that weren't being 'used', with the onus on the developer to manage these keys. It was meant to be a helper for people wanting to use css for animations (not just @keyframes
). however, it crippled glamor's internal design, and made it hard to optimize for the larger set of use cases.
That said, there is a small set of use cases where it useful (eg - aphrodite/#141), so maybe we can make a separate module that does just this?
https://github.com/threepointone/glamor/blob/master/docs/createElement.md
E.g. how do I use this for media
, hover
, etc.? It seems like a nice simplification for React but the docs aren't clear about how to use this special prop.
goals for the rewrite are -
It seems placeholder styles are not working in Chrome, seemingly because the selector ::placeholder
is not supported (needs to be ::-webkit-input-placeholder
) and as far as I could tell from a quick look through the code, the selectors are not processed by the prefixer, only rules are.
Question is, since the cases where the selector needs to be prefixed somehow are quite rare and tricky to handle in a generic way (for example, to get placeholder styling to work cross-browser you need to duplicate the rule blocks iirc), is it better to handle these things case by case or find some more generic solution (i.e pass all selectors through a prefixer)?
It will make it easier to write conditional styles this way:
const needPadding = true
<div {...style({ color: 'black', padding: needPadding && 10 })}/>
@threepointone I can send PR if you find this change useful.
very specific bug - if there's a multinested merge()
inside a media()
, and that inner merge
has a custom label, then editing it with hot loading enabled does not change the label in the dom. I've narrowed it down to this testcase -
export class App extends React.Component {
render() {
return <div {...media('(min-width: 500px)',
merge( 'container',
merge('inner',
{ color: 'red' },
hover({ color: 'blue' }))))} />
}
}
in the above, editing 'container' works fine, but editing 'inner' doesn't reflect in the dom after the hot update.
this points to be some hashing error in either merge()
or media()
to be clear, editing the styles works fine, just the label doesn't update.
needs a refactor and cleanup ugh
What are your thoughts on adding an .editorconfig
file? This will allow consistent editor formatting as I find a lot of indent/newline conversions when using atom.
renderStaticOptimized
vs renderStatic
statsI'm unwilling to async-ify the application of styles like aphrodite, but I'm willing to figure out alternatives -
Iโve found that when the React tree is rendered there is a flash of unstyled content with just the React HTML and without the glamor styles. Is there a suggestion on how to fix this?
Great library by the way! I think this approach makes use of the best of all other CSS-in-JS approaches.
hot loading 'works' right now, but it does reinsert unneeded rules into the sheet. must fix.
Currently we can do
insertRule('html, body { padding: 0 }')
It would be great to support same definition as in createElement helper. Something like:
global('html, body', { padding: 0 })
global('a', [ { color: 'red'}, hover({ color: 'blue' }) ])
I installed using --save
and you have react-hot-loader
specified as a dev-dep. Unless I explicitly install it I get:
ERROR in ./~/glamor/lib/index.js
Module build failed: ReferenceError: Unknown plugin "react-hot-loader/babel" specified in "/Users/tshugart/Sites/skatejs/skatejs.github.io/node_modules/glamor/package.json.env.development" at 0, att
empted to resolve relative to "/Users/tshugart/Sites/skatejs/skatejs.github.io/node_modules/glamor"
I could be wrong but it seems that since I'm in "development" it seems your babel env config gets loaded, but since dev deps aren't installed, it can't find the plugin specified in there.
Not sure the best way to fix this without compromising dev ergonomics on your end. You could specify react-hot-loader as a standard dependency so that it's picked up in dev mode for consumers. Thoughts?
on server side, it should do the current behavior, which is adding all prefixes
on browser, only needed prefixes
Last plugin run first. Is it intentional?
the goal is to make these work -
glamor ./src/app.js -cc ./src/app.css #css only
glamor -./src/app.js -d lib #html/css/ids
cat src/*.js | glamor | jq #pipe in and out
parent issue for container queries.
feel free to add/discuss stuff here.
This could easily be something in my setup, but I created a Codepen pen to kick the tires of glamor by porting my Aphrodite example/pen and I noticed the following:
Hovering over "This turns red on hover" works until I resize the Codepen preview divider and/or sometimes the entire browser window (or DevTools pane).
It's odd as sometimes I can reproduce it consistently on 1 resize (especially the Codepen preview divider) and sometimes it takes a while (10+ resizes). Takes a refresh to restore hovering after I cause the issue.
This also seems to occur in the Debug mode of the pen, but it took a lot of resizing to reproduce.
bring back coverage reports for tests
we should probably move away from browserify, because fatigue and whatnot.
once the hairball is refactored, must consider adding flow and/or ts typings to the lib. because apparently that's a thing now.
keeping this issue open for the same. please contribute!
I've tested some edge cases and here is what we have currently:
style({})
// returns
{ 'data-css-120drhm': '*' }
// inserts to stylesheet
'[data-css-120drhm] { null }'
select(' a', {})
// returns
{ 'data-css-p8xeo9': '*' }
// inserts
'[data-css-p8xeo9] a { null }'
merge()
// returns
{ 'data-css-120drhm': '[]' }
// inserts nothing to stylesheet
merge({})
// returns
{ 'data-css-11ra3p3': '[{:}]' }
// inserts nothing to stylesheet
media('()', {})
// returns
{ 'data-css-11qittp': '*mq({:})' }
// inserts to stylesheet
`
@media (){
[data-css-11qittp] { null }
}`
media('()')
// returns
{ 'data-css-1853dek': '*mq()' }
// inserts nothing to stylesheet
keyframes('bounce', {})
// returns
'bounce_nc5hzc'
// inserts to stylesheet
`
@-webkit-keyframes bounce_nc5hzc { }
@-moz-keyframes bounce_nc5hzc { }
@-o-keyframes bounce_nc5hzc { }
@keyframes bounce_nc5hzc { }
`
fontFace({})
// returns
undefined
// inserts nothing to stylesheet
fontFace({fontStyle: 'normal'})
// returns
undefined
// inserts to stylesheet
'@font-face { font-style:normal;}'
cssFor()
// returns
''
// inserts nothing to stylesheet
attribsFor()
// returns
''
// inserts nothing to stylesheet
I suggest:
to be more specific - I'd like to scan the top 1000 (10000?) sites, extract the css from them, and count the number of rules in them. this will give as indication as whether we should use more stylesheets behind-the-scenes, or whether we're fine with just one.
Hi the idea of this lib is really great! I want to start using it instead of Radium.
I'm having trouble running the code, I'm getting 'Cannot read property 'cssRules' of undefined' on the following line: insertSheetRule(cssrule(type, style, id), sheet.cssRules.length);
I'm doing a simple test:
import {style} from '@threepointone/react-css'
export default class Test extends React.Component {
render() {
return <div
{...style({ color: 'red', cursor: 'pointer' })}
>
TEST
</div>
}
}
This error occurs in only on our (sourcegraph.com) production set up, when glamor is in speedy
mode. If its relevant, we also use TypeScript.
This can be reproduced in latest Safari and Chrome on iOS 10.0.1 on iPad and iPhone.
It does not appear to be an issue on some other mobile devices, e.g., Nexus 5x / Chrome.
This is the JS error I am getting on my iPad in Safari:
For now, we've disabled speedy
mode, but it is, of course slower.
dev only linting would be nice
copy something like http://flexboxgrid.com/ ?
helpers / plugins for http://cssnext.io/
since we generate/add css rules to the dom as soon they're computed, style objects that change over many different values will leave behind unused rules in the dom. while there exists a function remove
to remove rules based on the generated hash/refs, I can't think of a simple way to expose it. Hopefully this is an edge case and doesn't affect many people. If so, the recommendation is to use use regular style prop for styles that change over many different values.
of note: this problem is not unique to this lib.
I have a div that I'm adding some styles too:
<div
{...style({
paddingTop: rhythm(1),
textAlign: 'center',
maxWidth: 960,
margin: '0 auto',
})}
{...media(presets.tablet, {
paddingTop: rhythm(3),
})}
>
The media paddingTop
should always win but when it's at rhythm(3)
(Typography.js helper function) it doesn't but if I change it to rhythm(3.5)
it does.
Screenshots from chrome devtools:
It looks like it's just the hash length for the media query attribute that's changing?
parent issue/scratchpad for all things perf
things that can affect performance
things to lookout for
things that can help
style()
should be able to accept rules like -
style({
color: 'red',
':hover': {
color: 'blue'
}
})
why not, yeah ? :)
The basic idea here is to process the javascript and replace function calls with values, deduping common declarations and avoiding cpu cycles. If we could detect all functional calls to style
/<pseudo>
/media
, and the arguments passed to them were constant objects with primitive values (eg -{color:'red'}
), we could then hoist the function call to the very top of the program, deduping on 'equal' values, and replacing the callsite with the resulting {[data-*]:<id>}
object.
Further ideas in jsxstyle.
frameworks that use jsx/virtual dom should be able to use this out of the box. however, not sure how to apply these data attributes in angular/ember templates. keeping this issue open to investigate; please help/contribute!
Related to #15, I have to install babel-preset-stage-0
to get it compiling now.
the current implementation is rather weak, and doesn't participate well in the hashing goodness; further I haven't really used it extensively yet. open to ideas.
because we use the data attribute name purely as an indexing scheme and don't 'accept' names in our function calls, we don't generate 'pretty' classnames, which might make debugging hard. keeping this issue open for alternate solutions.
ref #6, #aphrodite/130
Since glamor mutates a stylesheet in the head - I don't see any options how to suppress that and instead generate a string or use an alternate style tag - I'm wondering how this could be used to work with a style tag in a shadow root since global styles can't leak into a shadow root?
A way to do this might be to buffer the calls and return a string:
import { buffer, style } from 'glamor';
const div = document.createElement('div');
const css = buffer(() => {
return {
declaration1: style({ backgroundColor: 'orange' }),
declaration2: style({ backgroundColor: 'black' }),
};
});
div.attachShadow({ open: true });
div.shadowRoot.innerHTML = `
<style>${css.toString()}</style>
<div ${css.declaration1}>
<span ${css.declaration2}>in shadow root</span>
</div>
`;
I've thought about being able to supply a custom style element, however, that would couple the implementation to the actual DOM and in my case, I'm using web components with a virtual DOM.
ref #[aphrodite/129]
because of this chrome issue, the generated css cannot be edited in chrome devtools, and it doesn't look like that'll get fixed any time soon.
not all hope is lost though, we can simply reconstruct the css like aphrodite does it. must also investigate batching with react's loop, preventing aphrodite's async problem.
Not a big deal with gzip but still should be fixed at some point.
Also it'd be nice to remove to remove extra whitespace to keep that slick compiled & minified look :-)
Is there a reason for pre-building 'CSSPropertyOperations' instead of requiring it from React or copy/pasting the original files?
Webpack complains about its format:
WARNING in ./~/glamor/lib/CSSPropertyOperations.js
Critical dependencies:
26:78-86 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
@ ./~/glamor/lib/CSSPropertyOperations.js 26:78-86
Thanks!
merge
/ media
to get cleanercache
/inserted
logicI just tried to use it for animation and ended up with a pile of silly css rules ๐น
<div {...style({ width: x })}/>
I guess we need to show a dev warning for this case. I can address it later when I got better feel of the library.
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.