Skip to content

Commit

Permalink
Reduce bundle size and simplify interop #2, #1
Browse files Browse the repository at this point in the history
  • Loading branch information
Zaid-Ajaj committed Jul 22, 2019
1 parent 7b73de7 commit 90a2e88
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 77 deletions.
8 changes: 6 additions & 2 deletions demo/App.fs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ let customStyles =
style.position position.sticky
]

Browser.Dom.console.log(customStyles)

let render state dispatch =
Html.div [
attr.id "main"
Expand All @@ -46,15 +48,17 @@ let render state dispatch =
Html.span [ customStyles ]

Html.button [
attr.id "incr"
attr.className "btn btn-success"
attr.style [ style.marginLeft 5 ]
attr.style [ style.marginRight 5 ]
attr.onClick (fun _ -> dispatch Increment)
attr.content "Increment"
]

Html.button [
attr.id "decr"
attr.className "btn btn-danger"
attr.style [ style.marginRight 5 ]
attr.styleList [ true, [style.marginLeft 5]; true, [style.color colors.blueViolet] ]
attr.onClick (fun _ -> dispatch Decrement)
attr.content "Decrement"
]
Expand Down
8 changes: 5 additions & 3 deletions src/Attributes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ namespace Feliz

open Fable.React
open Browser.Types
open Fable.Core.JsInterop
open Fable.Core

type attr() =
static member inline id(value: string) = Interop.mkAttr "id" value
Expand Down Expand Up @@ -59,7 +61,7 @@ type attr() =
/// Alias for inline `attr.children [ Html.content value ]`
static member inline content(value: int) = attr.children [ unbox value ]
/// Alias for inline `attr.children [ Html.content value ]`
static member inline content(value: ReactElement) = attr.children [ value ]
static member inline content(value: ReactElement) = attr.children [ unbox value ]
static member inline rows(value: int) = Interop.mkAttr "rows" value
static member inline rowSpan(value: int) = Interop.mkAttr "rowSpan" value
static member inline inputType(value: string) = Interop.mkAttr "type" value
Expand Down Expand Up @@ -136,10 +138,10 @@ type attr() =
static member inline onAnimationEnd (handler: AnimationEvent -> unit) = Interop.mkAttr "onAnimationEnd" handler
static member inline onAnimationIteration (handler: AnimationEvent -> unit) = Interop.mkAttr "onAnimationIteration" handler
static member inline onTransitionEnd (handler: TransitionEvent -> unit) = Interop.mkAttr "onTransitionEnd" handler
static member inline style (properties: IStyleAttribute list) = Interop.mkAttr "style" (Interop.createObj (unbox properties))
static member inline style (properties: IStyleAttribute list) = Interop.mkAttr "style" (keyValueList CaseRules.LowerFirst properties)
static member styleList (properties: (bool * IStyleAttribute list) list) =
properties
|> List.filter fst
|> List.collect snd
|> (unbox >> Interop.createObj)
|> keyValueList CaseRules.LowerFirst
|> Interop.mkAttr "style"
2 changes: 1 addition & 1 deletion src/Feliz.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<PackageIconUrl></PackageIconUrl>
<PackageTags>fsharp;fable;react;html</PackageTags>
<Authors>Zaid Ajaj</Authors>
<Version>0.5.0</Version>
<Version>0.6.0</Version>
<TargetFramework>netstandard2.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
Expand Down
61 changes: 31 additions & 30 deletions src/Html.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ namespace Feliz

open Fable.React
open Fable.Core
open Fable.Core.JsInterop

[<Erase>]
type Html =
Expand Down Expand Up @@ -47,10 +48,10 @@ type Html =
static member inline ol xs = Interop.createElement "ol" xs
static member inline a xs = Interop.createElement "a" xs
static member inline anchor xs = Interop.createElement "anchor" xs
static member inline img xs = Interop.createVoid "img" xs
static member inline br xs = Interop.createVoid "br" xs
static member inline hr xs = Interop.createVoid "hr" xs
static member inline input xs = Interop.createVoid "input" xs
static member inline img xs = Interop.createElement "img" xs
static member inline br xs = Interop.createElement "br" xs
static member inline hr xs = Interop.createElement "hr" xs
static member inline input xs = Interop.createElement "input" xs
static member inline form xs = Interop.createElement "form" xs
static member inline i xs = Interop.createElement "i" xs
static member inline p xs = Interop.createElement "p" xs
Expand All @@ -62,29 +63,29 @@ type Html =
static member content (value: int) : ReactElement = unbox value
static member text (value: string) : ReactElement = unbox value
static member text (value: int) : ReactElement = unbox value
static member inline div (value: string) = Interop.reactElement "div" (obj()) value
static member inline div (value: int) = Interop.reactElement "div" (obj()) value
static member inline span (value: string) = Interop.reactElement "span" (obj()) value
static member inline span (value: int) = Interop.reactElement "span" (obj()) value
static member inline h1 (value: string) = Interop.reactElement "h1" (obj()) value
static member inline h1 (value: int) = Interop.reactElement "h1" (obj()) value
static member inline h2 (value: string) = Interop.reactElement "h2" (obj()) value
static member inline h2 (value: int) = Interop.reactElement "h2" (obj()) value
static member inline h3 (value: string) = Interop.reactElement "h3" (obj()) value
static member inline h3 (value: int) = Interop.reactElement "h3" (obj()) value
static member inline h4 (value: string) = Interop.reactElement "h4" (obj()) value
static member inline h4 (value: int) = Interop.reactElement "h4" (obj()) value
static member inline h5 (value: string) = Interop.reactElement "h5" (obj()) value
static member inline h5 (value: int) = Interop.reactElement "h5" (obj()) value
static member inline h6 (value: string) = Interop.reactElement "h6" (obj()) value
static member inline h6 (value: int) = Interop.reactElement "h6" (obj()) value
static member inline strong(value: string) = Interop.reactElement "strong" (obj()) value
static member inline strong(value: int) = Interop.reactElement "strong" (obj()) value
static member inline p(value: string) = Interop.reactElement "p" (obj()) value
static member inline p(value: int) = Interop.reactElement "p" (obj()) value
static member inline paragraph(value: string) = Interop.reactElement "p" (obj()) value
static member inline paragraph(value: int) = Interop.reactElement "p" (obj()) value
static member inline td(value: string) = Interop.reactElement "td" (obj()) value
static member inline td(value: int) = Interop.reactElement "td" (obj()) value
static member inline th(value: string) = Interop.reactElement "th" (obj()) value
static member inline th(value: int) = Interop.reactElement "th" (obj()) value
static member inline div (value: string) = Interop.reactElement "div" (createObj [ "children" ==> [| value |] ])
static member inline div (value: int) = Interop.reactElement "div" (createObj [ "children" ==> [| value |] ])
static member inline span (value: string) = Interop.reactElement "span" (createObj [ "children" ==> [| value |] ])
static member inline span (value: int) = Interop.reactElement "span" (createObj [ "children" ==> [| value |] ])
static member inline h1 (value: string) = Interop.reactElement "h1" (createObj [ "children" ==> [| value |] ])
static member inline h1 (value: int) = Interop.reactElement "h1" (createObj [ "children" ==> [| value |] ])
static member inline h2 (value: string) = Interop.reactElement "h2" (createObj [ "children" ==> [| value |] ])
static member inline h2 (value: int) = Interop.reactElement "h2" (createObj [ "children" ==> [| value |] ])
static member inline h3 (value: string) = Interop.reactElement "h3" (createObj [ "children" ==> [| value |] ])
static member inline h3 (value: int) = Interop.reactElement "h3" (createObj [ "children" ==> [| value |] ])
static member inline h4 (value: string) = Interop.reactElement "h4" (createObj [ "children" ==> [| value |] ])
static member inline h4 (value: int) = Interop.reactElement "h4" (createObj [ "children" ==> [| value |] ])
static member inline h5 (value: string) = Interop.reactElement "h5" (createObj [ "children" ==> [| value |] ])
static member inline h5 (value: int) = Interop.reactElement "h5" (createObj [ "children" ==> [| value |] ])
static member inline h6 (value: string) = Interop.reactElement "h6" (createObj [ "children" ==> [| value |] ])
static member inline h6 (value: int) = Interop.reactElement "h6" (createObj [ "children" ==> [| value |] ])
static member inline strong(value: string) = Interop.reactElement "strong" (createObj [ "children" ==> [| value |] ])
static member inline strong(value: int) = Interop.reactElement "strong" (createObj [ "children" ==> [| value |] ])
static member inline p(value: string) = Interop.reactElement "p" (createObj [ "children" ==> [| value |] ])
static member inline p(value: int) = Interop.reactElement "p" (createObj [ "children" ==> [| value |] ])
static member inline paragraph(value: string) = Interop.reactElement "p" (createObj [ "children" ==> [| value |] ])
static member inline paragraph(value: int) = Interop.reactElement "p" (createObj [ "children" ==> [| value |] ])
static member inline td(value: string) = Interop.reactElement "td" (createObj [ "children" ==> [| value |] ])
static member inline td(value: int) = Interop.reactElement "td" (createObj [ "children" ==> [| value |] ])
static member inline th(value: string) = Interop.reactElement "th" (createObj [ "children" ==> [| value |] ])
static member inline th(value: int) = Interop.reactElement "th" (createObj [ "children" ==> [| value |] ])
44 changes: 3 additions & 41 deletions src/Interop.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,46 +6,8 @@ open Fable.React

[<RequireQualifiedAccess>]
module Interop =
let reactElement (name: string) (props: 'a) (children: 'b) : ReactElement = import "createElement" "react"

let reactElement (name: string) (props: 'a) : ReactElement = import "createElement" "react"
let inline mkAttr (key: string) (value: obj) : IReactAttribute = unbox (key, value)
let inline mkStyle (key: string) (value: obj) : IStyleAttribute = unbox (key, value)

[<Emit("$2[$0] = $1")>]
let setProperty (key: string) (value: obj) (objectLiteral: obj) = jsNative

let createObj (properties: obj list) =
let propsObj = obj()
let propsList = unbox<(string * obj) list> properties
for (key, value) in propsList do
if key <> "children" then
setProperty key value propsObj
propsObj

let extract (pred: 't -> bool) (xs: 't list) : 't option * 't list =
let rec extract' pred xs elem acc =
match xs, elem with
| [ ], Some _ -> elem, acc
| [ ], None -> None, acc
| values, Some _ -> elem, List.append values acc
| x :: rest, None when pred x -> Some x, List.append acc rest
| x :: rest, None -> extract' pred rest None (List.append [x] acc)

extract' pred xs None [ ]

let createElement name (properties: IReactAttribute list) : ReactElement =
let props = unbox<(string * obj) list> properties
match extract (fun (key, value) -> key = "children") props with
| None, rest ->
let restProps = createObj (unbox rest)
reactElement name restProps null
| Some (key, value), rest ->
let restProps = createObj (unbox rest)
reactElement name restProps (unbox value)

let createVoid name (properties: IReactAttribute list) : ReactElement =
let props = unbox<(string * obj) list> properties
match extract (fun (key, value) -> key = "children") props with
| _, rest ->
let restProps = createObj (unbox rest)
reactElement name restProps null
let inline createElement name (properties: IReactAttribute list) : ReactElement =
reactElement name (keyValueList CaseRules.LowerFirst properties)

0 comments on commit 90a2e88

Please sign in to comment.