Skip to content

Commit

Permalink
* search-box: support to binding hotkeys to searchbox.
Browse files Browse the repository at this point in the history
  • Loading branch information
catouse committed Dec 5, 2023
1 parent d5f2c09 commit ce813fa
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 14 deletions.
59 changes: 48 additions & 11 deletions lib/search-box/src/components/search-box.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Component, createRef} from 'preact';
import {classes, Icon, nextGid} from '@zui/core';
import {$, classes, getHotkeysMap, Icon, nextGid} from '@zui/core';
import '../style';

import type {ComponentChildren, RenderableProps} from 'preact';
Expand All @@ -10,6 +10,7 @@ export class SearchBox extends Component<SearchBoxOptions, SearchBoxState> {
clearIcon: true,
searchIcon: true,
delay: 500,
hotkeys: true,
};

protected _gid: string;
Expand All @@ -18,12 +19,48 @@ export class SearchBox extends Component<SearchBoxOptions, SearchBoxState> {

protected _timer = 0;

protected _hotkeysScope?: string;

constructor(props: SearchBoxOptions) {
super(props);
this.state = {focus: false, value: props.defaultValue || ''};
this._gid = props.id || `search-box-${nextGid()}`;
}

componentDidMount(): void {
const {hotkeys} = this.props;
if (hotkeys) {
const hotkeysMap = getHotkeysMap(hotkeys, {
clear: {
keys: ['Escape'],
handler: (event) => {
this.clear(event);
},
},
enter: {
keys: ['Enter'],
handler: (event) => {
this.props.onEnter?.(this.state.value, event);
},
},
});
if (hotkeysMap) {
this._hotkeysScope = `SearchBox_${this._gid}`;
console.log('hotkeysMap', hotkeysMap);
$(this.input).hotkeys(hotkeysMap, {
scope: this._hotkeysScope,
event: 'keydown',
});
}
}
}

componentWillUnmount(): void {
if (this._hotkeysScope) {
$(this.input).unbindHotkeys(this._hotkeysScope);
}
}

get id() {
return this._gid;
}
Expand All @@ -32,9 +69,12 @@ export class SearchBox extends Component<SearchBoxOptions, SearchBoxState> {
return this._input.current;
}

_handleClearBtnClick = (event: MouseEvent) => {
focus() {
this.input?.focus();
}

clear(event?: Event) {
const oldValue = this.state.value;
event.stopPropagation();
this.setState({value: ''}, () => {
const {onChange, onClear} = this.props;
onClear?.(event);
Expand All @@ -43,6 +83,11 @@ export class SearchBox extends Component<SearchBoxOptions, SearchBoxState> {
onChange?.('', event);
}
});
}

_handleClearBtnClick = (event: MouseEvent) => {
event.stopPropagation();
this.clear(event);
};

_handleChange = (event: Event) => {
Expand Down Expand Up @@ -80,14 +125,6 @@ export class SearchBox extends Component<SearchBoxOptions, SearchBoxState> {
this._timer = 0;
}

focus() {
this.input?.focus();
}

componentWillUnmount(): void {
this._clearTimer();
}

render(props: RenderableProps<SearchBoxOptions>, state: Readonly<SearchBoxState>) {
const {style, className, rootClass, rootStyle, readonly, disabled, circle, placeholder, mergeIcon, searchIcon, clearIcon, value: controlledValue, compact, prefixClass, suffixClass} = props;
const {focus, value} = state;
Expand Down
8 changes: 5 additions & 3 deletions lib/search-box/src/types/search-box-options.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type {ClassNameLike, IconType, JSX} from '@zui/core';
import type {ClassNameLike, HotkeysSettings, IconType, JSX} from '@zui/core';

export type SearchBoxOptions = {
id?: string;
Expand All @@ -20,8 +20,10 @@ export type SearchBoxOptions = {
mergeIcon?: boolean | IconType;
prefixClass?: ClassNameLike;
suffixClass?: ClassNameLike;
onChange?: (value: string, event: Event) => void;
onClear?: (event: MouseEvent) => void;
hotkeys?: HotkeysSettings;
onChange?: (value: string, event: Event | undefined) => void;
onEnter?: (value: string, event: Event | undefined) => void;
onClear?: (event: Event | undefined) => void;
onFocus?: (event: FocusEvent) => void;
onBlur?: (event: FocusEvent) => void;
};

0 comments on commit ce813fa

Please sign in to comment.