fix(ui): defer select options and omit unused selection tags
This commit is contained in:
1 parent
61a4f01321
commit
9d90418490
4 files changed
+62
-6
No files matched your search
@@ -688,7 +688,7 @@
|
||||
},
|
||||
"packages/ui": {
|
||||
"name": "@wrnexus/ui",
|
||||
"version": "0.8.63",
|
||||
"version": "0.8.64",
|
||||
"dependencies": {
|
||||
"@wrnexus/core": "workspace:*",
|
||||
},
|
||||
|
||||
@@ -304,7 +304,7 @@ component AdvancedSelect {
|
||||
aria-label="{selectedOptionsLabel}"
|
||||
data-show="multiple && selectedTemplate !== 'count' && selectedTemplate !== 'text' && selectedCount() > 0"
|
||||
>
|
||||
{#each allOptions() as option}
|
||||
{#each multiple && selectedTemplate !== 'count' && selectedTemplate !== 'text' ? selectedOptions() : [] as option}
|
||||
<span data-show="isSelected(option)">
|
||||
{#if optionTemplate === "icon" && option.icon}<i class="{option.icon}" aria-hidden="true"></i>{/if}
|
||||
{#if optionTemplate === "avatar" && option.avatar}<img src="{option.avatar}" alt="" />{/if}
|
||||
@@ -371,7 +371,7 @@ component AdvancedSelect {
|
||||
role="listbox"
|
||||
aria-multiselectable="{multiple}"
|
||||
>
|
||||
{#each groups as group}
|
||||
{#each open ? groups : [] as group}
|
||||
{#if visibleOptions(group.options || []).length}
|
||||
<div class="wrn-next__option-group" role="group" aria-label="{group.label}">
|
||||
<div class="wrn-next__group-label">{group.label}</div>
|
||||
@@ -402,7 +402,7 @@ component AdvancedSelect {
|
||||
{/if}
|
||||
{/each}
|
||||
|
||||
{#each visibleOptions(options) as option}
|
||||
{#each open ? visibleOptions(options) : [] as option}
|
||||
<button
|
||||
type="button"
|
||||
class="wrn-next__select-option {isSelected(option) ? 'wrn-next__select-option--selected' : ''} {optionIndex(option) === activeIndex ? 'wrn-next__select-option--active' : ''}"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/ui",
|
||||
"version": "0.8.63",
|
||||
"version": "0.8.64",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "src/index.ts",
|
||||
|
||||
@@ -1910,6 +1910,61 @@ test("input number increments, decrements, applies steps, and respects limits",
|
||||
expect(decrement().disabled).toBe(true);
|
||||
});
|
||||
|
||||
test("advanced select keeps large closed lists compact and renders only selected tags", async () => {
|
||||
const source = readFileSync(uiComponentPath("AdvancedSelect"), "utf8");
|
||||
const options = Array.from({ length: 420 }, (_, i) => ({
|
||||
value: String(i),
|
||||
label: "Option " + i,
|
||||
}));
|
||||
const html = await renderComponent(source, {
|
||||
name: "large",
|
||||
value: "419",
|
||||
options,
|
||||
searchResultLimit: 40,
|
||||
});
|
||||
expect(Buffer.byteLength(html)).toBeLessThan(120_000);
|
||||
const dom = mountHtml(html);
|
||||
expect(dom.querySelectorAll(".wrn-next__select-option")).toHaveLength(0);
|
||||
expect(dom.querySelectorAll(".wrn-next__select-tags > span")).toHaveLength(0);
|
||||
expect(dom.querySelector(".wrn-next__select-value")?.textContent).toContain("Option 419");
|
||||
(dom.querySelector(".wrn-next__select-trigger") as HTMLButtonElement).click();
|
||||
expect(dom.querySelectorAll(".wrn-next__select-option")).toHaveLength(40);
|
||||
(dom.querySelector(".wrn-next__select-trigger") as HTMLButtonElement).click();
|
||||
expect(dom.querySelectorAll(".wrn-next__select-option")).toHaveLength(0);
|
||||
|
||||
const multi = mountHtml(
|
||||
await renderComponent(source, {
|
||||
name: "selected-tags",
|
||||
multiple: true,
|
||||
values: ["419"],
|
||||
options,
|
||||
searchResultLimit: 4,
|
||||
}),
|
||||
);
|
||||
expect(multi.querySelectorAll(".wrn-next__select-tags > span")).toHaveLength(1);
|
||||
expect(multi.querySelector(".wrn-next__select-tags")?.textContent).toContain("Option 419");
|
||||
(multi.querySelector(".wrn-next__select-trigger") as HTMLButtonElement).click();
|
||||
(multi.querySelector(".wrn-next__select-option") as HTMLButtonElement).click();
|
||||
expect(multi.querySelectorAll(".wrn-next__select-tags > span")).toHaveLength(2);
|
||||
(multi.querySelector(".wrn-next__clear-select") as HTMLButtonElement).click();
|
||||
expect(multi.querySelectorAll(".wrn-next__select-tags > span")).toHaveLength(0);
|
||||
});
|
||||
|
||||
test("advanced select lazily opens grouped options and honors defaultOpen", async () => {
|
||||
const source = readFileSync(uiComponentPath("AdvancedSelect"), "utf8");
|
||||
const groups = [{ label: "Regions", options: [{ value: "in", label: "India" }] }];
|
||||
const dom = mountHtml(await renderComponent(source, { name: "grouped", groups }));
|
||||
expect(dom.querySelectorAll(".wrn-next__option-group")).toHaveLength(0);
|
||||
(dom.querySelector(".wrn-next__select-trigger") as HTMLButtonElement).click();
|
||||
expect(dom.querySelectorAll(".wrn-next__option-group")).toHaveLength(1);
|
||||
(dom.querySelector(".wrn-next__select-option") as HTMLButtonElement).click();
|
||||
expect((dom.querySelector('input[type="hidden"]') as HTMLInputElement).value).toBe("in");
|
||||
const opened = mountHtml(
|
||||
await renderComponent(source, { name: "opened", groups, defaultOpen: true }),
|
||||
);
|
||||
expect(opened.querySelectorAll(".wrn-next__select-option")).toHaveLength(1);
|
||||
});
|
||||
|
||||
test("advanced select limits rendered options but searches the full dataset and retains saved values", async () => {
|
||||
const source = readFileSync(uiComponentPath("AdvancedSelect"), "utf8");
|
||||
const dom = mountHtml(
|
||||
@@ -1921,8 +1976,9 @@ test("advanced select limits rendered options but searches the full dataset and
|
||||
}),
|
||||
);
|
||||
expect(dom.querySelector(".wrn-next__select-value")?.textContent).toContain("Region 99");
|
||||
expect(dom.querySelectorAll(".wrn-next__select-option")).toHaveLength(4);
|
||||
expect(dom.querySelectorAll(".wrn-next__select-option")).toHaveLength(0);
|
||||
(dom.querySelector(".wrn-next__select-trigger") as HTMLButtonElement).click();
|
||||
expect(dom.querySelectorAll(".wrn-next__select-option")).toHaveLength(4);
|
||||
const search = dom.querySelector('input[type="search"]') as HTMLInputElement;
|
||||
search.value = "Region 99";
|
||||
search.dispatchEvent(new (dom.window as any).Event("input", { bubbles: true }));
|
||||
|
||||
Reference in new issue
Block a user