chore: a11y and animation for the theme toggle
This commit is contained in:
parent
21653c4156
commit
03a249c032
2 changed files with 77 additions and 27 deletions
|
@ -1,19 +1,12 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import cx from 'classnames';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Link, useLocation } from 'react-router-dom';
|
||||
import {
|
||||
Moon,
|
||||
Command,
|
||||
Activity,
|
||||
Globe,
|
||||
Link2,
|
||||
Settings,
|
||||
File
|
||||
} from 'react-feather';
|
||||
import { Command, Activity, Globe, Link2, Settings, File } from 'react-feather';
|
||||
|
||||
import { connect } from './StateProvider';
|
||||
import { switchTheme } from '../store/app';
|
||||
import { getTheme, switchTheme } from '../store/app';
|
||||
|
||||
import SvgYacd from './SvgYacd';
|
||||
import s from './SideBar.module.css';
|
||||
|
@ -68,7 +61,6 @@ const pages = [
|
|||
iconId: 'command',
|
||||
labelText: 'Rules'
|
||||
},
|
||||
|
||||
{
|
||||
to: '/connections',
|
||||
iconId: 'link',
|
||||
|
@ -86,7 +78,7 @@ const pages = [
|
|||
}
|
||||
];
|
||||
|
||||
function SideBar({ dispatch }) {
|
||||
function SideBar({ dispatch, theme }) {
|
||||
const location = useLocation();
|
||||
const switchThemeHooked = useCallback(() => {
|
||||
dispatch(switchTheme());
|
||||
|
@ -115,18 +107,67 @@ function SideBar({ dispatch }) {
|
|||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className={s.themeSwitchContainer} onClick={switchThemeHooked}>
|
||||
<Moon size={20} />
|
||||
</div>
|
||||
<button className={s.themeSwitchContainer} onClick={switchThemeHooked}>
|
||||
{theme === 'light' ? <MoonA /> : <Sun />}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// SideBar.propTypes = {
|
||||
// location: PropTypes.shape({
|
||||
// pathname: PropTypes.string
|
||||
// }).isRequired
|
||||
// };
|
||||
function MoonA() {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<motion.path
|
||||
d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"
|
||||
initial={{ rotate: -30 }}
|
||||
animate={{ rotate: 0 }}
|
||||
transition={{ duration: 0.7 }}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
const mapState = () => null;
|
||||
function Sun() {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<circle cx="12" cy="12" r="5"></circle>
|
||||
<motion.g
|
||||
initial={{ scale: 0.8 }}
|
||||
animate={{ scale: 1 }}
|
||||
transition={{ duration: 0.7 }}
|
||||
>
|
||||
<line x1="12" y1="1" x2="12" y2="3"></line>
|
||||
<line x1="12" y1="21" x2="12" y2="23"></line>
|
||||
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
||||
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
||||
<line x1="1" y1="12" x2="3" y2="12"></line>
|
||||
<line x1="21" y1="12" x2="23" y2="12"></line>
|
||||
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
||||
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
||||
</motion.g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
const mapState = s => ({ theme: getTheme(s) });
|
||||
export default connect(mapState)(SideBar);
|
||||
|
|
|
@ -96,24 +96,33 @@
|
|||
}
|
||||
|
||||
.themeSwitchContainer {
|
||||
--sz: 50px;
|
||||
--sz: 40px;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
bottom: 10px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: var(--sz);
|
||||
height: var(--sz);
|
||||
padding: 20px 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
svg {
|
||||
display: block;
|
||||
color: var(--color-icon);
|
||||
|
||||
color: var(--color-text);
|
||||
|
||||
padding: 5px;
|
||||
appearance: none;
|
||||
outline: none;
|
||||
user-select: none;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 100%;
|
||||
&:focus {
|
||||
border-color: var(--color-focus-blue);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue