mirror of
https://github.com/SomboChea/ui
synced 2026-01-18 00:56:00 +07:00
initial commit
This commit is contained in:
129
src/components/AutoComplete/index.js
Normal file
129
src/components/AutoComplete/index.js
Normal file
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* @prettier
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import type { Node } from 'react';
|
||||
import Autosuggest from 'react-autosuggest';
|
||||
import match from 'autosuggest-highlight/match';
|
||||
import parse from 'autosuggest-highlight/parse';
|
||||
import Paper from '@material-ui/core/Paper';
|
||||
import MenuItem from '@material-ui/core/MenuItem';
|
||||
|
||||
import { fontWeight } from '../../utils/styles/sizes';
|
||||
import { Wrapper, InputField } from './styles';
|
||||
import { IProps } from './types';
|
||||
|
||||
const renderInputComponent = (inputProps): Node => {
|
||||
const { ref, startAdornment, disableUnderline, onKeyDown, ...others } = inputProps;
|
||||
return (
|
||||
<InputField
|
||||
InputProps={{
|
||||
inputRef: node => {
|
||||
ref(node);
|
||||
},
|
||||
startAdornment,
|
||||
disableUnderline,
|
||||
onKeyDown,
|
||||
}}
|
||||
fullWidth={true}
|
||||
{...others}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const getSuggestionValue = (suggestion): string => suggestion.name;
|
||||
|
||||
const renderSuggestion = (suggestion, { query, isHighlighted }): Node => {
|
||||
const matches = match(suggestion.name, query);
|
||||
const parts = parse(suggestion.name, matches);
|
||||
return (
|
||||
<MenuItem component={'div'} selected={isHighlighted}>
|
||||
<div>
|
||||
{parts.map((part, index) => {
|
||||
return part.highlight ? (
|
||||
<span href={suggestion.link} key={String(index)} style={{ fontWeight: fontWeight.semiBold }}>
|
||||
{part.text}
|
||||
</span>
|
||||
) : (
|
||||
<span href={suggestion.link} key={String(index)} style={{ fontWeight: fontWeight.light }}>
|
||||
{part.text}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</MenuItem>
|
||||
);
|
||||
};
|
||||
|
||||
const renderMessage = (message): Node => {
|
||||
return (
|
||||
<MenuItem component={'div'} selected={false}>
|
||||
<div>{message}</div>
|
||||
</MenuItem>
|
||||
);
|
||||
};
|
||||
|
||||
const SUGGESTIONS_RESPONSE = {
|
||||
LOADING: 'Loading...',
|
||||
FAILURE: 'Something went wrong.',
|
||||
NO_RESULT: 'No results found.',
|
||||
};
|
||||
|
||||
const AutoComplete = ({
|
||||
suggestions,
|
||||
startAdornment,
|
||||
onChange,
|
||||
onSuggestionsFetch,
|
||||
onCleanSuggestions,
|
||||
value = '',
|
||||
placeholder = '',
|
||||
disableUnderline = false,
|
||||
color,
|
||||
onClick,
|
||||
onKeyDown,
|
||||
onBlur,
|
||||
suggestionsLoading = false,
|
||||
suggestionsLoaded = false,
|
||||
suggestionsError = false,
|
||||
}: IProps): Node => {
|
||||
const autosuggestProps = {
|
||||
renderInputComponent,
|
||||
suggestions,
|
||||
getSuggestionValue,
|
||||
renderSuggestion,
|
||||
onSuggestionsFetchRequested: onSuggestionsFetch,
|
||||
onSuggestionsClearRequested: onCleanSuggestions,
|
||||
};
|
||||
const inputProps = {
|
||||
value,
|
||||
onChange,
|
||||
placeholder,
|
||||
startAdornment,
|
||||
disableUnderline,
|
||||
color,
|
||||
onKeyDown,
|
||||
onBlur,
|
||||
};
|
||||
|
||||
// this format avoid arrow function eslint rule
|
||||
function renderSuggestionsContainer({ containerProps, children, query }) {
|
||||
return (
|
||||
<Paper {...containerProps} square={true}>
|
||||
{suggestionsLoaded && children === null && query && renderMessage(SUGGESTIONS_RESPONSE.NO_RESULT)}
|
||||
{suggestionsLoading && query && renderMessage(SUGGESTIONS_RESPONSE.LOADING)}
|
||||
{suggestionsError && renderMessage(SUGGESTIONS_RESPONSE.FAILURE)}
|
||||
{children}
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<Autosuggest {...autosuggestProps} inputProps={inputProps} onSuggestionSelected={onClick} renderSuggestionsContainer={renderSuggestionsContainer} />
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default AutoComplete;
|
||||
52
src/components/AutoComplete/styles.js
Normal file
52
src/components/AutoComplete/styles.js
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @prettier
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import styled, { css } from 'react-emotion';
|
||||
|
||||
import TextField from '../TextField';
|
||||
import { IInputField } from './types';
|
||||
|
||||
export const Wrapper = styled.div`
|
||||
&& {
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
`;
|
||||
|
||||
export const InputField = ({ color, ...others }: IInputField) => (
|
||||
<TextField
|
||||
{...others}
|
||||
classes={{
|
||||
input: css`
|
||||
&& {
|
||||
${color &&
|
||||
css`
|
||||
color: ${color};
|
||||
`};
|
||||
}
|
||||
`,
|
||||
root: css`
|
||||
&& {
|
||||
&:before {
|
||||
content: '';
|
||||
border: none;
|
||||
}
|
||||
&:after {
|
||||
${color &&
|
||||
css`
|
||||
border-color: ${color};
|
||||
`};
|
||||
}
|
||||
&:hover:before {
|
||||
content: none;
|
||||
}
|
||||
}
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
29
src/components/AutoComplete/types.js
Normal file
29
src/components/AutoComplete/types.js
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @prettier
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import { InputAdornmentProps } from '@material-ui/core/InputAdornment';
|
||||
|
||||
export interface IProps {
|
||||
suggestions: any[];
|
||||
suggestionsLoading?: boolean;
|
||||
suggestionsLoaded?: boolean;
|
||||
suggestionsError?: boolean;
|
||||
apiLoading?: boolean;
|
||||
color?: string;
|
||||
value?: string;
|
||||
placeholder?: string;
|
||||
startAdornment?: React.ComponentType<InputAdornmentProps>;
|
||||
disableUnderline?: boolean;
|
||||
onChange?: (event: SyntheticKeyboardEvent<HTMLInputElement>, { newValue: string, method: string }) => void;
|
||||
onSuggestionsFetch?: ({ value: string }) => Promise<void>;
|
||||
onCleanSuggestions?: () => void;
|
||||
onClick?: (event: SyntheticKeyboardEvent<HTMLInputElement>, { suggestionValue: any[], method: string }) => void;
|
||||
onKeyDown?: (event: SyntheticKeyboardEvent<HTMLInputElement>) => void;
|
||||
onBlur?: (event: SyntheticKeyboardEvent<HTMLInputElement>) => void;
|
||||
}
|
||||
|
||||
export interface IInputField {
|
||||
color: string;
|
||||
}
|
||||
Reference in New Issue
Block a user