These are chat archives for japgolly/scalacss

23rd
Mar 2015
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 00:53
 object Style extends StyleSheet.Inline {
    import dsl._
    val pager = style(display.flex,
    justifyContent.spaceBetween)
  }

div(Style.pager)
[error] found : japgolly.scalacss.StyleA
[error] required: japgolly.scalajs.react.vdom.TagMod
am i missing something …..
David Barri
@japgolly
Mar 23 2015 00:55
Morning @chandu0101
Yes, it needs a scalajs-react bridge/adapter
I only finished writing it about 5 min ago :D
Give me about 10 min
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 00:56
morning mate , cool push it then , just created scalacss-playground. can’t wait! :)
David Barri
@japgolly
Mar 23 2015 01:08
Awesome
Ok, I've just updated master but there's no doc yet (doing that now)
See ./ext-react/src/test/scala/japgolly/scalacss/ReactTest.scala for an example
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 01:13
perfect thanks.
David Barri
@japgolly
Mar 23 2015 01:14
no worries!
Hey actually there might be a flaw in my logic...
How do we create the <style> tag? I wrote a renderer to a ReactElement but we wouldn't want to use a component
David Barri
@japgolly
Mar 23 2015 01:21
Maybe we need this:
        // Create the <style> tag
        var style = document.createElement("style");
        // WebKit hack :(
        style.appendChild(document.createTextNode(""));
        // Add the <style> element to the page
        document.head.appendChild(style);
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 01:25
to be frank i can only understand bits of this info right now , scalacss appends style tag ? , instead of generating css file and linking it back!
David Barri
@japgolly
Mar 23 2015 01:26
Instead of generating a CSS file it generates a <style> tag.
If it generates a CSS file, the file could go out-of-sync with the code which could be a subtle problem to detect.
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 01:27
oh ok
David Barri
@japgolly
Mar 23 2015 01:29
(Also it omits unnecessary browser prefixes at runtime because it knows which browser to target. Good because Chrome has started issuing console warnings about that.)
This is my missight:
Render styles to ReactElement. We don't want <style> as a ReactElement. :(
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 01:54
oh yeah , document.blah approach will be good then!
David Barri
@japgolly
Mar 23 2015 01:58
@chandu0101 ok i just updated master again
Tests pass but I haven't tried this for real yet - try calling .addToDocument() on your stylesheet
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 02:02
yay , previous button is on left next button on right :)
David Barri
@japgolly
Mar 23 2015 02:04
Oh cool it's working then?!
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 02:05
now i’ll go for breakfast with joy! , @japgolly thanks mate , will play with this cute sweet naughty toy after break fast :)
David Barri
@japgolly
Mar 23 2015 02:06
Awesome news! Enjoy mate
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 02:59
@japgolly mate did you conducted any size comparisons with/without scalacss ?
David Barri
@japgolly
Mar 23 2015 03:00
No not at all
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 03:04
in my emptry react proj with/without 546/230 K , is it normal !
David Barri
@japgolly
Mar 23 2015 03:04
I dunno what normal is yet :P
what about with fullOptJS?
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 03:05
lol , i thought you have some thing in req !
those figs are with fullOpt only , with fastOpt its around 2+ M
David Barri
@japgolly
Mar 23 2015 03:06
full opt adds 240k?!
Ah, also you should try with inlining and optimisation flags
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 03:08
love to see those documented :)
David Barri
@japgolly
Mar 23 2015 03:09
lol calm down son, remember you're looking at a 0.1.0-SNAPSHOT here :D
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 03:10
haha :P , atleast we shouldn’t scare the new comers !
David Barri
@japgolly
Mar 23 2015 03:12
heh yeah when the time is right we'll focus on that stuff
I'm just hooking it up to my work project now!
exciting
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 03:21

exciting

indeed
love to see some real world snippets of scala-css in future before we brutually murder your css baby :P

David Barri
@japgolly
Mar 23 2015 03:27
OMG IT WORKS PERFECTLY AND BEAUTIFULLY!
I've now got bootstrap buttons without any bootstrap shit outside of the styles file
AND just by adding this line
style(japgolly.scalacss.ext.CssReset.normaliseCss)
I added normalise.css to the page. It worked as expected too.
(Yeah that's a feature I haven't mentioned yet)
Wow, this is aweomsE!
Time to eat lunch and publish this for real
David Barri
@japgolly
Mar 23 2015 04:48
This is published now. 0.1.0 has been released.
SRGOM
@SRGOM
Mar 23 2015 05:38
This is great! Congratulations, and thank you!
David Barri
@japgolly
Mar 23 2015 06:24
You're welcome and thank you :D
Malchevskiy Misha
@malchmih
Mar 23 2015 07:09
Thanks =)
Otto Chrons
@ochrons
Mar 23 2015 07:09
gonna update SPA tutorial to use this soonish :)
David Barri
@japgolly
Mar 23 2015 07:10
:+1: :smile: @malchmih
@ochrons Niiice. The examples in the doco are more detailed now
scalajs-react one
You know what? I think it's gonna take a while for us to all work out best practices for styles in this new world.
We've so much freedom now, we have so many ways to structure our styles...
I'm doing some for my real app now and I'm not sure what's best...
The props for a generic component used to look like this:
  case class Props[A](value    : Vector[A],
                      all      : GenTraversable[A],
                      label    : A => String,
                      mandatory: A => Boolean,
                      change   : Vector[A] => IO[Unit])
Now it looks like this:
  case class Styles(row     : TagMod = EmptyTag,
                    dragHnd : TagMod = EmptyTag,
                    checkbox: TagMod = EmptyTag,
                    label   : TagMod = EmptyTag)

  val noStyle = new Styles()

  case class Props[A](value    : Vector[A],
                      all      : GenTraversable[A],
                      label    : A => String,
                      mandatory: A => Boolean,
                      change   : Vector[A] => IO[Unit],
                      styles   : Boolean => Styles = (_: Boolean) => noStyle)
Doesn't seem like the best way to do it...
This will take time. I'm looking forward to see how you guys structure stuff
(It's much more straight-forward for non-shared components)
David Barri
@japgolly
Mar 23 2015 07:17
There's a useful abstraction here we're missing... I can feel it.
@japgolly my lord review it and bless me with bugs :P
David Barri
@japgolly
Mar 23 2015 07:36
hahaha!
As I see things...
border :=! "1px solid transparent"
// ↑ can be safer ↓
border(1 px, solid,  transparent)
If transparent isn't in scope like that, it's an issue to fix
Similarly:
display :=! (if (hide) "none" else "block")
// better to be
(if (hide) display.none else display.block)
Let's try using safe children instead of unsafe, i'll give try
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 07:49
thanks mate
David Barri
@japgolly
Mar 23 2015 07:49
It seems that in order you use safe children you need that shapeless import.
If I can, I'll work around that in the next version so you don't need any special import.
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 07:49
cool ok
when i am reusing this component in another project
 CssPager.Style.addToDocument() // yeah i am in heaven
David Barri
@japgolly
Mar 23 2015 07:50
hehe be careful with that though
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 07:50
:o
why ?
David Barri
@japgolly
Mar 23 2015 07:51
If two stylesheets use different Registers and the same class-name-gen from Defaults, you will end up with different stylesheets both generating classnames like .scalacss-0001 (or _1 in production)
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 07:52
whats the best way then ?
David Barri
@japgolly
Mar 23 2015 07:52
It's best to only have one stylesheet object per SPA and include the children into the parent one.
OR you could make CssPager generate names like .csspager-0001 if you want to. It's all configurable :)
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 07:54
ok , thank you :)
David Barri
@japgolly
Mar 23 2015 07:55
Anytime mate!
Matt Hughes
@matthughes
Mar 23 2015 13:34
Unable to get some of the examples to compile: https://gist.github.com/matthughes/b74a71e645c3f7293757
do I have to turn on any special operators?
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 13:43
you’re mixing things standalone with inline!
Matt Hughes
@matthughes
Mar 23 2015 13:45
riight. So the '-' dsl is only mixed into standalone because only standalone has free-standing selectors. In inline mode, all your selectors are meant to be referenced in your app so they would never just have string keys; they would be vals, right?
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 13:49
thats my understanding too :)
Matt Hughes
@matthughes
Mar 23 2015 14:17
I do wonder why StandloneStyles doesn't have a addToDocument method though. Now that I understand the differences better, I agree everything that can go in Inline should go in inline, but what about elements outside of your React entrypoint?
For example, I need to apply some styles to body tag; my app actually starts at body > div.
I can just copy this
document.head.appendChild(ss.render[HTMLStyleElement])
Is the reasoning just to discourage people from using Standalone where not needed?
Justin du Coeur, AKA Mark Waks
@jducoeur
Mar 23 2015 14:31
Hmm -- that's a good point. It's probably going to be quite common to want to add a bit of styling from the code into the wrapper HTML around the SPA. Is there a best-practices way to do that yet? The quoted code is a little clunky; might be at least worth a wrapper like the suggested addToDocument, to make it clearer and more official.
Matt Hughes
@matthughes
Mar 23 2015 14:33
@japgolly In your example about where you add the Style case class to your Props, is there a reason you type those values as TagMod instead of the more specific StyleA?
Matt Hughes
@matthughes
Mar 23 2015 15:12
Can we get a more complete example on the Nested Styles doc? I'll volunteer to write something up but first I need to understand it :)
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 15:14
you mean type safe way ?
Matt Hughes
@matthughes
Mar 23 2015 15:14
Specifically struggling to understand what the code looks like at the call site. Compilable examples are always best. With a normal inline style, you just reference it inside your element: div(MyStyles.fancyDiv, "fancy")
Matt Hughes
@matthughes
Mar 23 2015 15:16
ah, so here you have to wrap the whole component
Is using scalajs-react in the examples verbotten?
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 15:18
sorry i didnt understand the question ..
Matt Hughes
@matthughes
Mar 23 2015 15:20
Your example helped a lot. I was wondering if we could actually show scalajs-react code in the composite example in the docs. So rather than just showing
Demo.example('outer )(o => _('label )(l => _('checkbox)(c =>
You could actually show how those styles are used.
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 15:26
+1 , thats what i suggested in the beginning ! . With real world examples people can easily understand , but we can't expect this from @japgolly , may be community(we) must send PR's! . I love to see scalajs-react in all examples, as @ochrons said its great opportunity to promote scalajs-react :P
Matt Hughes
@matthughes
Mar 23 2015 15:27
Was it objected to or just not done for lack of resources?
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 15:29
lack of resources ! , who don't want more docs :) . scalajs-react adaptor/bridge implemented in last stage of release.
Matt Hughes
@matthughes
Mar 23 2015 15:34
k. i mean showing actual component use will be pretty identical whether you are using scalareact or scalatags
Chandra Sekhar Kode
@chandu0101
Mar 23 2015 15:38
indeed
Otto Chrons
@ochrons
Mar 23 2015 17:14
well, you know the primary motivation for my SPA tutorial was the lack of concrete examples and good documentation on many Scala.js issues people face when doing a real app with it
it's a difficult balance between general purpose documentation and something that's very specific to a single case
but at least for myself, concrete code examples are usually faster/easier to understand than narrative doc text
Matt Hughes
@matthughes
Mar 23 2015 17:59
Well and in this case, the two current clients scalatags/scalajs-react will look superficially the same when using scalacss, so I don't see the harm.
Matt Hughes
@matthughes
Mar 23 2015 19:03
Is there any way to thread styles through components that don't expose their style internals like router? My application has a header and then whatever router renders. I want to apply flex: 1 0 auto to Router(). Any idaes how to accomplish?
React.render(
  div(AppStyles.flexColumn,
    shell.AppHeader(),
    Router()
  ), document.body)
Matt Hughes
@matthughes
Mar 23 2015 19:22
japgolly.scalacss.Attr does not take parameters [error] flex(1, 0, ""),
final val flex = Attr.alias("flex", Transform keys CanIUse.flexbox)(_( flexGrow, flexShrink, flexBasis))
flexGrow/Shrink are both numerical
and I believe I can use string for the last
(really we should have an overload methods with shrink and basis defaulted)
David Barri
@japgolly
Mar 23 2015 20:43
Morning! yawn
Matt Hughes
@matthughes
Mar 23 2015 20:44
haha
i looked at everytimezone.com earlier to see when you'd be around these parts
David Barri
@japgolly
Mar 23 2015 20:44
haha. Well I'm partially here, partially asleep :D
Justin du Coeur, AKA Mark Waks
@jducoeur
Mar 23 2015 20:45
This conversation is kind of magnificently international -- I'm about to knock off work for the day...
David Barri
@japgolly
Mar 23 2015 20:47
You'll be back! :P
Ok so the differences between Standalone and Inline. You can still add generic styles to Inline. There's unsafeChild() to model a style's children using a css selector, and unsafeRoot() which is like a plain old CSS.
If you want to style body > div you can just use unsafeRoot("body > div") in your inline stylesheet.
Some more detail between inline vs standalone in at the bottom of this.
Contibutions for more detail/clarity would be appreciated :D
About a full example for nested children - yeah I added one for reusable styles but not nested. @chandu0101 That gist we played with yesterday? What do you think about adding that to the nested styles page as an example?
David Barri
@japgolly
Mar 23 2015 20:52

Was it objected to or just not done for lack of resources?

hehe definitely not objected too, I just did other pages and was too tired to do all. Plus I think everything's clear but then I wrote it all so it's hard for me to judge.

@matthughes Why did I use xxx: TagMod = EmptyTag? The main reason is because it's more flexible. I can add a style but I can also add a data-id=7 attribute if I need to. They say it's a best practice to accept function inputs as generic as possible and be as specific as possible with your function outputs. Generally, I agree.
(Plus there's no notion of an empty StyleA)
David Barri
@japgolly
Mar 23 2015 20:59

any way to thread styles through components that don't expose their style internals

I don't think there is. I hit this yesterday too. I don't think you can apply a style to a React component from the outside, and then I thought "that's dumb, you should be able to", and then I thought about it more and realised that would lead to trouble after a while cos you'd make assumptions about what's inside and how it works, so now I'm not sure about the whole situation.

Exposing inputs for styles seems to be the way to go but in the context of the router like you said, I don't know....
Maybe instead of styling the route-page directly, the router should wrap it in a div and style that div.
@matthughes Ah you've hit an untyped attribute already. Have a quick look at this: http://japgolly.github.io/scalacss/book/features/typed-values.html

Excerpt from page:

If your favourite attribute doesn't have typed values, please patch it and submit a pull request.

Typing all values is a lot of work for one person and automation only gets one so far. Most are done but not all. If different users contribute a small amount of time to get a few attributes done then they'll all be typed in no time.

:D
Matt Hughes
@matthughes
Mar 23 2015 21:04
ah that works, but what about the actual 'flex' typed attribute. From what I can gather, it takes three values, but can't get it to compile.
Will be happy too once I'm a bit more familiar; I'm getting there but I just started using it today
David Barri
@japgolly
Mar 23 2015 21:04
I know. All the answers (including workaround for now) are on that page :)
Matt Hughes
@matthughes
Mar 23 2015 21:09
hmm how about if you give me sample code for using the flex shorthand I will write tut examples for all attributes
David Barri
@japgolly
Mar 23 2015 21:10
Sure happy to, but does that mean that page I linked you isn't effective? If it needs something different let me know.
Matt Hughes
@matthughes
Mar 23 2015 21:11
the untyped attr makes sense. But is 'flex' an untyped attribute? It looks like it takes three values like padding or margin?
final val flex = Attr.alias("flex", Transform keys CanIUse.flexbox)(_( flexGrow, flexShrink, flexBasis))
shouldn't it work just like this?
padding(0 px, 0 px, 0 px, 0 px), flex(1, 1, 0 px)
David Barri
@japgolly
Mar 23 2015 21:11
To use an attribute that doesn't have a typed value syntax yet, use the := operator.
flex := "1 0 auto"
Ah so the language "untyped attr" is unclear
Matt Hughes
@matthughes
Mar 23 2015 21:12
right. Looking at the definition, it looks like you do break it down into three values. Like, what is happening there? If I pass you a string with only two values is that going to blow up at runtime?
David Barri
@japgolly
Mar 23 2015 21:12
"Untyped attribute" just means I haven't added methods to the attribute so that Scala usage guarantees legal values.
Matt Hughes
@matthughes
Mar 23 2015 21:13
But your example makes it look like flex just takes a single string. What is (_( flexGrow, flexShrink, flexBasis)) doing?
David Barri
@japgolly
Mar 23 2015 21:13
No, no, if you use := it means you're giving it a string value that you would use in any other non-Scala CSS
Oh in the definition in Attrs? Yeah that's not documented (sorry! so much to do) - that's a list of ("real") attributes that it affects.
Matt Hughes
@matthughes
Mar 23 2015 21:15
oooh for the compose functionality
or conflict detection rather
David Barri
@japgolly
Mar 23 2015 21:15
So setting flex = blah means that it will affect grow, shrink, basis which
yeah exactly
Matt Hughes
@matthughes
Mar 23 2015 21:15
k
David Barri
@japgolly
Mar 23 2015 21:15
which is how it determines if there are any potential conflicts
Matt Hughes
@matthughes
Mar 23 2015 21:16
right. ok that makes more sense. now that I read padding, margin more carefully I see they extend TypedAttrT4Edges.
David Barri
@japgolly
Mar 23 2015 21:17
Yeah I just use plain old subclassing to share common patterns between typed attributes
Matt Hughes
@matthughes
Mar 23 2015 21:19
Any thoughts on using macros to preserve the css class names?
rather than generating scalacss-001?
David Barri
@japgolly
Mar 23 2015 21:20
Oh how do you mean?
(Keep in mind classnames are generated only when created in an Inline stylesheet and with configurable rules)
#12 :)
Matt Hughes
@matthughes
Mar 23 2015 21:21
So if you have an inline stylesheet with val jumbotron = style(...), when you use that style in a tag, it will actually use the classname 'jumbotron'
Would make debugging styles via Chrome/Firefox easier
David Barri
@japgolly
Mar 23 2015 21:22
You can do val jumbotron = style("jumbotron")(...) now
Matt Hughes
@matthughes
Mar 23 2015 21:23
ah that works. macro could make that automatic but good enough for me.
David Barri
@japgolly
Mar 23 2015 21:23
But even if a macro made it so you didn't need to specify names, I'd worry about potential conflict.
Matt Hughes
@matthughes
Mar 23 2015 21:23
but that goes away with full opt right? or will specified names stay the same?
David Barri
@japgolly
Mar 23 2015 21:23
You'd have to be careful of using shared modules or inner objects (for organisation)
Matt Hughes
@matthughes
Mar 23 2015 21:24
s/goes away/mangled
David Barri
@japgolly
Mar 23 2015 21:24
Oh you mean dev-only and in prod it overrides them with auto-generated names?
Matt Hughes
@matthughes
Mar 23 2015 21:25
Right. I thought I saw in the docs that the classnames get mangled when running fullOpt.
but I guess you can override that behavior right? Defaults._ is just setting it for you.
David Barri
@japgolly
Mar 23 2015 21:26
The behaviour is the same under the covers, it's just the function that generates classnames that changes.
The implicit instance of this changes:
  trait NameGen {
    def next: (ClassName, NameGen)
  }
David Barri
@japgolly
Mar 23 2015 22:26
This message was deleted
You know a macro that named a style's class using its variable name but gets mangled in prod can be easily supported by just adding another method to StyleS (Static style):
preferredClassName: Option[ClassName]
Then name generators can decide whether or not to honour it or override it.
Potential conflicts could also be avoided by stylesheets' checking that the name is available when styles are registered.
Quite easy to support. Like 10 LoC.
@matthughes You'd have to do the macro stuff though, I've never written any macros (avoiding until scala.meta is ready) but I could integrate it