mirror of
https://github.com/codex-team/editor.js
synced 2024-05-29 12:02:46 +02:00
8f156a87ea
* the popover component, vertical toolbox * toolbox position improved * popover width improved * always show the plus button * search field added * search input in popover * trying to create mobile toolbox * feat(toolbox): popover adapted for mobile devices (#2004) * FIx mobile popover fixed positioning * Add mobile popover overlay * Hide mobile popover on scroll * Alter toolbox buttons hover * Fix closing popover on overlay click * Tests fix * Fix onchange test * restore focus after toolbox closing by ESC * don't move toolbar by block-hover on mobile Resolves #1972 * popover mobile styles improved * Cleanup * Remove scroll event listener * Lock scroll on mobile * don't show shortcuts in mobile popover * Change data attr name * Remove unused styles * Remove unused listeners * disable hover on mobile popover * Scroll fix * Lint * Revert "Scroll fix" This reverts commit82deae543e
. * Return back background color for active state of toolbox buttons Co-authored-by: Peter Savchenko <specc.dev@gmail.com> * Vertical toolbox fixes (#2017) * Replace visibility property with display for hiding popover * Disable arrow right and left keys for popover * Revert "Replace visibility property with display for hiding popover" This reverts commitaf521cf6f2
. * Hide popover via setting max-height to 0 to fix animation in safari * Remove redundant condition * Extend element interface to avoid ts errors * Do not subscribe to block hovered if mobile * Add unsubscribing from overlay click event * Rename isMobile to isMobileScreen * Cleanup * fix: popover opening direction (#2022) * Change popover opening direction based on available space below it * Update check * Use cacheable decorator * Update src/components/flipper.ts Co-authored-by: George Berezhnoy <gohabereg@users.noreply.github.com> * Fixes * Fix test * Clear search on popover hide * Fix popover width * Fix for tests * Update todos * Linter fixes * rm todo about beforeInsert because I have no idea what does it mean * i18n for search labels done * rm methods for hiding/showing of + * some code style update * Update CHANGELOG.md * make the list items a little bit compact * fix z-index issue caused by block-appearing animation also, improve popover padding for two reasons: - make the popover more consistent with the Table tool popover (in future, it can be done with the same api method) - make popover looks better Co-authored-by: Tanya Fomina <fomina.tatianaaa@yandex.ru> Co-authored-by: George Berezhnoy <gohabereg@users.noreply.github.com>
153 lines
3.1 KiB
TypeScript
153 lines
3.1 KiB
TypeScript
import Dom from '../dom';
|
|
import Listeners from './listeners';
|
|
|
|
/**
|
|
* 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);
|
|
const icon = Dom.svg('search', 16, 16);
|
|
|
|
this.input = Dom.make('input', SearchInput.CSS.input, {
|
|
placeholder,
|
|
}) as HTMLInputElement;
|
|
|
|
iconWrapper.appendChild(icon);
|
|
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);
|
|
}
|
|
}
|