Skip to content

Commit

Permalink
Merge pull request #152 from exadel-inc/bugfix/select-empty-option
Browse files Browse the repository at this point in the history
Bugfix/UIPSelectSetting: empty option processing
  • Loading branch information
Sisha0 authored Nov 18, 2021
2 parents 456c2ff + ab525c4 commit 23f315d
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import {attr, boolAttr} from '@exadel/esl/modules/esl-base-element/core';
import type {ESLSelect} from '@exadel/esl/modules/esl-forms/esl-select/core';
import {randUID} from '@exadel/esl/modules/esl-utils/misc/uid';
import {memoize} from '@exadel/esl/modules/esl-utils/decorators/memoize';

import {UIPSetting} from '../setting';
import {ChangeAttrConfig, UIPStateModel} from '../../../../../core/registration';
import {ChangeAttrConfig, UIPStateModel} from '../../../../../core/base/model';
import TokenListUtils from '../../../../../utils/token-list-utils';
import {WARNING_MSG} from '../../../../../utils/warning-msg';

import type {ESLSelect} from '@exadel/esl/modules/esl-forms/esl-select/core';

/**
* Custom setting for selecting attribute's value.
* @extends UIPSetting
Expand All @@ -30,6 +30,7 @@ export class UIPSelectSetting extends UIPSetting {
/** Select field to change setting's value. */
protected $field: ESLSelect;

@memoize()
protected get settingOptions(): string[] {
return this.$field.options.map(opt => opt.value);
}
Expand Down Expand Up @@ -112,10 +113,18 @@ export class UIPSelectSetting extends UIPSetting {
return this.multiple ? this.setValue('') : this.setInconsistency(WARNING_MSG.noMatch);
}

/** Update setting's value for append {@link mode}. */
/** Update setting's value for {@link mode} = "append". */
protected updateAppend(attrValues: (string | null)[]): void {
const commonOptions = TokenListUtils.intersection(
...attrValues.map(val => TokenListUtils.split(val)), this.settingOptions);
// array of each attribute's value intersection with select options
const valuesOptions = attrValues.map(val => TokenListUtils.intersection(this.settingOptions, TokenListUtils.split(val)));

// make empty option active if no options intersections among attribute values
if (this.settingOptions.includes('') && valuesOptions.every(inter => !inter.length)) {
return this.setValue('');
}

// common options among all attribute values
const commonOptions = TokenListUtils.intersection(...valuesOptions);

if (this.multiple || commonOptions.length) return this.setValue(TokenListUtils.join(commonOptions));

Expand Down
9 changes: 4 additions & 5 deletions src/utils/token-list-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,10 @@ export default class TokenListUtils {
}

/** Get array which contains only common elements from arrays. */
static intersection<T>(...arrays: T[][]): T[] {
return Array.from(arrays.reduce((intersect, arr) => {
arr.forEach(val => !intersect.has(val) && intersect.delete(val));
return intersect;
}, new Set(arrays[0])));
static intersection<T>(...rest: T[][]): T[];
static intersection<T>(a: T[], b: T[], ...rest: T[][]): T[] {
if (rest.length) return TokenListUtils.intersection(a, TokenListUtils.intersection(b, ...rest));
return a.filter(Set.prototype.has, new Set(b));
}

/** Remove all element appearances from array. */
Expand Down

0 comments on commit 23f315d

Please sign in to comment.