Skip to content

Commit

Permalink
Add value property and value-changed event to combobox
Browse files Browse the repository at this point in the history
This CL adds `value` as a bound property, which changes the UI to
select the option associated with the `value`, and adds a
`value-changed` for when the user selects an option from the dropdown
using mouse or key.

Also updates demo to one of the descriptors for better demoing.

Bug: b/301017714
Change-Id: I48db8bb0683c665724e755c3dc98b70b67781d3a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4944951
Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com>
Commit-Queue: John Lee <johntlee@chromium.org>
Reviewed-by: Riley Tatum <rtatum@google.com>
Cr-Commit-Position: refs/heads/main@{#1210648}
  • Loading branch information
John Lee authored and Chromium LUCI CQ committed Oct 17, 2023
1 parent 91f5d94 commit 178346a
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const HIGHLIGHTABLE_ITEMS_SELECTOR = '[role=group], [role=option]';
/* Selector for selectable options in the dropdown. */
const SELECTABLE_ITEMS_SELECTOR = '[role=option]';

export type OptionElement = HTMLElement&{value?: string};

export interface CustomizeChromeCombobox {
$: {
input: HTMLDivElement,
Expand All @@ -40,7 +42,15 @@ export class CustomizeChromeCombobox extends PolymerElement {
observer: 'onExpandedChange_',
},
label: String,
selectedElement_: Object,
selectedElement_: {
type: Object,
observer: 'onSelectedElementChanged_',
},
value: {
type: String,
notify: true,
observer: 'onValueChanged_',
},
};
}

Expand All @@ -49,7 +59,8 @@ export class CustomizeChromeCombobox extends PolymerElement {
private highlightedElement_: HTMLElement|null = null;
label: string;
private domObserver_: MutationObserver|null = null;
private selectedElement_: HTMLElement|null = null;
private selectedElement_: OptionElement|null = null;
value: string|undefined;

override connectedCallback() {
super.connectedCallback();
Expand Down Expand Up @@ -215,6 +226,32 @@ export class CustomizeChromeCombobox extends PolymerElement {
this.highlightElement_(this.highlightableElements_[index]!);
}

private onSelectedElementChanged_() {
if (!this.selectedElement_) {
this.value = undefined;
return;
}

this.value = this.selectedElement_.value;
}

private onValueChanged_() {
if (!this.value) {
return;
}

if (this.selectedElement_ && this.selectedElement_.value === this.value) {
// Selected element matches the value. Nothing left to do.
return;
}

this.selectItem_(
(Array.from(this.querySelectorAll(SELECTABLE_ITEMS_SELECTOR)) as
OptionElement[])
.find(option => option.value === this.value) ||
null);
}

private selectItem_(item: HTMLElement|null): boolean {
if (!item) {
return false;
Expand All @@ -229,7 +266,7 @@ export class CustomizeChromeCombobox extends PolymerElement {
}

item.toggleAttribute('selected', true);
this.selectedElement_ = item;
this.selectedElement_ = item as OptionElement;
return true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,17 +143,15 @@ <h2 slot="heading">Wallpaper Search</h2>
</div>

<!-- demo -->
<customize-chrome-combobox label="My label">
<div role="group">
Group 1
<div role="option">Option 1</div>
<div role="option">Option 2</div>
<div role="option">Option 3</div>
</div>
<div role="group">
Group 2
<div role="option">Option 4</div>
<div role="option">Option 5</div>
<div role="option">Option 6</div>
</div>
<customize-chrome-combobox id="combobox" label="Descriptor A"
value="[[selectedDescriptorA_]]"
on-value-changed="onComboboxDemoChange_">
<template is="dom-repeat" items="[[descriptors_.descriptorA]]">
<div role="group">
[[item.category]]
<template is="dom-repeat" items="[[item.labels]]">
<div role="option" value="[[item]]">[[item]]</div>
</template>
</div>
</template>
</customize-chrome-combobox>
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_butto
import {assert} from 'chrome://resources/js/assert.js';
import {DomRepeatEvent, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';

import {CustomizeChromeCombobox} from './combobox/customize_chrome_combobox.js';
import {CustomizeChromePageHandlerInterface, DescriptorA, DescriptorB, Descriptors, WallpaperSearchResult} from './customize_chrome.mojom-webui.js';
import {CustomizeChromeApiProxy} from './customize_chrome_api_proxy.js';
import {getTemplate} from './wallpaper_search.html.js';

export interface WallpaperSearchElement {
$: {
combobox: CustomizeChromeCombobox,
descriptorMenuA: CrActionMenuElement,
descriptorMenuB: CrActionMenuElement,
descriptorMenuC: CrActionMenuElement,
Expand Down Expand Up @@ -84,6 +86,10 @@ export class WallpaperSearchElement extends PolymerElement {
this.dispatchEvent(new Event('back-click'));
}

private onComboboxDemoChange_() {
this.selectedDescriptorA_ = this.$.combobox.value || null;
}

private onDescriptorLabelClickA_(e: DomRepeatEvent<string>) {
this.selectedDescriptorA_ = e.model.item;
this.$.descriptorMenuA.close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

import 'chrome://customize-chrome-side-panel.top-chrome/combobox/customize_chrome_combobox.js';

import {CustomizeChromeCombobox} from 'chrome://customize-chrome-side-panel.top-chrome/combobox/customize_chrome_combobox.js';
import {CustomizeChromeCombobox, OptionElement} from 'chrome://customize-chrome-side-panel.top-chrome/combobox/customize_chrome_combobox.js';
import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
import {isVisible} from 'chrome://webui-test/test_util.js';
import {eventToPromise, isVisible} from 'chrome://webui-test/test_util.js';

suite('ComboboxTest', () => {
let combobox: CustomizeChromeCombobox;
Expand All @@ -19,10 +19,11 @@ suite('ComboboxTest', () => {
return group;
}

function addOption(parent: HTMLElement = combobox): HTMLElement {
const option = document.createElement('div');
function addOption(parent: HTMLElement = combobox): OptionElement {
const option = document.createElement('div') as OptionElement;
option.setAttribute('role', 'option');
option.innerText = 'Option';
option.value = 'value';
parent.appendChild(option);
return option;
}
Expand Down Expand Up @@ -140,4 +141,39 @@ suite('ComboboxTest', () => {
assertTrue(optionA2.hasAttribute('selected'));
assertTrue(isVisible(combobox.$.dropdown));
});

test('NotifiesValueChange', async () => {
const option1 = addOption();
option1.value = 'option-1-value';
const option2 = addOption();
option2.value = 'option-2-value';

let valueChangeEvent = eventToPromise('value-changed', combobox);
combobox.$.input.click();
option1.dispatchEvent(new Event('click', {composed: true, bubbles: true}));
await valueChangeEvent;
assertEquals('option-1-value', combobox.value);
assertTrue(option1.hasAttribute('selected'));

valueChangeEvent = eventToPromise('value-changed', combobox);
combobox.$.input.click();
option2.dispatchEvent(new Event('click', {composed: true, bubbles: true}));
assertEquals('option-2-value', combobox.value);
assertTrue(option2.hasAttribute('selected'));
});

test('UpdatesWithBoundValue', async () => {
const option1 = addOption();
option1.value = 'option-1-value';
const option2 = addOption();
option2.value = 'option-2-value';

combobox.value = 'option-1-value';
assertTrue(option1.hasAttribute('selected'));
assertFalse(option2.hasAttribute('selected'));

combobox.value = 'option-2-value';
assertFalse(option1.hasAttribute('selected'));
assertTrue(option2.hasAttribute('selected'));
});
});

0 comments on commit 178346a

Please sign in to comment.