From 48538eb552f8040d095ff340486bd4ca34f7d596 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 21 Mar 2024 09:36:30 +0100 Subject: [PATCH] [SimplePrimitives] Add accordion variants with custom titles --- .../Primitives/SimplePrimitives.fs | 55 ++++++++++++++++--- src/Examples (dotnetcore)/23 - Inputs/App.fs | 22 ++++++-- 2 files changed, 64 insertions(+), 13 deletions(-) diff --git a/src/Aardvark.UI.Primitives/Primitives/SimplePrimitives.fs b/src/Aardvark.UI.Primitives/Primitives/SimplePrimitives.fs index c9e9e052..c9028760 100644 --- a/src/Aardvark.UI.Primitives/Primitives/SimplePrimitives.fs +++ b/src/Aardvark.UI.Primitives/Primitives/SimplePrimitives.fs @@ -623,7 +623,7 @@ module SimplePrimitives = | Single _ | Empty true -> true | _ -> false - let private accordionImpl (input: AccordionInput<'msg>) (attributes: AttributeMap<'msg>) (sections: list * DomNode<'msg>>) = + let private accordionImpl (input: AccordionInput<'msg>) (attributes: AttributeMap<'msg>) (sections: list * DomNode<'msg>>) = let dependencies = Html.semui @ [ { name = "accordion"; url = "resources/accordion.js"; kind = Script }] @@ -677,7 +677,7 @@ module SimplePrimitives = for (title, node) in sections do div [clazz "title"] [ i [clazz "dropdown icon"] [] - Incremental.text title + title ] div [clazz "content"] [ node @@ -689,24 +689,43 @@ module SimplePrimitives = /// Simple container dividing content into titled sections, which can be opened and closed. /// The active set holds the indices of the open sections. /// The toggle (index, isOpen) message is fired when a section is opened or closed. - let accordion (toggle: int * bool -> 'msg) (active: aset) - (attributes: AttributeMap<'msg>) (sections: list * DomNode<'msg>>) = + let accordion' (toggle: int * bool -> 'msg) (active: aset) + (attributes: AttributeMap<'msg>) (sections: list * DomNode<'msg>>) = let cb s i = toggle (i, s) sections |> accordionImpl (AccordionInput.Multi (active, cb)) attributes /// Simple container dividing content into titled sections, which can be opened and closed (only one can be open at a time). /// The active value holds the index of the open section, or -1 if there is no open section. /// The setActive (index | -1) message is fired when a section is opened or closed. - let accordionExclusive (setActive: int -> 'msg) (active: aval) - (attributes: AttributeMap<'msg>) (sections: list * DomNode<'msg>>) = + let accordionExclusive' (setActive: int -> 'msg) (active: aval) + (attributes: AttributeMap<'msg>) (sections: list * DomNode<'msg>>) = let cb s i = (if s then i else -1) |> setActive sections |> accordionImpl (AccordionInput.Single (active, cb)) attributes /// Simple container dividing content into titled sections, which can be opened and closed. /// If exclusive is true, only one section can be open at a time. - let accordionSimple (exclusive: bool) (attributes: AttributeMap<'msg>) (sections: list * DomNode<'msg>>) = + let accordionSimple' (exclusive: bool) (attributes: AttributeMap<'msg>) (sections: list * DomNode<'msg>>) = sections |> accordionImpl (AccordionInput.Empty exclusive) attributes + /// Simple container dividing content into titled sections, which can be opened and closed. + /// The active set holds the indices of the open sections. + /// The toggle (index, isOpen) message is fired when a section is opened or closed. + let accordion (toggle: int * bool -> 'msg) (active: aset) + (attributes: AttributeMap<'msg>) (sections: list * DomNode<'msg>>) = + sections |> List.map (fun (t, c) -> Incremental.text t, c) |> accordion' toggle active attributes + + /// Simple container dividing content into titled sections, which can be opened and closed (only one can be open at a time). + /// The active value holds the index of the open section, or -1 if there is no open section. + /// The setActive (index | -1) message is fired when a section is opened or closed. + let accordionExclusive (setActive: int -> 'msg) (active: aval) + (attributes: AttributeMap<'msg>) (sections: list * DomNode<'msg>>) = + sections |> List.map (fun (t, c) -> Incremental.text t, c) |> accordionExclusive' setActive active attributes + + /// Simple container dividing content into titled sections, which can be opened and closed. + /// If exclusive is true, only one section can be open at a time. + let accordionSimple (exclusive: bool) (attributes: AttributeMap<'msg>) (sections: list * DomNode<'msg>>) = + sections |> List.map (fun (t, c) -> Incremental.text t, c) |> accordionSimple' exclusive attributes + [] module ``Primtive Builders`` = @@ -973,6 +992,28 @@ module SimplePrimitives = (values : amap<'T, DomNode<'msg>>) (selected : alist<'T>) (update : 'T list -> 'msg) = Incremental.dropdownMultiSelect attributes compare defaultText values selected update + /// Simple container dividing content into titled sections, which can be opened and closed. + /// The active set holds the indices of the open sections. + /// The toggle message (index, isOpen) is fired when a section is opened or closed. + let inline accordion' (toggle: int * bool -> 'msg) (active: aset) + (attributes: Attribute<'msg> list) (sections: list * DomNode<'msg>>) = + let attributes = AttributeMap.ofList attributes + sections |> Incremental.accordion' toggle active attributes + + /// Simple container dividing content into titled sections, which can be opened and closed (only one can be open at a time). + /// The active value holds the index of the open section, or -1 if there is no open section. + /// The setActive (index | -1) message is fired when a section is opened or closed. + let inline accordionExclusive' (setActive: int -> 'msg) (active: aval) + (attributes: Attribute<'msg> list) (sections: list * DomNode<'msg>>) = + let attributes = AttributeMap.ofList attributes + sections |> Incremental.accordionExclusive' setActive active attributes + + /// Simple container dividing content into titled sections, which can be opened and closed. + /// If exclusive is true, only one section can be open at a time. + let inline accordionSimple' (exclusive: bool) (attributes: Attribute<'msg> list) (sections: list * DomNode<'msg>>) = + let attributes = AttributeMap.ofList attributes + sections |> Incremental.accordionSimple' exclusive attributes + /// Simple container dividing content into titled sections, which can be opened and closed. /// The active set holds the indices of the open sections. /// The toggle message (index, isOpen) is fired when a section is opened or closed. diff --git a/src/Examples (dotnetcore)/23 - Inputs/App.fs b/src/Examples (dotnetcore)/23 - Inputs/App.fs index 36660ee5..d50953d5 100644 --- a/src/Examples (dotnetcore)/23 - Inputs/App.fs +++ b/src/Examples (dotnetcore)/23 - Inputs/App.fs @@ -83,9 +83,9 @@ let view (model : AdaptiveModel) = ] ] - accordionSimple true [ clazz "inverted item" ] [ + accordionSimple' true [ clazz "inverted item" ] [ // Checkboxes - "Checkboxes", div [ clazz "menu" ] [ + text "Checkboxes", div [ clazz "menu" ] [ div [ clazz "item" ] [ simplecheckbox { attributes [clazz "inverted"] @@ -102,7 +102,7 @@ let view (model : AdaptiveModel) = ] // Sliders - "Sliders", div [ clazz "menu" ] [ + text "Sliders", div [ clazz "menu" ] [ div [ clazz "item" ] [ description "Float" slider { min = 1.0; max = 100.0; step = 0.1 } [clazz "ui inverted red slider"] model.value SetValue @@ -115,7 +115,7 @@ let view (model : AdaptiveModel) = ] // Input fields - "Input fields", div [ clazz "menu" ] [ + text "Input fields", div [ clazz "menu" ] [ div [ clazz "item" ] [ description "Numeric (float)" simplenumeric { @@ -180,7 +180,7 @@ let view (model : AdaptiveModel) = ] // Dropdowns - "Dropdown menus", div [ clazz "menu" ] [ + text "Dropdown menus", div [ clazz "menu" ] [ div [ clazz "item" ] [ description "Non-clearable" dropdownUnclearable [ clazz "inverted selection" ] enumValues model.enumValue SetEnumValue @@ -204,7 +204,17 @@ let view (model : AdaptiveModel) = ] // Color picker - "Color picker", div [ clazz "menu" ] [ + let colorHeader = + span [] [ + text "Color picker" + + Incremental.i (AttributeMap.ofAMap <| amap { + let! c = model.color + yield style $"width: 16px; height: 16px; position: absolute; margin-left: 10px; border: thin solid; background-color: #{c.ToHexString()}" + }) AList.empty + ] + + colorHeader, div [ clazz "menu" ] [ div [ clazz "item" ] [ description "Dropdown variations"