mirror of
https://github.com/codex-team/editor.js
synced 2024-05-20 15:26:48 +02:00
07b1ce2aca
* Add new popover class * Add flipper * confirmation * confirmation * Add confirmation support * Add search * Add toggle group support and update popover tests * Add custom content support * Fix scroll issue * Add mobile version * Integration * Fix animation * Cleanup * Fix popover position for narrow mode * Fix tests * Update version and changelog * Rename css classes * Move files * Stop using PopoverItem from outside of popover context * Fix jsdoc * Move error animation to popover item * Update css variables * Update docs/CHANGELOG.md Co-authored-by: Ilya Maroz <37909603+ilyamore88@users.noreply.github.com> * Update src/components/block-tunes/block-tune-move-down.ts Co-authored-by: Peter Savchenko <specc.dev@gmail.com> * Update src/components/block-tunes/block-tune-move-up.ts Co-authored-by: Peter Savchenko <specc.dev@gmail.com> * Fixes * Fix imports * Fix toolbox close event * Move search-input file * Fix comment * Rename method * Cleanup * Remove onFlip callback from popover item * Rename * Fix removing event listener * Move popover animations to popover.css file * Cleanup styles * Fix jsdoc * Fix confirmation chains * Close toolbox oly when it's open * Change activation error animation * Update version and changelog * Fix overlay * Update icon border-radius on mobile * Disable item text select * Update changelog * Update yarn.lock * Add rc postfix to version --------- Co-authored-by: Ilya Maroz <37909603+ilyamore88@users.noreply.github.com> Co-authored-by: Peter Savchenko <specc.dev@gmail.com>
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 {
|
|
title?: 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: (query: string, 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: (query: string, 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.searchQuery, 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.title?.toLowerCase() || '';
|
|
const query = this.searchQuery.toLowerCase();
|
|
|
|
return text.includes(query);
|
|
}
|
|
}
|