Coder Social home page Coder Social logo

fable.haunted's Introduction

Fable.Haunted

Haunted bindings for Fable

Too stringy? check out vscode-template-fsharp-highlight for html highlight in VSCode

Check the library in action here

Lit will only re-render the particular parts of your template that change the rest will remain unchanged! render-on-change

module Main

open Browser.Types
open Lit
open Haunted
open Haunted.Types
open Fable.Core
open Controllers

JsInterop.importSideEffects "./styles.css"

type EventTarget with
    member this.Value = (this :?> HTMLInputElement).value

type Msg =
    | Increment
    | Decrement
    | Reset

let private custom_element
    (props: {| sample: string option
               complexValues: {| message: string |} option |})
    =
    let value =
        props.complexValues
        |> Option.defaultValue {| message = "default message" |}

    let mouseCtrl =
        Haunted.useController<MouseController> (fun host -> MouseController(host) :> ReactiveController)

    let sample = defaultArg props.sample "default sample"

    html
        $"""
        <p>A! {sample} - {value.message}</p>
        <p>
            You can use reactive controllers too!
            <br>
            Mouse Position: x - {mouseCtrl.x}, y - {mouseCtrl.y}
        </p>
    """

// defineComponent registers a Custom Element so you don't need to actually
// call this function inside any component, you can use the component itself
defineComponent
    "inner-component"
    (Haunted.Component(
        custom_element,
        // if you want to monitor attributes you need to pass an array of attribute names
        // these will become available in the function's first argument
        // also these components can be simple custom elements without shadow DOM
        // if you choose not to use shadow DOM you can use normal css stylesheets like bulma or bootstrap
        {| observedAttributes = [| "sample" |]
           useShadowDOM = false |}
    ))

// by itself lit-html functions are stateless
let private aStatelessFunction paramA paramB =
    html
        $"""
        <div>A standard stateless Lit Template!</div>
        this will re-render when the parameters change: {paramA} - {paramB}
        """

let private elmishLike: Reducer<int, Msg> =
    fun state action ->
        match action with
        | Increment -> state + 1
        | Decrement -> state - 1
        | Reset -> 0

// we can use haunted to add state to our components
let private app () =

    let state, dispatch = Haunted.useReducer (elmishLike, 0)

    let log =
        Haunted.useCallback ((fun x -> printfn "%s" x), [| state |])

    let clockCtrl =
        Haunted.useController<ClockController> (fun host -> ClockController(host, 1000) :> ReactiveController)

    log $"{state}"

    let complex =
        {| message = $"Complex object message value: {state}" |}

    html
        $"""
        <h1>Hello, World! - {clockCtrl.time.ToLongTimeString()}</h1>
        <!--You can observe attributes or even properties thanks to lit's templating engine -->
        <inner-component sample={$"Attribute value: {state}"} .complexValues={complex}></inner-component>
        {aStatelessFunction "value" state}
        <section>
            <p>Counter: {state}</p>
            <button @click="{fun _ -> dispatch Increment}">Increment</button>
            <button @click="{fun _ -> dispatch Decrement}">Decrement</button>
            <button @click="{fun _ -> dispatch Reset}">Reset</button>
        </section>
        """

defineComponent "fable-app" (Haunted.Component(app, {| useShadowDOM = false |}))

fable.haunted's People

Contributors

alfonsogarciacaro avatar angelmunoz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

fable.haunted's Issues

Namespace: Haunted or Fable.Haunted?

We had some discussions a while ago about how to name Fable packages. IIRC we agreed that it was better to prefix Nuget packages with Fable so they are more searchable, but it was tedious for users to open too many Fable. statements, so it was preferred to drop Fable from the namespace. This is how packages like Fable.Elmish or Fable.Browser.* works. Fable.Lit is also like this and there's a contrast in the open statements of the sample.

open Browser.Types
open Lit
open Fable.Haunted
open Fable.Haunted.Types

Maybe we should just use Haunted? What do you think @AngelMunoz? Also cc @MangelMaxime

lit-html 2

This is a bit confusing, I realized the documentation in lit.dev is for lit-html 2 which is currently in release candidate state. And haunted depends on lit-html 1. It'd be nice to start using lit-html 2 right away as it has interesting features like ref but I'm not sure when haunted will support it. Besides, I was very excited about virtual components because they would make the transition easier from react components, but it looks they have issues.

So basically the question is, how much should we commit ourselves to haunted? Does it look as they will move fast enough? Should we try to create our own hooks (with the new directives in lit-html 2 this looks easier).

Port Feliz.UseElmish

I guess it should be immediately usable although we need some other Feliz hooks like useCancellationToken. I can try to do it later.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.