|
1 | 1 | # purescript-react-stylesheet
|
2 | 2 |
|
3 |
| -Utilities to use [Purescript Stylesheet](https://github.com/danieljharvey/purescript-stylesheet) with [Purescript React](https://github.com/purescript-contrib/purescript-react). |
| 3 | +Utilities to use [Purescript Stylesheet](https://github.com/danieljharvey/purescript-stylesheet) with [Purescript React](https://github.com/purescript-contrib/purescript-react). Demo app [here](https://github.com/danieljharvey/purescript-stylesheet-example). |
4 | 4 |
|
5 | 5 | Purescript Stylesheet is a Virtual Stylesheet that allows you to dynamically add styles to a CSS Stylesheet. This library provides components that provide and consume a Virtual Stylesheet via React Context.
|
6 | 6 |
|
7 |
| -Currently in the experimental stage - demonstration app in progress. |
| 7 | +### What? |
| 8 | + |
| 9 | +Purescript Stylesheet allows you to create styles for your app that change depending on state. You provide functions from `props` to `CSS` and Stylesheet takes care of plopping them into a real stylesheet in your browser and making things look nice. |
| 10 | + |
| 11 | +### Like Styled Components? |
| 12 | + |
| 13 | +Yeah, that kind of thing. The ideas in this library aren't really new, I just wanted something like this in Purescript. |
| 14 | + |
| 15 | +### How do I use it then? |
| 16 | + |
| 17 | +Good question. |
| 18 | + |
| 19 | +We'll start by creating a `StyleContext`. |
| 20 | + |
| 21 | +```haskell |
| 22 | +import React.Stylesheet |
| 23 | + |
| 24 | +styleContext :: StyleContext |
| 25 | +styleContext |
| 26 | + = createStyleContext (SProxy :: SProxy "hey-nice-styles-buddy") |
| 27 | +``` |
| 28 | + |
| 29 | +This contains three things - |
| 30 | + |
| 31 | +1. Provider - a React class that provides the Stylesheet superpowers via React Context. |
| 32 | +2. Consumer - a React class that can be used to consume the Stylesheet superpowers |
| 33 | +3. Elements - a big pile of pre-wrapped DOM elements that will probably be the most useful part. |
| 34 | + |
| 35 | +We need to put the `Provider` at the tree of our app. |
| 36 | + |
| 37 | +```haskell |
| 38 | +mainClass :: React.ReactClass { } |
| 39 | +mainClass = React.component "Main" component |
| 40 | + where |
| 41 | + component this = |
| 42 | + pure { state: { |
| 43 | + { todos: [] |
| 44 | + } |
| 45 | + , render: pure |
| 46 | + $ React.createLeafElement styleContext.provider |
| 47 | + { children: [ render ] } |
| 48 | + } |
| 49 | + where |
| 50 | + render state = ... |
| 51 | +``` |
| 52 | + |
| 53 | +In this example the `render` function then takes care of the rest of your app. |
| 54 | + |
| 55 | +### What now? |
| 56 | + |
| 57 | +Let's make an element with styles! |
| 58 | + |
| 59 | +We define styles with a `CSSRuleSet`. It takes a type that defines the props it can receive. Here is one that takes no props (which we represent with `unit`). |
| 60 | + |
| 61 | +```haskell |
| 62 | +containerStyle :: CSSRuleSet Unit |
| 63 | +containerStyle |
| 64 | + = str """ |
| 65 | + margin: 20px; |
| 66 | + padding: 20px; |
| 67 | + border-radius: 10px; |
| 68 | + display: flex; |
| 69 | + flex-direction: row; |
| 70 | + justify-content: center; |
| 71 | + """ |
| 72 | +``` |
| 73 | + |
| 74 | +We are using Purescript's triple quote thing to smash a big lump of stupid CSS into a `CSSRuleSet`. Now let's give them to an element... |
| 75 | + |
| 76 | +```haskell |
| 77 | +container :: Array Props -> Array ReactElement -> ReactElement |
| 78 | +container |
| 79 | + = styleContext.elements.div containerStyles unit |
| 80 | +``` |
| 81 | + |
| 82 | +We've taken the `div` element from our `StyleContext`, and added these styles to it. Now we can use this `container` element in our app: |
| 83 | + |
| 84 | +```haskell |
| 85 | +render = container [] [ text "I am some text in an attractive looking box" ] |
| 86 | +``` |
| 87 | + |
| 88 | +### Good stuff. |
| 89 | + |
| 90 | +Now, what about something smarter? Let's have something with props. |
| 91 | + |
| 92 | +```haskell |
| 93 | +data TrafficLights |
| 94 | + = Red |
| 95 | + | Yellow |
| 96 | + | Green |
| 97 | + |
| 98 | +trafficStyle :: CSSRuleSet TrafficLights |
| 99 | +trafficStyle |
| 100 | + = str """ |
| 101 | + border: none; |
| 102 | + border-radius: 20px; |
| 103 | + width: 40px; |
| 104 | + height: 40px; |
| 105 | + """ |
| 106 | + <> fun (\light -> case light of |
| 107 | + Red -> "background-color: red;" |
| 108 | + Yellow -> "background-color: yellow;" |
| 109 | + Green -> "background-color: green;") |
| 110 | + |
| 111 | +trafficLight :: TrafficLights -> ReactElement |
| 112 | +trafficLight colour |
| 113 | + = styleContext.elements.div trafficStyle colour [] {} |
| 114 | +``` |
| 115 | + |
| 116 | +We have have a colour-changing traffic light! |
| 117 | + |
| 118 | +### Working example: |
| 119 | + |
| 120 | +The full working example is [here](https://github.com/danieljharvey/purescript-stylesheet-example). |
| 121 | + |
| 122 | +### Why just Purescript React? Why not [insert thing]? |
| 123 | + |
| 124 | +If this doesn't turn out to be an utter disaster, I would like to port it for use in React Basic and Halogen. If you are good at those things and want to help, by all means get in touch. |
| 125 | + |
| 126 | +### Why plain text CSS and not something more type-safe? |
| 127 | + |
| 128 | +Three reasons: |
| 129 | + |
| 130 | +1. Lazyness |
| 131 | +2. Easy to paste existing CSS in for ease of adoption |
| 132 | +3. Lazyness |
8 | 133 |
|
9 | 134 | ### Docs?
|
10 | 135 |
|
11 |
| -Yes, on [Pursuit](https://pursuit.purescript.org/packages/purescript-react-stylesheet/0.0.2) |
| 136 | +Yes, on [Pursuit](https://pursuit.purescript.org/packages/purescript-react-stylesheet/0.0.2)111 |
0 commit comments