Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 33 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# bs-css

Statically typed DSL for writing css in reason and rescript.
Statically typed DSL for writing css in ReScript.

The bs-css library contains type css core definitions, it has different implementations:

- bs-css-emotion is a typed interface to [Emotion](https://github.com/emotion-js/emotion)
- bs-css-fela is a typed interface to [Fela](https://github.com/robinweser/fela) (react)
- bs-css-dom is a typed interface to `ReactDOMRe.Style.t` (reason-react)
- bs-css-dom is a typed interface to `ReactDOM.Style.t` (rescript-react)

If you know another implementation that can be added, send a link in an issue or create a PR.

Expand All @@ -18,7 +18,7 @@ or
yarn add bs-css bs-css-emotion
```

In your `bsconfig.json`, include `"bs-css"` and `"bs-css-emotion"` in the `bs-dependencies`.
In your `rescript.json`, include `"bs-css"` and `"bs-css-emotion"` in the `dependencies`.

You can replace `bs-css-emotion` with `bs-css-dom` in the above instructions if you prefer
to use React styles, or `bs-css-fela` for a different runtime.
Expand Down Expand Up @@ -59,7 +59,7 @@ module Styles = {
])

let actionButton = disabled =>
style(. [
style([
background(disabled ? darkgray : white),
color(black),
border(px(1), solid, black),
Expand All @@ -82,8 +82,8 @@ You can define global css rules with `global`
```rescript
open CssJs

global(. "body", [margin(px(0))])
global(. "h1, h2, h3", [color(rgb(33, 33, 33))])
global("body", [margin(px(0))])
global("h1, h2, h3", [color(rgb(33, 33, 33))])
```

**Keyframes**
Expand All @@ -99,7 +99,7 @@ let bounce = keyframes(. [
(100, [transform(scale(1.0, 1.0)), opacity(1.0)]),
])

let styles = style(. [
let styles = style([
animationName(bounce),
animationDuration(2000),
width(px(50)),
Expand All @@ -117,15 +117,15 @@ For some CSS parameters (like setting padding on an input field), one needs to u

```css
input[type="text"] {
padding:20px;
padding: 20px;
}
```

The `selector` function can be used:

```rescript
open CssJs
let styles = style(. [selector("input[type='text']", [padding(px(20))])])
let styles = style([selector("input[type='text']", [padding(px(20))])])
```

### Merging styles
Expand Down Expand Up @@ -159,7 +159,7 @@ let media2 = [
color(red)
])
]
let mergedStyles = style(. Belt.Array.concatMany([base, overrides, media1, media2]))
let mergedStyles = style(Belt.Array.concatMany([base, overrides, media1, media2]))
```

generates the following:
Expand All @@ -184,14 +184,14 @@ As you can see both properties from `base` are overwritten (as opposed to overri

`merge` safely merges styles by name. Uses [Emotion’s `cx` method](https://emotion.sh/docs/cx).

```reason
```rescript
open CssJs

let mergedStyles = merge(. [
style(. [padding(px(0)), fontSize(px(1))]),
style(. [padding(px(20)), fontSize(px(24)), color(blue)]),
style(. [media("(max-width: 768px)", [padding(px(10))])]),
style(. [media("(max-width: 768px)", [fontSize(px(16)), color(red)])]),
let mergedStyles = merge([
style([padding(px(0)), fontSize(px(1))]),
style([padding(px(20)), fontSize(px(24)), color(blue)]),
style([media("(max-width: 768px)", [padding(px(10))])]),
style([media("(max-width: 768px)", [fontSize(px(16)), color(red)])]),
])
```

Expand Down Expand Up @@ -230,7 +230,11 @@ let renderer = createRenderer()
switch ReactDOM.querySelector("#app") {
| None => ()
| Some(dom) =>
ReactDOM.render(<CssReact.RendererProvider renderer> ... </CssReact.RendererProvider>, dom)
dom
->ReactDOM.Client.createRoot
->ReactDOM.Client.Root.render(
<CssReact.RendererProvider renderer> ... </CssReact.RendererProvider>
)
}
```

Expand All @@ -245,7 +249,7 @@ module Styles = {
*/
open CssJs

let card = style(. [
let card = style([
display(flexBox),
flexDirection(column),
alignItems(stretch),
Expand All @@ -257,15 +261,15 @@ module Styles = {
padding(Theme.basePadding),
])

let title = style(. [
let title = style([
fontSize(rem(1.5)),
lineHeight(#abs(1.25)),
color(Theme.textColor),
marginBottom(Theme.basePadding),
])

let actionButton = disabled =>
style(. [
style([
background(disabled ? darkgray : white),
color(black),
border(px(1), solid, black),
Expand All @@ -277,9 +281,9 @@ module Styles = {
let make = () => {
let {css, _} = CssReact.useFela()

<div className={css(. Styles.card)}>
<h1 className={css(. Styles.title)}> {React.string("Hello")} </h1>
<button className={css(. Styles.actionButton(false))} />
<div className={css(Styles.card)}>
<h1 className={css(Styles.title)}> {React.string("Hello")} </h1>
<button className={css(Styles.actionButton(false))} />
</div>
}
```
Expand All @@ -288,12 +292,12 @@ let make = () => {

You can define global css rules with `global`

```rescript
```rescript
open CssJs
let renderer = createRenderer()

renderGlobal(. renderer, "body", [margin(px(0))])
renderGlobal(. renderer, "h1, h2, h3", [color(rgb(33, 33, 33))])
renderGlobal(renderer, "body", [margin(px(0))])
renderGlobal(renderer, "h1, h2, h3", [color(rgb(33, 33, 33))])
```

## Usage for bs-css-dom
Expand All @@ -305,7 +309,7 @@ module Styles = {
// Open the Css module, so we can access the style properties below without prefixing them with Css
open CssJs

let card = style(. [
let card = style([
display(flexBox),
flexDirection(column),
alignItems(stretch),
Expand All @@ -317,10 +321,10 @@ module Styles = {
padding(Theme.basePadding),
])

let title = style(. [fontSize(rem(1.5)), color(Theme.textColor), marginBottom(Theme.basePadding)])
let title = style([fontSize(rem(1.5)), color(Theme.textColor), marginBottom(Theme.basePadding)])

let actionButton = disabled =>
style(. [
style([
background(disabled ? darkgray : white),
color(black),
border(px(1), solid, black),
Expand Down
17 changes: 0 additions & 17 deletions bs-css-dom/bsconfig.json

This file was deleted.

17 changes: 8 additions & 9 deletions bs-css-dom/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,32 @@
"name": "bs-css-dom",
"version": "6.1.1",
"description": "bs-css bindings for React DOM",
"type": "module",
"scripts": {
"re:clean": "rescript clean",
"re:build": "rescript build",
"re:watch": "rescript build -w",
"re:build": "rescript",
"re:watch": "rescript watch",
"serve": "../node_modules/.bin/esbuild ./lib/js/example/App.js --servedir=example --outdir=example/js --bundle --loader:.js=jsx --define:process.env.NODE_ENV=\\\"development\\\""
},
"keywords": [
"bucklescript",
"rescript",
"reasonML",
"css"
],
"author": "Hervé Giraud <giraud.contact@yahoo.fr>",
"license": "ISC",
"repository": {
"type": "git",
"url": "git+https://github.com/reasonml-labs/bs-css.git"
"url": "git+https://github.com/giraud/bs-css.git"
},
"dependencies": {
"bs-css": "18.1.1"
},
"peerDependencies": {
"@rescript/react": "^0.10.0",
"react": "^17.0.0",
"react-dom": "^17.0.0"
"@rescript/react": "^0.14.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"rescript": "^9.0.0"
"rescript": "^12.0.0"
}
}
17 changes: 17 additions & 0 deletions bs-css-dom/rescript.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "bs-css-dom",
"jsx": { "version": 4 },
"warnings": {
"number": "+A-32-34-44",
"error": "+A-32-34-44"
},
"suffix": ".mjs",
"sources": ["src"],
"dependencies": ["bs-css", "@rescript/react"],
"package-specs": [
{
"module": "esmodule",
"in-source": false
}
]
}
28 changes: 14 additions & 14 deletions bs-css-dom/src/Css.res
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@ include Css_Legacy_Core
include Css_Colors

include Css_Legacy_Core.Make({
type styleEncoding = ReactDOM.Style.t
type renderer = Js.Json.t // not relevant
type styleEncoding = JsxDOMStyle.t
type renderer = JSON.t // not relevant
exception NotImplemented

external unsafeJsonCast: Js.Json.t => styleEncoding = "%identity"
external unsafeJsCast: Js.t<'a> => styleEncoding = "%identity"
external unsafeJsonCast: JSON.t => styleEncoding = "%identity"
external unsafeJsCast: {..} => styleEncoding = "%identity"

let injectRaw = (. _) => raise(NotImplemented)
let renderRaw = (. _, _) => raise(NotImplemented)
let injectRaw = _ => throw(NotImplemented)
let renderRaw = (_, _) => throw(NotImplemented)

let injectRules = (. _, _) => raise(NotImplemented)
let renderRules = (. _, _, _) => raise(NotImplemented)
let injectRules = (_, _) => throw(NotImplemented)
let renderRules = (_, _, _) => throw(NotImplemented)

let mergeStyles = (. styles) =>
Belt.Array.reduce(styles, Js.Obj.empty(), (acc, item) =>
Js.Obj.assign(acc, Obj.magic(item))
let mergeStyles = styles =>
Array.reduce(styles, Object.make(), (acc, item) =>
Object.assign(acc, Obj.magic(item))
)->unsafeJsCast

let make = (. props) => props->unsafeJsonCast
let make = props => props->unsafeJsonCast

let makeKeyframes = (. _) => raise(NotImplemented)
let renderKeyframes = (. _, _) => raise(NotImplemented)
let makeKeyframes = _ => throw(NotImplemented)
let renderKeyframes = (_, _) => throw(NotImplemented)
})
30 changes: 15 additions & 15 deletions bs-css-dom/src/CssJs.res
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@ include Css_Js_Core
include Css_Colors

include Css_Js_Core.Make({
type styleEncoding = ReactDOM.Style.t
type renderer = Js.Json.t // not relevant
type styleEncoding = JsxDOMStyle.t
type renderer = JSON.t // not relevant
exception NotImplemented

external unsafeJsonCast: Js.Json.t => styleEncoding = "%identity"
external unsafeJsCast: Js.t<'a> => styleEncoding = "%identity"
external unsafeJsonCast: JSON.t => styleEncoding = "%identity"
external unsafeJsCast: {..} => styleEncoding = "%identity"

let injectRaw = (. _) => raise(NotImplemented)
let renderRaw = (. _, _) => raise(NotImplemented)
let injectRaw = _ => throw(NotImplemented)
let renderRaw = (_, _) => throw(NotImplemented)

let injectRules = (. _, _) => raise(NotImplemented)
let renderRules = (. _, _, _) => raise(NotImplemented)
let injectRules = (_, _) => throw(NotImplemented)
let renderRules = (_, _, _) => throw(NotImplemented)

let mergeStyles = (. styles) =>
Belt.Array.reduce(styles, Js.Obj.empty(), (acc, item) =>
Js.Obj.assign(acc, Obj.magic(item))
let mergeStyles = styles =>
Array.reduce(styles, Object.make(), (acc, item) =>
Object.assign(acc, Obj.magic(item))
)->unsafeJsCast

let make = (. rules) => rules->unsafeJsonCast
let make = rules => rules->unsafeJsonCast

let makeKeyframes = (. _) => raise(NotImplemented)
let renderKeyframes = (. _, _) => raise(NotImplemented)
})
let makeKeyframes = _ => throw(NotImplemented)
let renderKeyframes = (_, _) => throw(NotImplemented)
})
14 changes: 0 additions & 14 deletions bs-css-emotion/bsconfig.json

This file was deleted.

Loading