Skip to content

Csharp -- Some bugfixes and improvements to the interop layer (mainly related to callbacks) #53

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
8431b7c
Multiple improvements in the code for the C# tests. (Host numbers, de…
Mrjuanblack Oct 27, 2021
8bfa310
New tests for the Basic Callback C# chapter.
Mrjuanblack Oct 28, 2021
b7019fd
CSharp -- Add seq overload to RadioItems options
jannesiera Oct 29, 2021
39dde8a
CSharp -- Fix bug where setting some component properties (like Radio…
jannesiera Oct 29, 2021
f87f9d1
Test for verifying the differences between C# and F# code on MultiInp…
Mrjuanblack Oct 29, 2021
704bcb0
Merge branch 'csharp' of https://github.com/plotly/Dash.NET into csharp
Mrjuanblack Oct 29, 2021
831d87a
Test for chained callbacks.
Mrjuanblack Oct 29, 2021
709b4aa
CSharp -- Fix ComponentPropTypes (passing to and receive from callbac…
jannesiera Nov 1, 2021
ccd1ede
CSharp -- Fix ComponentPropTypes (passing to and receive from callbac…
jannesiera Nov 1, 2021
19313be
CSharp -- Documenttion -- Fix Callback_CallbackChain example
jannesiera Nov 1, 2021
b63921b
CSharp -- Fix carriage returns in xml comments so they are correctly …
jannesiera Nov 1, 2021
7a43406
Merge branch 'dev' into csharp
jannesiera Nov 1, 2021
ba4cba7
Comment cleanup
jannesiera Nov 1, 2021
8d055e7
Changes to all examples to be more similar to F# docs (ip adrresses, …
Mrjuanblack Nov 1, 2021
76d6dc4
Merge branch 'csharp' of https://github.com/plotly/Dash.NET into csharp
Mrjuanblack Nov 1, 2021
084703d
New organization for the examples. New examples for the whole Core Co…
Mrjuanblack Nov 2, 2021
dacdf46
New tests for Core Components Input chapter. I also moved the dropdow…
Mrjuanblack Nov 3, 2021
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
25 changes: 25 additions & 0 deletions Dash.NET.CSharp/Callback.fs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace Dash.NET.CSharp

open System.Runtime.InteropServices
open Dash.NET.CSharp.DCC


type Dependency = System.ValueTuple<string, ComponentProperty>
Expand All @@ -9,6 +10,30 @@ type internal Helpers =
static member internal ConvertDependency ((id, prop) : System.ValueTuple<string, ComponentProperty>) = Dash.NET.Dependency.create (id, prop |> ComponentProperty.Unwrap)

type CallbackResult = internal WrappedCallbackResult of Dash.NET.CallbackResultBinding with
//static member Create(target : Dependency, results : obj array) =
// {
// Dash.NET.CallbackResultBinding.Target = target |> Helpers.ConvertDependency
// Dash.NET.CallbackResultBinding.BoxedResult =
// [
// for result in results do
// match result with
// | :? IUnwrap as result -> result.Unwrap()
// | _ -> result
// ]
// |> box
// }
// |> WrappedCallbackResult

//static member Create(target : Dependency, result : obj) =
// {
// Dash.NET.CallbackResultBinding.Target = target |> Helpers.ConvertDependency
// Dash.NET.CallbackResultBinding.BoxedResult =
// match result with
// | :? IUnwrap as result -> result.Unwrap() |> box
// | _ -> result |> box
// }
// |> WrappedCallbackResult

static member Create<'a>(target : Dependency, result : 'a) =
{
Dash.NET.CallbackResultBinding.Target = target |> Helpers.ConvertDependency
Expand Down
127 changes: 106 additions & 21 deletions Dash.NET.CSharp/ComponentPropTypes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ open System
open System.Runtime.InteropServices


type IUnwrap =
abstract Unwrap: unit -> obj

//module ComponentPropTypes =

type InputType = private WrappedInputType of Dash.NET.ComponentPropTypes.InputType with
Expand Down Expand Up @@ -38,11 +41,25 @@ type InputMode = private WrappedInputMode of Dash.NET.ComponentPropTypes.InputMo

// SpellCheckOptions can be exposed as a bool

type LoadingState = private WrappedLoadingState of Dash.NET.ComponentPropTypes.LoadingState with
static member internal Convert (v : LoadingState) : Dash.NET.ComponentPropTypes.LoadingState = match v with WrappedLoadingState v -> v
static member Init (isLoading : bool, [<Optional>] propName : string, [<Optional>] componentName : string) =
//type LoadingState = private WrappedLoadingState of Dash.NET.ComponentPropTypes.LoadingState with
// static member internal Unwrap (v : LoadingState) : Dash.NET.ComponentPropTypes.LoadingState = match v with WrappedLoadingState v -> v
// static member Init (isLoading : bool, [<Optional>] propName : string, [<Optional>] componentName : string) =
// guardAgainstNull "isLoading" isLoading
// Dash.NET.ComponentPropTypes.LoadingState.init (isLoading, ?propName = Option.ofObj propName, ?componentName = Option.ofObj componentName) |> WrappedLoadingState

[<CLIMutable>]
type LoadingState =
{
isLoading: bool
propName: string
componentName: string
}
static member Unwrap (v : LoadingState) : Dash.NET.ComponentPropTypes.LoadingState = Dash.NET.ComponentPropTypes.LoadingState.init (v.isLoading, ?propName = Option.ofObj v.propName, ?componentName = Option.ofObj v.componentName)

module LoadingState =
let Init (isLoading: bool, [<Optional>] propName: string, [<Optional>] componentName: string) : LoadingState =
guardAgainstNull "isLoading" isLoading
Dash.NET.ComponentPropTypes.LoadingState.init (isLoading, ?propName = Option.ofObj propName, ?componentName = Option.ofObj componentName) |> WrappedLoadingState
{ isLoading = isLoading; propName = propName; componentName = componentName }


type PersistenceTypeOptions = private WrappedPersistenceTypeOptions of Dash.NET.ComponentPropTypes.PersistenceTypeOptions with
Expand All @@ -53,28 +70,96 @@ type PersistenceTypeOptions = private WrappedPersistenceTypeOptions of Dash.NET.
static member Session () = Dash.NET.ComponentPropTypes.PersistenceTypeOptions.Session |> PersistenceTypeOptions.Wrap
static member Memory () = Dash.NET.ComponentPropTypes.PersistenceTypeOptions.Memory |> PersistenceTypeOptions.Wrap

type DropdownOption = private WrappedDropdownOption of Dash.NET.ComponentPropTypes.DropdownOption with
static member internal Convert (v : DropdownOption) = match v with WrappedDropdownOption v -> v
static member Init (label : IConvertible, value : IConvertible, [<Optional>] disabled : Nullable<bool>, [<Optional>] title : string) =
//type DropdownOption = private WrappedDropdownOption of Dash.NET.ComponentPropTypes.DropdownOption with
// static member internal Unwrap (v : DropdownOption) = match v with WrappedDropdownOption v -> v
// static member Init (label : IConvertible, value : IConvertible, [<Optional>] disabled : Nullable<bool>, [<Optional>] title : string) =
// guardAgainstNull "label" label
// guardAgainstNull "value" value
// Dash.NET.ComponentPropTypes.DropdownOption.init (label, value, ?disabled = Option.ofNullable disabled, ?title = Option.ofObj title) |> WrappedDropdownOption

[<CLIMutable>]
type DropdownOption<'a, 'b when 'a :> IConvertible and 'b :> IConvertible> =
{
label: 'a
value: 'b
disabled: Nullable<bool>
title: string
}
static member Unwrap (v : DropdownOption<'a, 'b>) : Dash.NET.ComponentPropTypes.DropdownOption = Dash.NET.ComponentPropTypes.DropdownOption.init (v.label, v.value, ?disabled = Option.ofNullable v.disabled, ?title = Option.ofObj v.title)

module DropdownOption =
let Init<'a, 'b when 'a :> IConvertible and 'b :> IConvertible> (label:'a, value:'b, [<Optional>] disabled: Nullable<bool>, [<Optional>] title: string) : DropdownOption<'a, 'b> =
guardAgainstNull "label" label
guardAgainstNull "value" value
Dash.NET.ComponentPropTypes.DropdownOption.init (label, value, ?disabled = Option.ofNullable disabled, ?title = Option.ofObj title) |> WrappedDropdownOption
{ label = label; value = value; disabled = disabled; title = title }

//type RadioItemsOption = private WrappedRadioItemsOption of Dash.NET.ComponentPropTypes.RadioItemsOption with
// static member Unwrap (v : RadioItemsOption) : Dash.NET.ComponentPropTypes.RadioItemsOption = match v with WrappedRadioItemsOption v -> v
// static member Init (label : IConvertible, value : IConvertible, [<Optional>] disabled : Nullable<bool>) =
// guardAgainstNull "label" label
// guardAgainstNull "value" value
// Dash.NET.ComponentPropTypes.RadioItemsOption.init (label, value, ?disabled = Option.ofNullable disabled) |> WrappedRadioItemsOption
// interface IUnwrap with
// member x.Unwrap () = RadioItemsOption.Unwrap x |> box

open DynamicObj

[<CLIMutable>]
type RadioItemsOption<'a, 'b when 'a :> IConvertible and 'b :> IConvertible> =
{
label : 'a
value : 'b
disabled : Nullable<bool>
}
with
//static member Init(label:'a, value:'b, [<Optional>]disabled:Nullable<bool>) = { label = label; value = value; disabled = disabled}
static member Unwrap (v : RadioItemsOption<'a, 'b>) : Dash.NET.ComponentPropTypes.RadioItemsOption = Dash.NET.ComponentPropTypes.RadioItemsOption.init (v.label, v.value, ?disabled = Option.ofNullable v.disabled)

type RadioItemsOption = private WrappedRadioItemsOption of Dash.NET.ComponentPropTypes.RadioItemsOption with
static member internal Convert (v : RadioItemsOption) : Dash.NET.ComponentPropTypes.RadioItemsOption = match v with WrappedRadioItemsOption v -> v
static member Init (label : IConvertible, value : IConvertible, [<Optional>] disabled : Nullable<bool>) =
module RadioItemsOption =
let Init<'a, 'b when 'a :> IConvertible and 'b :> IConvertible> (label: 'a, value: 'b, [<Optional>] disabled: Nullable<bool>) : RadioItemsOption<'a, 'b> =
guardAgainstNull "label" label
guardAgainstNull "value" value
Dash.NET.ComponentPropTypes.RadioItemsOption.init (label, value, ?disabled = Option.ofNullable disabled) |> WrappedRadioItemsOption
{ label = label; value = value; disabled = disabled }


type TabColors = private WrappedTabColors of Dash.NET.ComponentPropTypes.TabColors with
static member internal Convert (v : TabColors) : Dash.NET.ComponentPropTypes.TabColors = match v with WrappedTabColors v -> v
static member Init ([<Optional>] border : string, [<Optional>] primary : string, [<Optional>] background : string) =
Dash.NET.ComponentPropTypes.TabColors.init (?border = Option.ofObj border, ?primary = Option.ofObj primary, ?background = Option.ofObj background) |> WrappedTabColors

type ChecklistOption = private WrappedChecklistOption of Dash.NET.ComponentPropTypes.ChecklistOption with
static member internal Convert (v : ChecklistOption) : Dash.NET.ComponentPropTypes.ChecklistOption = match v with WrappedChecklistOption v -> v
static member Init (label : IConvertible, value : IConvertible, [<Optional>] disabled : Nullable<bool>) =
//type TabColors = private WrappedTabColors of Dash.NET.ComponentPropTypes.TabColors with
// static member internal Unwrap (v : TabColors) : Dash.NET.ComponentPropTypes.TabColors = match v with WrappedTabColors v -> v
// static member Init ([<Optional>] border : string, [<Optional>] primary : string, [<Optional>] background : string) =
// Dash.NET.ComponentPropTypes.TabColors.init (?border = Option.ofObj border, ?primary = Option.ofObj primary, ?background = Option.ofObj background) |> WrappedTabColors

[<CLIMutable>]
type TabColors =
{
border: string
primary: string
background: string
}
static member Unwrap (v : TabColors) : Dash.NET.ComponentPropTypes.TabColors = Dash.NET.ComponentPropTypes.TabColors.init (?border = Option.ofObj v.border, ?primary = Option.ofObj v.primary, ?background = Option.ofObj v.background)

module TabColors =
let Init ([<Optional>] border: string, [<Optional>] primary: string, [<Optional>] background: string) : TabColors =
{ border = border; primary = primary; background = background }


//type ChecklistOption = private WrappedChecklistOption of Dash.NET.ComponentPropTypes.ChecklistOption with
// static member internal Unwrap (v : ChecklistOption) : Dash.NET.ComponentPropTypes.ChecklistOption = match v with WrappedChecklistOption v -> v
// static member Init (label : IConvertible, value : IConvertible, [<Optional>] disabled : Nullable<bool>) =
// guardAgainstNull "label" label
// guardAgainstNull "value" value
// Dash.NET.ComponentPropTypes.ChecklistOption.init (label, value, ?disabled = Option.ofNullable disabled) |> WrappedChecklistOption

[<CLIMutable>]
type ChecklistOption<'a, 'b when 'a :> IConvertible and 'b :> IConvertible> =
{
label: 'a
value: 'b
disabled: Nullable<bool>
title: string
}
static member Unwrap (v : ChecklistOption<'a, 'b>) : Dash.NET.ComponentPropTypes.ChecklistOption = Dash.NET.ComponentPropTypes.ChecklistOption.init (v.label, v.value, ?disabled = Option.ofNullable v.disabled)

module ChecklistOption =
let Init<'a, 'b when 'a :> IConvertible and 'b :> IConvertible> (label:'a, value:'b, [<Optional>] disabled: Nullable<bool>, [<Optional>] title: string) : ChecklistOption<'a, 'b> =
guardAgainstNull "label" label
guardAgainstNull "value" value
Dash.NET.ComponentPropTypes.ChecklistOption.init (label, value, ?disabled = Option.ofNullable disabled) |> WrappedChecklistOption
{ label = label; value = value; disabled = disabled; title = title }
34 changes: 17 additions & 17 deletions Dash.NET.CSharp/CoreComponents/Checklist.fs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ module Checklist =
///<summary>
///An array of options
///</summary>
static member options([<ParamArray>] p : ChecklistOption array) =
static member options([<ParamArray>] p : ChecklistOption<'a,'b> array) =
guardAgainstNull "p" p
p |> Array.iter (guardAgainstNull "p")
OAttr.options (p |> Array.map ChecklistOption.Convert) |> Attr.Wrap
OAttr.options (p |> Array.map ChecklistOption.Unwrap) |> Attr.Wrap
///<summary>
///The currently selected value
///</summary>
Expand Down Expand Up @@ -76,7 +76,7 @@ module Checklist =
///</summary>
static member loadingState(p: LoadingState) =
guardAgainstNull "p" p
OAttr.loadingState (p |> LoadingState.Convert) |> Attr.Wrap
OAttr.loadingState (p |> LoadingState.Unwrap) |> Attr.Wrap
///<summary>
///Used to allow user interactions in this component to be persisted when
///the component - or the page - is refreshed. If &#96;persisted&#96; is truthy and
Expand Down Expand Up @@ -156,44 +156,44 @@ module Checklist =
///The values and labels of the checklist are specified in the &#96;options&#96;
///property and the checked items are specified with the &#96;value&#96; property.
///Each checkbox is rendered as an input with a surrounding label.
///&#10;
///<para>&#160;</para>
///Properties:
///&#10;
///<para>&#160;</para>
///• id (string) - The ID of this component, used to identify dash components
///in callbacks. The ID needs to be unique across all of the
///components in an app.
///&#10;
///<para>&#160;</para>
///• options (list with values of type: record with the fields: 'label: string | number (required)', 'value: string | number (required)', 'disabled: boolean (optional)'; default []) - An array of options
///&#10;
///<para>&#160;</para>
///• value (list with values of type: string | number; default []) - The currently selected value
///&#10;
///<para>&#160;</para>
///• className (string) - The class of the container (div)
///&#10;
///<para>&#160;</para>
///• style (record) - The style of the container (div)
///&#10;
///<para>&#160;</para>
///• inputStyle (record; default {}) - The style of the &lt;input&gt; checkbox element
///&#10;
///<para>&#160;</para>
///• inputClassName (string; default ) - The class of the &lt;input&gt; checkbox element
///&#10;
///<para>&#160;</para>
///• labelStyle (record; default {}) - The style of the &lt;label&gt; that wraps the checkbox input
/// and the option's label
///&#10;
///<para>&#160;</para>
///• labelClassName (string; default ) - The class of the &lt;label&gt; that wraps the checkbox input
/// and the option's label
///&#10;
///<para>&#160;</para>
///• loading_state (record with the fields: 'is_loading: boolean (optional)', 'prop_name: string (optional)', 'component_name: string (optional)') - Object that holds the loading state object coming from dash-renderer
///&#10;
///<para>&#160;</para>
///• persistence (boolean | string | number) - Used to allow user interactions in this component to be persisted when
///the component - or the page - is refreshed. If &#96;persisted&#96; is truthy and
///hasn't changed from its previous value, a &#96;value&#96; that the user has
///changed while using the app will keep that change, as long as
///the new &#96;value&#96; also matches what was given originally.
///Used in conjunction with &#96;persistence_type&#96;.
///&#10;
///<para>&#160;</para>
///• persisted_props (list with values of type: value equal to: 'value'; default ['value']) - Properties whose user interactions will persist after refreshing the
///component or the page. Since only &#96;value&#96; is allowed this prop can
///normally be ignored.
///&#10;
///<para>&#160;</para>
///• persistence_type (value equal to: 'local', 'session', 'memory'; default local) - Where persisted user changes will be stored:
///memory: only kept in memory, reset on page refresh.
///local: window.localStorage, data is kept after the browser quit.
Expand Down
Loading