Skip to content
This repository has been archived by the owner on Jul 16, 2023. It is now read-only.

Commit

Permalink
feat(search): 💄 add alternative search show method with icon
Browse files Browse the repository at this point in the history
  • Loading branch information
filipowm committed Jun 13, 2020
1 parent aa64116 commit 3170c51
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 53 deletions.
2 changes: 1 addition & 1 deletion config/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ features:
enabled: true
engine: 'algolia'
placeholder: 'Search'
searchStartMethod: 'input'
startComponent: 'input' # icon
debounceTime: 380
snippetLength: 23
hitsPerPage: 10
Expand Down
4 changes: 2 additions & 2 deletions config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ module.exports = {
algoliaAdminKey: null,
engine: 'algolia',
placeholder: 'Search',
searchStartMethod: 'input', // 'icon',
startComponent: 'input', // 'icon',
debounceTime: 380,
snippetLength: 22,
hitsPerPage: 10
hitsPerPage: 10,
},
toc: {
depth: 3,
Expand Down
44 changes: 44 additions & 0 deletions src/components/Buttons/ButtonIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import PropTypes from 'prop-types';
import React from 'react';
import styled from '@emotion/styled';

const ButtonIconWrapper = styled('div')`
display: flex;
justify-content: flex-end;
margin: 0 5px;
padding: 6px;
background-color: ${(props) => props.background};
border-radius: 50%;
cursor: pointer;
&:hover {
svg {
fill: ${(props) => props.hover};
stroke: ${(props) => props.hover};
}
}
svg {
transition: ${(props) => props.theme.transitions.hover};
fill: ${(props) => props.fill};
stroke: ${(props) => props.stroke};
}
`;

const ButtonIcon = ({ icon, ...props }) => {
return (
<ButtonIconWrapper {...props} role={'button'} tabIndex={0}>
{/* not defining color as a workaround to use css styling instead */}
{icon.render({ color: '' })}
</ButtonIconWrapper>
);
};

ButtonIcon.propTypes = {
background: PropTypes.string.isRequired,
hover: PropTypes.string.isRequired,
fill: PropTypes.string.isRequired,
stroke: PropTypes.string.isRequired,
icon: PropTypes.object.isRequired,
};

export default ButtonIcon;
1 change: 1 addition & 0 deletions src/components/Buttons/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as ButtonIcon } from './ButtonIcon';
38 changes: 10 additions & 28 deletions src/components/DarkModeSwitch/DarkModeSwitch.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,20 @@
import PropTypes from "prop-types";
import React from 'react';
import { Sun as DayImage, Moon as NightImage } from 'react-feather';
import styled from '@emotion/styled';

const StyledSwitch = styled('div')`
display: flex;
justify-content: flex-end;
width: 100%;
margin: 0 20px 0 5px;
padding: 6px;
background-color: ${(props) => props.theme.darkModeSwitch.background};
border-radius: 50%;
cursor: pointer;
&:hover {
svg {
fill: ${(props) => props.theme.darkModeSwitch.hover};
stroke: ${(props) => props.theme.darkModeSwitch.hover};
}
}
svg {
transition: ${(props) => props.theme.transitions.hover};
fill: ${(props) => props.theme.darkModeSwitch.fill};
stroke: ${(props) => props.theme.darkModeSwitch.stroke};
}
`;
import { ButtonIcon } from '../';
import { useTheme } from 'emotion-theming';

const DarkModeSwitch = ({ isDarkThemeActive, toggleActiveTheme, ...props }) => {
const theme = useTheme();
const img = isDarkThemeActive ? NightImage : DayImage;
return (
<StyledSwitch {...props} role={'button'} tabIndex={0} onClick={toggleActiveTheme}>
{/* not defining color as a workaround to use css styling instead */}
{img.render({ color: '' })}
</StyledSwitch>
<ButtonIcon background={theme.darkModeSwitch.background}
hover={theme.darkModeSwitch.hover}
fill={theme.darkModeSwitch.fill}
stroke={theme.darkModeSwitch.stroke}
icon={img}
onClick={toggleActiveTheme}
{...props} />
);
};

Expand Down
63 changes: 48 additions & 15 deletions src/components/Header/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@ import 'css';
import config from 'config';
import Logo from './logo';
import Navigation from './navigation';
import { DarkModeSwitch, SearchInput, Sidebar } from '../';
import { ButtonIcon, DarkModeSwitch, SearchInput, Sidebar } from '../';
import { Search } from 'react-feather';
import { useTheme } from 'emotion-theming';

const SearchIcon = styled(Search)`
width: 1.2em;
pointer-events: cursor;
margin: 0 10px;
`;

const isSearchEnabled = config.features.search && config.features.search.enabled;

Expand Down Expand Up @@ -47,6 +55,9 @@ const HeaderWrapper = styled.header`
@media (max-width: ${(props) => props.theme.breakpoints['small']}) {
display: block;
}
div:last-child {
margin-right: 25px;
}
`;

const TopNavigation = styled.div`
Expand Down Expand Up @@ -74,6 +85,37 @@ const TopNavigation = styled.div`
}
`;

const SearchOpener = ({ open }) => {
const theme = useTheme();
const method = config.features.search.startComponent;
let opener = <div></div>;
switch (method.toLowerCase()) {
case 'input':
opener = (
<SearchWrapper className={'hiddenMobile'}>
<SearchInput onChange={(e) => (e.target.value = '')} onFocus={open} />
</SearchWrapper>
);
break;
case 'icon':
opener = (
<ButtonIcon
background={theme.darkModeSwitch.background}
hover={theme.darkModeSwitch.hover}
fill={'transparent'}
stroke={theme.darkModeSwitch.stroke}
icon={Search}
onClick={open}
/>
);
break;
default:
console.error(`Provided show component '${method}' is not supported. Use 'icon' or 'input'.`);
opener = <div></div>;
}
return opener;
};

const Header = ({ setShowSearch, location, themeProvider }) => (
<StaticQuery
query={graphql`
Expand Down Expand Up @@ -104,11 +146,13 @@ const Header = ({ setShowSearch, location, themeProvider }) => (
const logoLink = logo.link !== '' ? logo.link : '/';
const logoImg = require('images/logo.svg');
const [darkMode, setDarkMode] = useState(false);

useEffect(() => {
setDarkMode(themeProvider.current.retrieveActiveTheme());
});

const open = () => {
setShowSearch(true);
};
return (
<HeaderWrapper>
<Logo link={logoLink} img={logoImg} title={headerTitle} />
Expand All @@ -118,23 +162,12 @@ const Header = ({ setShowSearch, location, themeProvider }) => (
<Sidebar location={location} />
<hr />

{isSearchEnabled ? (
<SearchWrapper>
<SearchInput />
</SearchWrapper>
) : null}
{isSearchEnabled ? <SearchOpener open={open} /> : null}
</div>
<Navigation links={headerLinks} helpUrl={helpUrl} />
</TopNavigation>

{isSearchEnabled ? (
<SearchWrapper className={'hiddenMobile'}>
<SearchInput
onChange={(e) => (e.target.value = '')}
onFocus={() => setShowSearch(true)}
/>
</SearchWrapper>
) : null}
{isSearchEnabled ? <SearchOpener open={open} /> : null}

{config.features.darkMode.enabled ? (
<DarkModeSwitch
Expand Down
8 changes: 1 addition & 7 deletions src/components/Search/Sidebar.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable react/display-name */
import styled from '@emotion/styled';
import React, { useRef, useEffect, useState, createRef } from 'react';
import React, { useRef } from 'react';
import config from 'config';
import VisibilitySensor from 'react-visibility-sensor';

Expand All @@ -20,12 +20,6 @@ const SearchWrapper = styled.div`
padding: 12px 0;
`;

const HitsWrapper = styled.div`
margin-top: 69px;
padding: 20px;
border-top: 1px solid ${(props) => props.theme.colors.border};
`;

const SearchSidebar = styled.div`
display: block; //${(props) => (props.show ? 'block' : 'none')};
z-index: 200;
Expand Down
1 change: 1 addition & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './Buttons';
export DarkModeSwitch from './DarkModeSwitch';
export EditOnRepo from './EditOnRepo';
export Header from './Header';
Expand Down

0 comments on commit 3170c51

Please sign in to comment.