mirror of
https://github.com/codex-team/editor.js
synced 2024-06-10 09:52:36 +02:00
b1b582b150
* chore(icons): migrating to the coded icon pack * conversion toolbar * inline toolbar, part 1 * inline-link tool has the new icons * added a test for creating a link by Enter keydown in link input * rm last icons, svg sprite, loaders * rollback .ce-settings styles * Update CHANGELOG.md * Update settings.json
154 lines
3.1 KiB
TypeScript
154 lines
3.1 KiB
TypeScript
import Dom from '../dom';
|
|
import Listeners from './listeners';
|
|
import { IconSearch } from '@codexteam/icons';
|
|
|
|
/**
|
|
* Item that could be searched
|
|
*/
|
|
interface SearchableItem {
|
|
label: string;
|
|
}
|
|
|
|
/**
|
|
* Provides search input element and search logic
|
|
*/
|
|
export default class SearchInput {
|
|
/**
|
|
* Input wrapper element
|
|
*/
|
|
private wrapper: HTMLElement;
|
|
|
|
/**
|
|
* Editable input itself
|
|
*/
|
|
private input: HTMLInputElement;
|
|
|
|
/**
|
|
* The instance of the Listeners util
|
|
*/
|
|
private listeners: Listeners;
|
|
|
|
/**
|
|
* Items for local search
|
|
*/
|
|
private items: SearchableItem[];
|
|
|
|
/**
|
|
* Current search query
|
|
*/
|
|
private searchQuery: string;
|
|
|
|
/**
|
|
* Externally passed callback for the search
|
|
*/
|
|
private readonly onSearch: (items: SearchableItem[]) => void;
|
|
|
|
/**
|
|
* Styles
|
|
*/
|
|
private static get CSS(): {
|
|
input: string;
|
|
icon: string;
|
|
wrapper: string;
|
|
} {
|
|
return {
|
|
wrapper: 'cdx-search-field',
|
|
icon: 'cdx-search-field__icon',
|
|
input: 'cdx-search-field__input',
|
|
};
|
|
}
|
|
|
|
/**
|
|
* @param options - available config
|
|
* @param options.items - searchable items list
|
|
* @param options.onSearch - search callback
|
|
* @param options.placeholder - input placeholder
|
|
*/
|
|
constructor({ items, onSearch, placeholder }: {
|
|
items: SearchableItem[];
|
|
onSearch: (items: SearchableItem[]) => void;
|
|
placeholder: string;
|
|
}) {
|
|
this.listeners = new Listeners();
|
|
this.items = items;
|
|
this.onSearch = onSearch;
|
|
|
|
this.render(placeholder);
|
|
}
|
|
|
|
/**
|
|
* Returns search field element
|
|
*/
|
|
public getElement(): HTMLElement {
|
|
return this.wrapper;
|
|
}
|
|
|
|
/**
|
|
* Sets focus to the input
|
|
*/
|
|
public focus(): void {
|
|
this.input.focus();
|
|
}
|
|
|
|
/**
|
|
* Clears search query and results
|
|
*/
|
|
public clear(): void {
|
|
this.input.value = '';
|
|
this.searchQuery = '';
|
|
this.onSearch(this.foundItems);
|
|
}
|
|
|
|
/**
|
|
* Clears memory
|
|
*/
|
|
public destroy(): void {
|
|
this.listeners.removeAll();
|
|
}
|
|
|
|
/**
|
|
* Creates the search field
|
|
*
|
|
* @param placeholder - input placeholder
|
|
*/
|
|
private render(placeholder: string): void {
|
|
this.wrapper = Dom.make('div', SearchInput.CSS.wrapper);
|
|
|
|
const iconWrapper = Dom.make('div', SearchInput.CSS.icon, {
|
|
innerHTML: IconSearch,
|
|
});
|
|
|
|
this.input = Dom.make('input', SearchInput.CSS.input, {
|
|
placeholder,
|
|
}) as HTMLInputElement;
|
|
|
|
this.wrapper.appendChild(iconWrapper);
|
|
this.wrapper.appendChild(this.input);
|
|
|
|
this.listeners.on(this.input, 'input', () => {
|
|
this.searchQuery = this.input.value;
|
|
|
|
this.onSearch(this.foundItems);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Returns list of found items for the current search query
|
|
*/
|
|
private get foundItems(): SearchableItem[] {
|
|
return this.items.filter(item => this.checkItem(item));
|
|
}
|
|
|
|
/**
|
|
* Contains logic for checking whether passed item conforms the search query
|
|
*
|
|
* @param item - item to be checked
|
|
*/
|
|
private checkItem(item: SearchableItem): boolean {
|
|
const text = item.label.toLowerCase();
|
|
const query = this.searchQuery.toLowerCase();
|
|
|
|
return text.includes(query);
|
|
}
|
|
}
|