Skip to content

Commit

Permalink
Fix #157: Add Attr.ClassPred, DynamicClassPred
Browse files Browse the repository at this point in the history
  • Loading branch information
Tarmil committed Feb 26, 2018
1 parent 2cd7acc commit 04bba18
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 21 deletions.
35 changes: 20 additions & 15 deletions WebSharper.UI.Tests/Main.fs
Original file line number Diff line number Diff line change
Expand Up @@ -567,21 +567,26 @@ module Main =
]
|> Doc.RunAppend JS.Document.Body
let rv = Var.Create { x = "red"; y = { z = "green"; t = "test" } }
div [Attr.Style "color" rv.V.y.z] [
text "Test text x.V: enter a color: "
Doc.Input [
attr.style ("background: " + rv.V.y.z)
on.click (fun el ev ->
let f x = x // Inner generic function that fails to compile if this lambda is passed as an Expr.
// This checks that we are calling:
// Client.on.click : (Element -> Event -> unit) -> Attr
// and not:
// Html.on.click : Expr<Element -> Event -> unit> -> Attr
()
)
] (rv.LensAuto(fun v -> v.y.z))
Doc.PasswordBoxV [attr.style ("background: " + rv.V.y.z)] rv.V.y.z
text (" You typed: " + rv.V.y.z)
div [
Attr.Style "color" rv.V.y.z
] [
p [] [
text "Test text x.V: enter a color: "
Doc.Input [
attr.style ("background: " + rv.V.y.z)
on.click (fun el ev ->
let f x = x // Inner generic function that fails to compile if this lambda is passed as an Expr.
// This checks that we are calling:
// Client.on.click : (Element -> Event -> unit) -> Attr
// and not:
// Html.on.click : Expr<Element -> Event -> unit> -> Attr
()
)
] (rv.LensAuto(fun v -> v.y.z))
Doc.PasswordBoxV [attr.style ("background: " + rv.V.y.z)] rv.V.y.z
]
p [] [text (" You typed: " + rv.V.y.z)]
V(ul [] (rv.V.y.z |> Seq.map (fun c -> li [] [text (string c)] :> Doc))).V
p [Attr.ClassPred "is-green" (rv.V.y.z = "green")] [text "this should be bordered with green iff you typed \"green\"."]
]
|> Doc.RunAppend JS.Document.Body
5 changes: 4 additions & 1 deletion WebSharper.UI.Tests/index.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en">
<head>
<title>WebSharper.UI.Tests</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="Content/WebSharper.UI.Tests.css" />
<script type="text/javascript" src="Content/WebSharper.UI.Tests.head.js"></script>
<style>
.is-green { border: solid 1px green; }
</style>
</head>
<body>
<div id="stresstest"></div>
Expand Down
17 changes: 12 additions & 5 deletions WebSharper.UI/Attr.Client.fs
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,6 @@ module Attr =
let Style name value =
As<Attr> (Attrs.Static (fun el -> DU.SetStyle el name value))

let Class name =
As<Attr> (Attrs.Static (fun el -> DU.AddClass el name))

let Animated name tr view attr =
As<Attr> (Attrs.Animated tr view (fun el v -> DU.SetAttr el name (attr v)))

Expand Down Expand Up @@ -329,9 +326,19 @@ module Attr =
(OnAfterRender (fun el -> callback el el?(id)))
(DynamicCustom (fun el x -> el?(id) <- x) v)

let DynamicClass name view ok =
let DynamicClassPred name view =
As<Attr> (Attrs.Dynamic view (fun el v ->
if ok v then DU.AddClass el name else DU.RemoveClass el name))
if v then DU.AddClass el name else DU.RemoveClass el name))

[<JavaScript; Macro(typeof<Macros.AttrClass>)>]
let ClassPred name isSet =
As<Attr> (Attrs.Static (fun el ->
if isSet then DU.AddClass el name else DU.RemoveClass el name))

let Class name = ClassPred name true

let DynamicClass name view ok =
DynamicClassPred name (View.Map ok view)

let DynamicPred name predView valView =
let viewFn el (p, v) =
Expand Down
7 changes: 7 additions & 0 deletions WebSharper.UI/Attr.Client.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,14 @@ module Attr =
/// Sets a CSS class.
val Class : name: string -> Attr

// new; V-enabled on `isSet` (turns it into DynamicClassPred)
val ClassPred : name: string -> isSet: bool -> Attr

/// Dynamic variant of Style.
val DynamicClassPred : name: string -> isSet: View<bool> -> Attr

/// Sets a CSS class when the given view satisfies a predicate.
[<System.Obsolete "Use ClassPred or DynamicClassPred">]
val DynamicClass : name: string -> view: View<'T> -> apply: ('T -> bool) -> Attr

/// Sets an attribute when a view satisfies a predicate.
Expand Down
10 changes: 10 additions & 0 deletions WebSharper.UI/Macros.fs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ module internal Macros =
| _ -> false
let isV (m: Method) = m.Value.MethodName = "get_V"
let stringT = NonGenericType (ty' "netstandard" "System.String")
let boolT = NonGenericType (ty' "netstandard" "System.Boolean")
let objT = NonGenericType (ty' "netstandard" "System.Object")
let viewModule = NonGeneric (ty "View")
let varModule = NonGeneric (ty "Var")
Expand All @@ -83,6 +84,7 @@ module internal Macros =
let textViewFn = gen[] (meth "TextView" [viewOf stringT] docT)
let attrDynFn = gen[] (meth "Dynamic" [stringT; viewOf stringT] attrT)
let attrDynStyleFn = gen[] (meth "DynamicStyle" [stringT; viewOf stringT] attrT)
let attrDynClassFn = gen[] (meth "DynamicClassPred" [stringT; viewOf boolT] attrT)
let docEmbedFn t = gen[t] (meth "EmbedView" [viewOf T0] docT)
let lensFn t u = gen[t; u] (meth "Lens" [varOf T0; T0 ^-> T1; T0 ^-> T1 ^-> T0] (varOf T1))
let inputFn n t = gen[] (meth n [seqOf attrT; varOf t] eltT)
Expand Down Expand Up @@ -280,6 +282,14 @@ module internal Macros =
| V.Kind.Const _ -> MacroFallback
| V.Kind.View e -> MacroOk (Call (None, clientAttrModule, attrDynStyleFn, [call.Arguments.[0]; e]))

type AttrClass() =
inherit Macro()

override this.TranslateCall(call) =
match V.Visit stringT call.Arguments.[1] with
| V.Kind.Const _ -> MacroFallback
| V.Kind.View e -> MacroOk (Call (None, clientAttrModule, attrDynClassFn, [call.Arguments.[0]; e]))

type LensMeth() =
inherit Macro()

Expand Down
1 change: 1 addition & 0 deletions WebSharper.UI/Macros.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ module internal Macros =
[<Class>] type TextView = inherit WebSharper.Core.Macro
[<Class>] type AttrCreate = inherit WebSharper.Core.Macro
[<Class>] type AttrStyle = inherit WebSharper.Core.Macro
[<Class>] type AttrClass = inherit WebSharper.Core.Macro
[<Class>] type ElementMixed = inherit WebSharper.Core.Macro
[<Class>] type DocConcatMixed = inherit WebSharper.Core.Macro
[<Class>] type LensMeth = inherit WebSharper.Core.Macro
Expand Down

0 comments on commit 04bba18

Please sign in to comment.