Skip to content

Commit

Permalink
[Primitives] Rework dropdown
Browse files Browse the repository at this point in the history
This commit reworks the dropdown implementation. The old
implementation did not allow users to define an explicit order
of the values (amap only). Also the custom TriggerDropdown,
DropdownConfig, and DropdownMode types were unwieldy.
The new API provides a few variants with simple parameters.
  • Loading branch information
hyazinthh committed May 8, 2024
1 parent 05c72d0 commit 20a5c81
Show file tree
Hide file tree
Showing 10 changed files with 444 additions and 377 deletions.
1 change: 1 addition & 0 deletions src/Aardvark.UI.Primitives/Aardvark.UI.Primitives.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
<EmbeddedResource Include="resources\spectrum-overrides.css" />
<EmbeddedResource Include="resources\notifications.js" />
<EmbeddedResource Include="resources\accordion.js" />
<EmbeddedResource Include="resources\dropdown.js" />
<None Include="paket.references" />
</ItemGroup>
<ItemGroup>
Expand Down
455 changes: 249 additions & 206 deletions src/Aardvark.UI.Primitives/Primitives/SimplePrimitives.fs

Large diffs are not rendered by default.

28 changes: 4 additions & 24 deletions src/Aardvark.UI.Primitives/Primitives/UI.Primitives.Simple.fs
Original file line number Diff line number Diff line change
Expand Up @@ -215,31 +215,11 @@ module Simple =
let largeTextArea (changed : string -> 'msg) (value : aval<string>) =
largeTextArea' changed value AttributeMap.empty

[<System.Obsolete("Use Dropdown.dropdown instead. Make sure to add the Aardvark.UI.Primitives WebPart.")>]
let dropDown<'a, 'msg when 'a : comparison and 'a : equality> (att : list<string * AttributeValue<'msg>>) (current : aval<'a>) (update : 'a -> 'msg) (names : Map<'a, string>) : DomNode<'msg> =

let mutable back = Map.empty
let forth =
names |> Map.map (fun a s ->
let id = System.Guid.NewGuid()
back <- Map.add id a back
id
)

let selectedValue = current |> AVal.map (fun c -> Map.find c forth)

let boot =
String.concat "\r\n" [
sprintf "$('#__ID__').dropdown().dropdown('set selected', '%s');" (string (AVal.force selectedValue))
"current.onmessage = function(v) { $('#__ID__').dropdown('set selected', v); };"
]

onBoot' ["current", AVal.channel selectedValue] boot (
select ((onChange (fun str -> Map.find (str |> System.Guid.Parse) back |> update))::att) [
for (value, name) in Map.toSeq names do
let v = Map.find value forth
yield option [attribute "value" (string v)] [ text name ]
]
)
let values: seq<'a * DomNode<'msg>> = names |> Seq.map (fun (KeyValue(value, str)) -> value, text str)
Dropdown.dropdown update false None current att values

[<System.Obsolete("Broken. To be removed.")>]
let allValues<'a when 'a : comparison> =
FSharpType.GetUnionCases(typeof<'a>,true) |> Array.map (fun c -> unbox<'a>(FSharpValue.MakeUnion(c, [||], true)), c.Name) |> Map.ofArray
40 changes: 40 additions & 0 deletions src/Aardvark.UI.Primitives/resources/dropdown.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
if (!aardvark.dropdown) {
/**
* @param {*} x
* @param {*} y
*/
function arraysIdentical(x, y) {
const a = Array.isArray(x) ? x : [x];
const b = Array.isArray(y) ? y : [y];
let i = a.length;
if (i != b.length) return false;
while (i--) {
if (a[i] !== b[i]) return false;
}
return true;
};

/**
* @param {HTMLElement[]} $self
* @param {string} trigger
* @param {{onmessage: function}} channel
*/
aardvark.dropdown = function ($self, trigger, channel) {
$self.dropdown({
on: trigger,
onChange: function (value) { aardvark.processEvent($self[0].id, 'data-event', value); }
});

channel.onmessage = function(values) {
const curr = $self.dropdown('get values');

// Prevent resetting the same values (leads to flickering)
if (arraysIdentical(curr, values)) {
return;
}

$self.dropdown('clear', true);
$self.dropdown('set selected', values, true); // set exactly bugged? clear seems to trigger event
};
};
}
Loading

0 comments on commit 20a5c81

Please sign in to comment.