Skip to content

Commit

Permalink
fix(select): change label on slot change
Browse files Browse the repository at this point in the history
  • Loading branch information
aesteves60 committed Oct 5, 2023
1 parent 021d89f commit 1752902
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import type { OdsSelectOptionAttribute } from './interfaces/attributes';
import type { OdsSelectOptionEvent, OdsSelectOptionClickEventDetail } from './interfaces/events';
import type { OdsSelectOptionMethod } from './interfaces/methods';
import type { OsdsSelect } from '../osds-select/osds-select';
import { Component, Element, Event, EventEmitter, Host, Method, Prop, State, Watch, h } from '@stencil/core';
import { OdsLogger } from '@ovhcloud/ods-common-core';
import { Component, Element, Event, EventEmitter, Host, Method, Prop, State, h } from '@stencil/core';
import { DEFAULT_ATTRIBUTE as SELECT_DEFAULT_ATTRIBUTE } from '../osds-select/constants/default-attributes';
import { DEFAULT_ATTRIBUTE } from './constants/default-attributes';

Expand All @@ -18,7 +17,6 @@ import { DEFAULT_ATTRIBUTE } from './constants/default-attributes';
shadow: true,
})
export class OsdsSelectOption implements OdsSelectOptionAttribute, OdsSelectOptionEvent, OdsSelectOptionMethod {
private logger = new OdsLogger('OsdsSelectOption');
private selectParent: (HTMLStencilElement & OsdsSelect) | null = null;

@Element() el!: HTMLStencilElement;
Expand Down Expand Up @@ -73,23 +71,12 @@ export class OsdsSelectOption implements OdsSelectOptionAttribute, OdsSelectOpti
return this.el.innerText;
}

@Watch('value')
watchValue(value: OdsInputValue) {
this.logger.log(`[select=${this.value}]`, 'value changed', { value });
}

@Watch('selected')
updateSelectGroupValue(selected: boolean) {
this.logger.log(`[select=${this.value}]`, 'selected changed.', { selected });
}

emitClick(value: OdsInputValue) {
this.odsSelectOptionClick.emit({ value });
}

handleClick(event: MouseEvent) {
event.stopPropagation();
this.logger.log(`[select=${this.value}]`, 'option clicked.');
this.emitClick(this.value);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,20 @@ describe('e2e:osds-select', () => {

expect(selectedLabel).toBe(null);
});

it('should change the selected value text', async () => {
await setup({ attributes: { value: '42' } });
await page.waitForChanges();

const options = await page.findAll('osds-select > osds-select-option');
options.forEach((option) => {
option.innerHTML = `NewValue${option.getAttribute('value')}`
});
await page.waitForChanges();

const label = await page.find('osds-select >>> .select-trigger__label');
expect(label.innerText.trim()).toBe('NewValue42');
});
});

// TODO getValidity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ import { DEFAULT_VALIDITY_STATE } from './constants/default-validity-state';
import { ODS_SELECT_SIZE } from './constants/select-size';
import { OsdsSelect } from './osds-select';

const mutationObserverMock = jest.fn(function MutationObserver(callback) {
this.observe = jest.fn();
this.disconnect = jest.fn();
// Optionally add a trigger() method to manually trigger a change
this.trigger = (mockedMutationsList) => {
callback(mockedMutationsList, this);
};
});
// @ts-ignore
global.MutationObserver = mutationObserverMock;

const logger = new OdsLogger('osds-select-spec');

// mock validity property that does not exist when stencil mock HTMLInputElement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import type { ODS_SELECT_SIZE } from './constants/select-size';
import type { OsdsSelectOption } from '../osds-select-option/osds-select-option';
import type { OdsSelectOptionClickEventDetail } from '../osds-select-option/interfaces/events';
import { Component, Element, Event, EventEmitter, Host, Listen, Method, Prop, State, Watch, h } from '@stencil/core';
import { OdsLogger } from '@ovhcloud/ods-common-core';
import { ODS_ICON_NAME, ODS_ICON_SIZE } from '@ovhcloud/ods-component-icon';
import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming';
import { ocdkAssertEventTargetIsNode, ocdkDefineCustomElements, ocdkIsSurface } from '@ovhcloud/ods-cdk';
Expand All @@ -28,13 +27,13 @@ ocdkDefineCustomElements()
shadow: true,
})
export class OsdsSelect implements OdsSelectAttribute, OdsSelectEvent, OdsSelectMethod {
private logger = new OdsLogger('OsdsSelect');
controller: OdsSelectController = new OdsSelectController(this);
anchor!: HTMLElement;
surface: OcdkSurface | undefined = undefined;
/** is the select was touched by the user */
dirty = false;
selectedLabelSlot: HTMLElement | null = null;
observer?: MutationObserver = undefined;

@Element() el!: HTMLStencilElement;

Expand Down Expand Up @@ -103,14 +102,17 @@ export class OsdsSelect implements OdsSelectAttribute, OdsSelectEvent, OdsSelect
}

componentWillLoad() {
this.onDefaultValueChange();
if (this.value === '' && this.defaultValue !== undefined) {
this.value = this.defaultValue;
}
this.openedChanged(this.opened);
this.selectedLabelSlot = this.el.querySelector('[slot="selectedLabel"]');
}

disconnectedCallback(): void {
this.observer?.disconnect();
}

/**
* once the component did load, update the state depending the children,
* in order to synchronize the already set value with the placeholder
Expand All @@ -120,11 +122,6 @@ export class OsdsSelect implements OdsSelectAttribute, OdsSelectEvent, OdsSelect
await this.updateSelectOptionStates(this.value);
}

@Watch('defaultValue')
onDefaultValueChange(defaultValue?: OdsInputValue) {
this.logger.debug(`[input=${this.value}]`, 'defaultValue', defaultValue);
}

@Watch('opened')
openedChanged(opened: boolean) {
if (this.surface) {
Expand All @@ -134,13 +131,11 @@ export class OsdsSelect implements OdsSelectAttribute, OdsSelectEvent, OdsSelect

@Watch('value')
async onValueChange(value: OdsInputValue, oldValue?: OdsInputValue) {
this.logger.log(`[onValueChange=${this.value}]`, 'value changed. emit new value', { value });
this.emitChange(value, oldValue);
await this.updateSelectOptionStates(value);
}

private emitChange(value: OdsInputValue, oldValue?: OdsInputValue) {
this.logger.debug('emit', { value, oldValue });
this.odsValueChange.emit({
value: value,
oldValue: oldValue,
Expand Down Expand Up @@ -225,13 +220,11 @@ export class OsdsSelect implements OdsSelectAttribute, OdsSelectEvent, OdsSelect
}

changeValue(value: OdsInputValue) {
this.logger.log(`[changeValue=${this.value}]`, 'value changed', { value });
this.value = value;
}

// Toggle overlay when we click on the Select.
handleSelectClick(): void {
this.logger.log('[handleSelectClick]', arguments, { validity: this.validityState });
if (this.disabled) {
return;
}
Expand All @@ -250,7 +243,6 @@ export class OsdsSelect implements OdsSelectAttribute, OdsSelectEvent, OdsSelect
if (!this.dirty || this.surface?.isClickOutsideSurface(ev)) {
return;
}
this.logger.log('[checkForClickOutside]', arguments, { validity: this.validityState });
this.controller.closeSurface();

this.controller.selectOptions.forEach((option) => {
Expand All @@ -268,7 +260,6 @@ export class OsdsSelect implements OdsSelectAttribute, OdsSelectEvent, OdsSelect

@Listen('odsSelectOptionClick')
handleValueChange(event: CustomEvent<OdsSelectOptionClickEventDetail>): void {
this.logger.log(`[odsSelectOptionClick=${this.value}]`, 'received odsSelectOptionClick event', { detail: event.detail });
this.changeValue(event.detail.value);
this.controller.closeSurface();
}
Expand All @@ -284,12 +275,15 @@ export class OsdsSelect implements OdsSelectAttribute, OdsSelectEvent, OdsSelect
this.controller.syncReferences()
}

handleSlotChange() {
async handleSlotChange(): Promise<void> {
this.setSelectOptions();
await this.updateSelectOptionStates();
}

setSelectOptions() {
this.controller.selectOptions = this.getSelectOptionList();
this.observer = new MutationObserver(async() => await this.updateSelectOptionStates(this.value));
this.controller.selectOptions.forEach((option) => this.observer?.observe(option, { childList: true }))
}

getSelectOptionList(): (HTMLElement & OsdsSelectOption)[] {
Expand Down
5 changes: 5 additions & 0 deletions packages/components/select/src/global.dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ Object.keys(examples).forEach(k => {
// todo
// examples.select1.component && (examples.select1.component.opened = !examples.select1.component.opened);
// evt.stopPropagation()
const options = document.querySelectorAll('#select1 > osds-select-option');
options.forEach((option) => {
option.innerHTML = `NewValue${option.getAttribute('value')}`;
});
// const select = document.querySelector('#select1');
};

(window as any).select6Clear = function () {
Expand Down

0 comments on commit 1752902

Please sign in to comment.