Consolidates the search inputs
This commit is contained in:
parent
1b352531ca
commit
67209d8881
13 changed files with 263 additions and 319 deletions
|
@ -1,13 +1,26 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// Copyright 2021-2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { ChangeEvent, KeyboardEvent } from 'react';
|
||||
import type {
|
||||
ChangeEvent,
|
||||
FocusEventHandler,
|
||||
KeyboardEvent,
|
||||
ReactNode,
|
||||
} from 'react';
|
||||
import React, { forwardRef } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import type { LocalizerType } from '../types/Util';
|
||||
import { getClassNamesFor } from '../util/getClassNamesFor';
|
||||
|
||||
export type PropTypes = {
|
||||
readonly children?: ReactNode;
|
||||
readonly disabled?: boolean;
|
||||
readonly label?: string;
|
||||
readonly hasSearchIcon?: boolean;
|
||||
readonly i18n: LocalizerType;
|
||||
readonly moduleClassName?: string;
|
||||
readonly onClear?: () => unknown;
|
||||
readonly onBlur?: FocusEventHandler<HTMLInputElement>;
|
||||
readonly onChange: (ev: ChangeEvent<HTMLInputElement>) => unknown;
|
||||
readonly onKeyDown?: (ev: KeyboardEvent<HTMLInputElement>) => unknown;
|
||||
readonly placeholder: string;
|
||||
|
@ -19,8 +32,14 @@ const BASE_CLASS_NAME = 'module-SearchInput';
|
|||
export const SearchInput = forwardRef<HTMLInputElement, PropTypes>(
|
||||
(
|
||||
{
|
||||
children,
|
||||
disabled = false,
|
||||
hasSearchIcon = true,
|
||||
i18n,
|
||||
label,
|
||||
moduleClassName,
|
||||
onClear,
|
||||
onBlur,
|
||||
onChange,
|
||||
onKeyDown,
|
||||
placeholder,
|
||||
|
@ -31,18 +50,48 @@ export const SearchInput = forwardRef<HTMLInputElement, PropTypes>(
|
|||
const getClassName = getClassNamesFor(BASE_CLASS_NAME, moduleClassName);
|
||||
return (
|
||||
<div className={getClassName('__container')}>
|
||||
<i className={getClassName('__icon')} />
|
||||
{hasSearchIcon && <i className={getClassName('__icon')} />}
|
||||
{children}
|
||||
<input
|
||||
className={getClassName('__input')}
|
||||
aria-label={label || i18n('search')}
|
||||
className={classNames(
|
||||
getClassName('__input'),
|
||||
value && getClassName('__input--with-text'),
|
||||
children && getClassName('__input--with-children')
|
||||
)}
|
||||
dir="auto"
|
||||
disabled={disabled}
|
||||
onBlur={onBlur}
|
||||
onChange={onChange}
|
||||
onKeyDown={onKeyDown}
|
||||
onKeyDown={event => {
|
||||
const { ctrlKey, key } = event;
|
||||
|
||||
// On Linux, this key combo selects all text.
|
||||
if (window.platform === 'linux' && ctrlKey && key === '/') {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
} else if (key === 'Escape' && onClear) {
|
||||
onClear();
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
onKeyDown?.(event);
|
||||
}}
|
||||
placeholder={placeholder}
|
||||
ref={ref}
|
||||
type="text"
|
||||
value={value}
|
||||
/>
|
||||
{value && onClear && (
|
||||
<button
|
||||
aria-label={i18n('cancel')}
|
||||
className={getClassName('__cancel')}
|
||||
onClick={onClear}
|
||||
tabIndex={-1}
|
||||
type="button"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue