Handle dynamically adding items in list components: Radio Group, Tabs, Listbox, Menu

Fixes #29

Upstream Headless UI handles this for Radio Group but not for the others. I didn't see any reason why not to implement this for the other ones too.
This commit is contained in:
Ryan Gossiaux
2021-12-31 11:46:00 -10:00
parent b5b6854d2d
commit e16e27f04e
10 changed files with 263 additions and 14 deletions

View File

@@ -155,7 +155,31 @@
searchQuery = "";
},
registerOption(id: string, dataRef) {
options = [...options, { id, dataRef }];
if (!$optionsRef) {
// We haven't mounted yet so just append
options = [...options, { id, dataRef }];
return;
}
let currentActiveOption =
activeOptionIndex !== null ? options[activeOptionIndex] : null;
let orderMap = Array.from(
$optionsRef.querySelectorAll('[id^="headlessui-listbox-option-"]')!
).reduce(
(lookup, element, index) =>
Object.assign(lookup, { [element.id]: index }),
{}
) as Record<string, number>;
let nextOptions = [...options, { id, dataRef }];
nextOptions.sort((a, z) => orderMap[a.id] - orderMap[z.id]);
options = nextOptions;
// Maintain the correct item active
activeOptionIndex = (() => {
if (currentActiveOption === null) return null;
return options.indexOf(currentActiveOption);
})();
},
unregisterOption(id: string) {
let nextOptions = options.slice();