Skip to content

Instantly share code, notes, and snippets.

@AngelMunoz
Created September 10, 2021 18:13
Show Gist options
  • Save AngelMunoz/e252b15a237ce40ddaf792e851952f08 to your computer and use it in GitHub Desktop.
Save AngelMunoz/e252b15a237ce40ddaf792e851952f08 to your computer and use it in GitHub Desktop.
Bindings for LitElement
module Lit.Extensions
open Fable.Core
open Fable.Core.JsInterop
open Lit
[<Interface>]
type ReactiveController =
abstract member hostConnected : unit -> unit
abstract member hostDisconnected : unit -> unit
abstract member hostUpdate : unit -> unit
abstract member hostUpdated : unit -> unit
[<Interface>]
type ReactiveControllerHost =
abstract member updateComplete : bool
abstract member addController : ReactiveController -> unit
abstract member removeController : ReactiveController -> unit
abstract member requestUpdate : unit -> unit
[<ImportMember("lit")>]
type LitElement() =
abstract member attributeChangedCallback : string -> unit
default _.attributeChangedCallback(name: string) : unit = jsNative
abstract member attributeChangedCallback : string * string option * string option -> unit
default _.attributeChangedCallback(name: string, ?_old: string, ?value: string) : unit = jsNative
abstract member addController : ReactiveController -> unit
default _.addController(controller: ReactiveController) = jsNative
abstract member removeController : ReactiveController -> unit
default _.removeController(controller: ReactiveController) = jsNative
abstract member connectedCallback : unit -> unit
default _.connectedCallback() : unit = jsNative
abstract member disconnectedCallback : unit -> unit
default _.disconnectedCallback() : unit = jsNative
abstract member createRenderRoot : unit -> obj
default _.createRenderRoot() : obj = jsNative
abstract member render : unit -> TemplateResult
default _.render() : TemplateResult = jsNative
abstract member firstUpdated : obj -> unit
default _.firstUpdated(_changedProperties: obj) : unit = jsNative
abstract member getUpdateComplete : unit -> JS.Promise<bool>
default _.getUpdateComplete() : JS.Promise<bool> = jsNative
abstract member performUpdate : unit -> JS.Promise<obj>
default _.performUpdate() : JS.Promise<obj> = jsNative
abstract member requestUpdate : unit -> unit
default _.requestUpdate() = jsNative
abstract member requestUpdate : string option * obj option * obj option -> unit
default _.requestUpdate(?name: string, ?oldValue: obj, ?options: obj) = jsNative
abstract member shouldUpdate : unit -> bool
default _.shouldUpdate() : bool = jsNative
abstract member shouldUpdate : obj option -> bool
default _.shouldUpdate(?_changedProperties: obj) : bool = jsNative
abstract member update : obj option -> unit
default _.update(?changedProperties: obj) : unit = jsNative
abstract member updated : obj option -> unit
default _.updated(?_changedProperties: obj) : unit = jsNative
abstract member willUpdate : obj option -> unit
default _.willUpdate(?_changedProperties: obj) : unit = jsNative
member _.renderRoot: obj = jsNative
member _.hasUpdated: bool = jsNative
member _.isUpdatePending: bool = jsNative
member _.updateComplete: bool = jsNative
[<Emit("customElements.define($0, $1)")>]
let defineComponent (name: string) (comp: obj) : unit = jsNative
[<Emit("String")>]
let JsString: obj = jsNative
/// <summary>
/// Indicates how to convert the attribute to a property.
/// It is used to convert the attribute value a the property value.
/// </summary>
/// <remarks>
/// The first parameter is the string value from the attribute in the DOM node.
/// The second parameter is the type of the object (if it was provided) that may be one of
/// `Boolean`, `String`, `Number`, `Object`, and `Array`
/// </remarks>
type SimpleConverter = string option -> obj option -> obj
/// The function should take the `newValue` and `oldValue` and
/// return `true` if an update should be requested.
type HasChangedFn = obj -> obj -> bool
type ComplexConverter =
{| fromAttribute: SimpleConverter
toAttribute: obj -> obj -> obj |}
/// Indicates how to convert the attribute to/from a property. If this value
/// is `Simple`, it is used to convert the attribute value a the property
/// value. If it's `Complex`, when a property changes
/// and the converter is used to update the attribute,
/// the property is never updated again as a result of the attribute changing,
/// and vice versa.
[<EraseAttribute>]
type AttributeConverter =
| Complex of ComplexConverter
| Simple of SimpleConverter
type Property =
/// <summary>
/// Indicates the property is internal private state. The
/// property should not be set by users. A common
/// practice to use a leading `_` in the name. The property is not added to
/// `observedAttributes`.
/// </summary>
| Internal
/// <summary>
/// Indicates the property becomes an observed attribute.
/// the lowercased property name is observed (e.g. `fooBar` becomes `foobar`).
/// </summary>
| Attribute of bool
/// <summary>
/// Indicates the property becomes an observed attribute.
/// the string value is observed (e.g 'color-depth').
/// </summary>
/// <remarks>The value has to be lower-cased and dash-cased due to the HTML Spec.</remarks>
| CustomAttribute of string
/// Indicates the type of the property. This is used only as a hint for the
/// `converter` to determine how to convert the attribute
/// to/from a property.
/// `Boolean`, `String`, `Number`, `Object`, and `Array` should be used.
| Type of obj
/// A function that indicates if a property should be considered changed when
/// it is set. The function should take the `newValue` and `oldValue` and
/// return `true` if an update should be requested.
| HasChanged of HasChangedFn
/// Indicates how to convert the attribute to/from a property. If this value
/// is a function, it is used to convert the attribute value a the property
/// value. If it's an object, it can have keys for `fromAttribute` and
/// `toAttribute`. If no `toAttribute` function is provided and
/// `reflect` is set to `true`, the property value is set directly to the
/// attribute. A default `converter` is used if none is provided; it supports
/// `Boolean`, `String`, `Number`, `Object`, and `Array`. Note,
/// when a property changes and the converter is used to update the attribute,
/// the property is never updated again as a result of the attribute changing,
/// and vice versa.
| Converter of AttributeConverter
/// Indicates if the property should reflect to an attribute.
/// If `true`, when the property is set, the attribute is set using the
/// attribute name determined according to the rules for the `attribute`
/// property option and the value of the property converted using the rules
/// from the `converter` property option.
| Reflect
/// Indicates whether an accessor will be created for this property. By
/// default, an accessor will be generated for this property that requests an
/// update when set. No accessor will be created, and
/// it will be the user's responsibility to call
/// `this.requestUpdate(propertyName, oldValue)` to request an update when
/// the property changes.
| NoAccessor
let getLitProperties (properties: ((string * Property list) list)) =
createObj [ for (property, configuration) in properties do
property
==> createObj [ for config in configuration do
match config with
| Internal -> "state" ==> (true :> obj)
| Attribute value -> "attribute" ==> (value :> obj)
| CustomAttribute value -> "attribute" ==> (value :> obj)
| Type value -> "type" ==> value
| HasChanged value -> "hasChanged" ==> unbox value
| Converter value -> "converter" ==> (value :> obj)
| Reflect -> "reflect" ==> (true :> obj)
| NoAccessor -> "noAccessor" ==> (true :> obj) ] ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment