Use tags and aliases when filtering icons in Icon Picker (#10425)

This commit is contained in:
Paul Bottein 2021-10-27 22:12:12 +02:00 committed by GitHub
parent 10986db7c6
commit 74533cebc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 13 deletions

View File

@ -26,6 +26,7 @@ const getMeta = () => {
path: svg.match(/ d="([^"]+)"/)[1], path: svg.match(/ d="([^"]+)"/)[1],
name: icon.name, name: icon.name,
tags: icon.tags, tags: icon.tags,
aliases: icon.aliases,
}; };
}); });
}; };
@ -37,6 +38,7 @@ const addRemovedMeta = (meta) => {
path: removeIcon.path, path: removeIcon.path,
name: removeIcon.name, name: removeIcon.name,
tags: [], tags: [],
aliases: [],
})); }));
const combinedMeta = [...meta, ...removedMeta]; const combinedMeta = [...meta, ...removedMeta];
return combinedMeta.sort((a, b) => a.name.localeCompare(b.name)); return combinedMeta.sort((a, b) => a.name.localeCompare(b.name));
@ -141,7 +143,15 @@ gulp.task("gen-icons-json", (done) => {
fs.writeFileSync( fs.writeFileSync(
path.resolve(OUTPUT_DIR, "iconList.json"), path.resolve(OUTPUT_DIR, "iconList.json"),
JSON.stringify(orderMeta(meta).map((icon) => icon.name)) JSON.stringify(
orderMeta(meta).map((icon) => ({
name: icon.name,
keywords: [
...icon.tags.map((t) => t.toLowerCase().replace(/\s\/\s/g, " ")),
...icon.aliases,
],
}))
)
); );
done(); done();

View File

@ -11,10 +11,14 @@ import { PolymerChangedEvent } from "../polymer-types";
import "./ha-icon"; import "./ha-icon";
import "./ha-icon-button"; import "./ha-icon-button";
let mdiIconList: string[] = []; type IconItem = {
icon: string;
keywords: string[];
};
let iconItems: IconItem[] = [];
// eslint-disable-next-line lit/prefer-static-styles // eslint-disable-next-line lit/prefer-static-styles
const rowRenderer: ComboBoxLitRenderer<string> = (item) => html`<style> const rowRenderer: ComboBoxLitRenderer<IconItem> = (item) => html`<style>
paper-icon-item { paper-icon-item {
padding: 0; padding: 0;
margin: -8px; margin: -8px;
@ -37,8 +41,8 @@ const rowRenderer: ComboBoxLitRenderer<string> = (item) => html`<style>
<ha-svg-icon .path=${mdiCheck}></ha-svg-icon> <ha-svg-icon .path=${mdiCheck}></ha-svg-icon>
<paper-icon-item> <paper-icon-item>
<ha-icon .icon=${item} slot="item-icon"></ha-icon> <ha-icon .icon=${item.icon} slot="item-icon"></ha-icon>
<paper-item-body>${item}</paper-item-body> <paper-item-body>${item.icon}</paper-item-body>
</paper-icon-item>`; </paper-icon-item>`;
@customElement("ha-icon-picker") @customElement("ha-icon-picker")
@ -66,7 +70,7 @@ export class HaIconPicker extends LitElement {
item-label-path="icon" item-label-path="icon"
.value=${this._value} .value=${this._value}
allow-custom-value allow-custom-value
.filteredItems=${mdiIconList} .filteredItems=${iconItems}
${comboBoxRenderer(rowRenderer)} ${comboBoxRenderer(rowRenderer)}
@opened-changed=${this._openedChanged} @opened-changed=${this._openedChanged}
@value-changed=${this._valueChanged} @value-changed=${this._valueChanged}
@ -105,10 +109,13 @@ export class HaIconPicker extends LitElement {
private async _openedChanged(ev: PolymerChangedEvent<boolean>) { private async _openedChanged(ev: PolymerChangedEvent<boolean>) {
this._opened = ev.detail.value; this._opened = ev.detail.value;
if (this._opened && !mdiIconList.length) { if (this._opened && !iconItems.length) {
const iconList = await import("../../build/mdi/iconList.json"); const iconList = await import("../../build/mdi/iconList.json");
mdiIconList = iconList.default.map((icon) => `mdi:${icon}`); iconItems = iconList.default.map((icon) => ({
(this.comboBox as any).filteredItems = mdiIconList; icon: `mdi:${icon.name}`,
keywords: icon.keywords,
}));
(this.comboBox as any).filteredItems = iconItems;
} }
} }
@ -133,16 +140,28 @@ export class HaIconPicker extends LitElement {
const filterString = ev.detail.value.toLowerCase(); const filterString = ev.detail.value.toLowerCase();
const characterCount = filterString.length; const characterCount = filterString.length;
if (characterCount >= 2) { if (characterCount >= 2) {
const filteredItems = mdiIconList.filter((icon) => const filteredItems: IconItem[] = [];
icon.includes(filterString) const filteredItemsByKeywords: IconItem[] = [];
);
iconItems.forEach((item) => {
if (item.icon.includes(filterString)) {
filteredItems.push(item);
return;
}
if (item.keywords.some((t) => t.includes(filterString))) {
filteredItemsByKeywords.push(item);
}
});
filteredItems.push(...filteredItemsByKeywords);
if (filteredItems.length > 0) { if (filteredItems.length > 0) {
(this.comboBox as any).filteredItems = filteredItems; (this.comboBox as any).filteredItems = filteredItems;
} else { } else {
(this.comboBox as any).filteredItems = [filterString]; (this.comboBox as any).filteredItems = [filterString];
} }
} else { } else {
(this.comboBox as any).filteredItems = mdiIconList; (this.comboBox as any).filteredItems = iconItems;
} }
} }