mirror of
https://github.com/Redocly/redoc.git
synced 2024-11-26 10:33:44 +03:00
feat: add clear icon to searchbox
This commit is contained in:
parent
b797c965b2
commit
825162e5d7
|
@ -1,81 +1,13 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import styled from '../../styled-components';
|
|
||||||
|
|
||||||
import { IMenuItem } from '../../services/MenuStore';
|
import { IMenuItem } from '../../services/MenuStore';
|
||||||
import { SearchStore } from '../../services/SearchStore';
|
import { SearchStore } from '../../services/SearchStore';
|
||||||
import { MenuItem } from '../SideMenu/MenuItem';
|
import { MenuItem } from '../SideMenu/MenuItem';
|
||||||
import { MenuItemLabel } from '../SideMenu/styled.elements';
|
|
||||||
import { MarkerService } from '../../services/MarkerService';
|
import { MarkerService } from '../../services/MarkerService';
|
||||||
import { SearchDocument } from '../../services/SearchWorker.worker';
|
import { SearchDocument } from '../../services/SearchWorker.worker';
|
||||||
|
|
||||||
const SearchInput = styled.input.attrs({
|
import { ClearIcon, SearchIcon, SearchInput, SearchResultsBox } from './elements';
|
||||||
className: 'search-input',
|
|
||||||
})`
|
|
||||||
width: calc(100% - ${props => props.theme.spacingUnit * 2}px);
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin: 0 ${props => props.theme.spacingUnit}px;
|
|
||||||
padding: 5px 0 5px ${props => props.theme.spacingUnit}px;
|
|
||||||
border: 0;
|
|
||||||
border-bottom: 1px solid #e1e1e1;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 13px;
|
|
||||||
color: ${props => props.theme.colors.text};
|
|
||||||
background-color: transparent;
|
|
||||||
outline: none;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const SearchIcon = styled((props: any) => (
|
|
||||||
<svg
|
|
||||||
className={props.className}
|
|
||||||
version="1.1"
|
|
||||||
viewBox="0 0 1000 1000"
|
|
||||||
x="0px"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
y="0px"
|
|
||||||
>
|
|
||||||
<path d="M968.2,849.4L667.3,549c83.9-136.5,66.7-317.4-51.7-435.6C477.1-25,252.5-25,113.9,113.4c-138.5,138.3-138.5,362.6,0,501C219.2,730.1,413.2,743,547.6,666.5l301.9,301.4c43.6,43.6,76.9,14.9,104.2-12.4C981,928.3,1011.8,893,968.2,849.4z M524.5,522c-88.9,88.7-233,88.7-321.8,0c-88.9-88.7-88.9-232.6,0-321.3c88.9-88.7,233-88.7,321.8,0C613.4,289.4,613.4,433.3,524.5,522z" />
|
|
||||||
</svg>
|
|
||||||
)).attrs({
|
|
||||||
className: 'search-icon',
|
|
||||||
})`
|
|
||||||
position: absolute;
|
|
||||||
left: ${props => props.theme.spacingUnit}px;
|
|
||||||
height: 1.8em;
|
|
||||||
width: 0.9em;
|
|
||||||
|
|
||||||
path {
|
|
||||||
fill: ${props => props.theme.colors.text};
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const SearchResultsBox = styled.div.attrs({
|
|
||||||
className: 'search-results',
|
|
||||||
})`
|
|
||||||
padding: ${props => props.theme.spacingUnit / 4}px 0;
|
|
||||||
background-color: #ededed;
|
|
||||||
min-height: 150px;
|
|
||||||
max-height: 250px;
|
|
||||||
border-top: 1px solid #e1e1e1;
|
|
||||||
border-bottom: 1px solid #e1e1e1;
|
|
||||||
margin-top: 10px;
|
|
||||||
line-height: 1.4;
|
|
||||||
font-size: 0.9em;
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
${MenuItemLabel} {
|
|
||||||
padding-top: 6px;
|
|
||||||
padding-bottom: 6px;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: #e1e1e1;
|
|
||||||
}
|
|
||||||
|
|
||||||
> svg {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export interface SearchBoxProps {
|
export interface SearchBoxProps {
|
||||||
search: SearchStore;
|
search: SearchStore;
|
||||||
|
@ -113,13 +45,13 @@ export class SearchBox extends React.PureComponent<SearchBoxProps, SearchBoxStat
|
||||||
this.props.marker.unmark();
|
this.props.marker.unmark();
|
||||||
}
|
}
|
||||||
|
|
||||||
clear() {
|
clear = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
results: [],
|
results: [],
|
||||||
term: '',
|
term: '',
|
||||||
});
|
});
|
||||||
this.props.marker.unmark();
|
this.props.marker.unmark();
|
||||||
}
|
};
|
||||||
|
|
||||||
clearIfEsq = event => {
|
clearIfEsq = event => {
|
||||||
if (event && event.keyCode === 27) {
|
if (event && event.keyCode === 27) {
|
||||||
|
@ -163,6 +95,7 @@ export class SearchBox extends React.PureComponent<SearchBoxProps, SearchBoxStat
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
{this.state.term && <ClearIcon onClick={this.clear}>×</ClearIcon>}
|
||||||
<SearchIcon />
|
<SearchIcon />
|
||||||
<SearchInput
|
<SearchInput
|
||||||
value={this.state.term}
|
value={this.state.term}
|
||||||
|
|
85
src/components/SearchBox/elements.tsx
Normal file
85
src/components/SearchBox/elements.tsx
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import styled from '../../styled-components';
|
||||||
|
import { MenuItemLabel } from '../SideMenu/styled.elements';
|
||||||
|
|
||||||
|
export const SearchInput = styled.input.attrs({
|
||||||
|
className: 'search-input',
|
||||||
|
})`
|
||||||
|
width: calc(100% - ${props => props.theme.spacingUnit * 2}px);
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0 ${props => props.theme.spacingUnit}px;
|
||||||
|
padding: 5px ${props => props.theme.spacingUnit / 2}px 5px ${props => props.theme.spacingUnit}px;
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 1px solid #e1e1e1;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 13px;
|
||||||
|
color: ${props => props.theme.colors.text};
|
||||||
|
background-color: transparent;
|
||||||
|
outline: none;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const SearchIcon = styled((props: any) => (
|
||||||
|
<svg
|
||||||
|
className={props.className}
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 1000 1000"
|
||||||
|
x="0px"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
y="0px"
|
||||||
|
>
|
||||||
|
<path d="M968.2,849.4L667.3,549c83.9-136.5,66.7-317.4-51.7-435.6C477.1-25,252.5-25,113.9,113.4c-138.5,138.3-138.5,362.6,0,501C219.2,730.1,413.2,743,547.6,666.5l301.9,301.4c43.6,43.6,76.9,14.9,104.2-12.4C981,928.3,1011.8,893,968.2,849.4z M524.5,522c-88.9,88.7-233,88.7-321.8,0c-88.9-88.7-88.9-232.6,0-321.3c88.9-88.7,233-88.7,321.8,0C613.4,289.4,613.4,433.3,524.5,522z" />
|
||||||
|
</svg>
|
||||||
|
)).attrs({
|
||||||
|
className: 'search-icon',
|
||||||
|
})`
|
||||||
|
position: absolute;
|
||||||
|
left: ${props => props.theme.spacingUnit}px;
|
||||||
|
height: 1.8em;
|
||||||
|
width: 0.9em;
|
||||||
|
|
||||||
|
path {
|
||||||
|
fill: ${props => props.theme.colors.text};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const SearchResultsBox = styled.div.attrs({
|
||||||
|
className: 'search-results',
|
||||||
|
})`
|
||||||
|
padding: ${props => props.theme.spacingUnit / 4}px 0;
|
||||||
|
background-color: #ededed;
|
||||||
|
min-height: 150px;
|
||||||
|
max-height: 250px;
|
||||||
|
border-top: 1px solid #e1e1e1;
|
||||||
|
border-bottom: 1px solid #e1e1e1;
|
||||||
|
margin-top: 10px;
|
||||||
|
line-height: 1.4;
|
||||||
|
font-size: 0.9em;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
${MenuItemLabel} {
|
||||||
|
padding-top: 6px;
|
||||||
|
padding-bottom: 6px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #e1e1e1;
|
||||||
|
}
|
||||||
|
|
||||||
|
> svg {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const ClearIcon = styled.i`
|
||||||
|
position: absolute;
|
||||||
|
display: inline-block;
|
||||||
|
width: ${props => props.theme.spacingUnit / 2}px;
|
||||||
|
text-align: center;
|
||||||
|
right: ${props => props.theme.spacingUnit}px;
|
||||||
|
line-height: 2em;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-style: normal;
|
||||||
|
color: '#666';
|
||||||
|
`;
|
Loading…
Reference in New Issue
Block a user