Skip to content

Commit

Permalink
feat: add zoom slider to interface controls (#402)
Browse files Browse the repository at this point in the history
* build: install jotai in frontend

* feat: add modal component

* feat: convert nav links to modals

* fix: add missing dark theme support

* feat: add Slider component

* feat: add zoom slider for source view

* feat: add touchscreen support for modals

* fix: lint error
  • Loading branch information
bhajneet authored Sep 28, 2022
1 parent b431ac3 commit d6a664a
Show file tree
Hide file tree
Showing 9 changed files with 476 additions and 190 deletions.
264 changes: 160 additions & 104 deletions frontend/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "0.1.0",
"dependencies": {
"gurmukhi-utils": "^3.2.2",
"jotai": "^1.8.4",
"lodash": "^4.17.21",
"lucide-react": "^0.88.0",
"new-github-issue-url": "^1.0.0",
Expand Down
100 changes: 100 additions & 0 deletions frontend/src/components/Modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { X } from 'lucide-react'
import { Dispatch, ReactNode, SetStateAction } from 'react'
import { createUseStyles } from 'react-jss'

import theme from '../helpers/theme'

type ModalProps = {
visible: boolean,
setVisible: Dispatch<SetStateAction<boolean>>,
children?: ReactNode,
}

const useStyles = createUseStyles( {
modalBackDrop: {
position: 'fixed',
left: 0,
top: 0,
backgroundColor: `${theme.ModalBackdrop}`,
width: '100%',
height: '100%',
zIndex: 2,
},
modal: {
zIndex: 3,
margin: `calc(${theme.Gutter} * .5) auto 0`,
background: `${theme.ModalBg}`,
borderRadius: theme.Gap,
maxWidth: '810px',
maxHeight: `calc(100% - ${theme.Gutter})`,
display: 'flex',
flexDirection: 'column',
overflow: 'auto',
},
close: {
float: 'right',
top: 0,
position: 'sticky',
lineHeight: 0,
padding: `calc(${theme.Gap} * 1.5)`,
cursor: 'pointer',
'&:hover': {
color: `${theme.Blue}`,
},
},
content: {
flexGrow: 1,
overflowY: 'scroll',
'&::-webkit-scrollbar': {
display: 'none',
},
},
'@media (prefers-color-scheme: dark)': {
modalBackDrop: {
backgroundColor: `${theme.ModalBackdropDarkScheme}`,
},
modal: {
background: `${theme.ModalBgDarkScheme}`,
},
close: {
'&:hover': {
color: `${theme.BlueDarkScheme}`,
},
},
},
'@media (pointer: coarse)': {
modal: {
width: '100%',
margin: [ 0, 'auto' ],
left: 0,
right: 0,
bottom: 0,
maxHeight: `calc(100% - ${theme.Gap})`,
borderRadius: [ theme.Gap, theme.Gap, 0, 0 ],
position: 'fixed',
},
},
} )

const Modal = ( { visible, setVisible, children }: ModalProps ) => {
const classes = useStyles()
const toggleVisibility = () => setVisible( !visible )

if ( visible ) {
return (
<div className={classes.modalBackDrop} onClick={toggleVisibility}>
<div className={classes.modal} onClick={( e ) => e.stopPropagation()}>
<div className={classes.content}>
<div className={classes.close} onClick={toggleVisibility}>
<X />
</div>
{children}
</div>
</div>
</div>
)
}
return null
}

export default Modal
29 changes: 28 additions & 1 deletion frontend/src/components/Nav.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { useState } from 'react'
import { createUseStyles } from 'react-jss'
import { Link } from 'react-router-dom'

import theme from '../helpers/theme'
import About from '../screens/About'
import Interface from '../screens/Interface'
import Content from './Content'
import Logo from './Logo'
import Modal from './Modal'

const useStyles = createUseStyles( {
nav: {
Expand All @@ -21,9 +25,13 @@ const useStyles = createUseStyles( {
fontSize: '0.8rem',
},
button: {
cursor: 'pointer',
'&:hover': {
color: theme.Blue,
},
'& + $button': {
marginLeft: '1.5rem',
},
},
'@media (prefers-color-scheme: dark)': {
nav: {
Expand All @@ -40,6 +48,8 @@ const useStyles = createUseStyles( {

const Nav = () => {
const classes = useStyles()
const [ visibleAbout, setVisibleAbout ] = useState( false )
const [ visibleInterface, setVisibleInterface ] = useState( false )

return (
<div className={classes.nav}>
Expand All @@ -49,10 +59,27 @@ const Nav = () => {
<Logo />
</Link>
<div>
<Link to="/about" className={classes.button}>About</Link>
<span
className={classes.button}
onClick={() => setVisibleAbout( true )}
>
About
</span>
<span
className={classes.button}
onClick={() => setVisibleInterface( true )}
>
Interface
</span>
</div>
</div>
</Content>
<Modal visible={visibleAbout} setVisible={setVisibleAbout}>
<About />
</Modal>
<Modal visible={visibleInterface} setVisible={setVisibleInterface}>
<Interface />
</Modal>
</div>
)
}
Expand Down
72 changes: 72 additions & 0 deletions frontend/src/components/Slider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Dispatch, SetStateAction } from 'react'
import { createUseStyles } from 'react-jss'

import theme from '../helpers/theme'

type SliderProps = {
min: number,
max: number,
step: number | string,
units: string,
value: number,
setValue: Dispatch<SetStateAction<number>>,
}

const useStyles = createUseStyles( {
legend: {
width: '100%',
display: 'flex',
justifyContent: 'space-between',
fontSize: '0.75rem',
color: `${theme.FgMuted}`,
},
value: {
color: `${theme.Fg}`,
},
slider: {
width: '100%',
},

'@media (prefers-color-scheme: dark)': {
legend: {
color: `${theme.FgMutedDarkScheme}`,
},
value: {
color: `${theme.FgDarkScheme}`,
},
},

} )

const Slider = ( { min, max, step, units, value, setValue }: SliderProps ) => {
const classes = useStyles()
return (
<>
<div className={classes.legend}>
<span>
{min}
{units}
</span>
<span className={classes.value}>
{value}
{units}
</span>
<span>
{max}
{units}
</span>
</div>
<input
className={classes.slider}
type="range"
min={min}
max={max}
step={step}
defaultValue={value}
onChange={( e ) => setValue( parseFloat( e.target.value as unknown as string ) )}
/>
</>
)
}

export default Slider
10 changes: 8 additions & 2 deletions frontend/src/helpers/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,21 @@ const theme = {
Fg: 'rgb(8.33% 7.46% 5.52%)', // lch(6% 3 85)
FgDarkScheme: 'rgb(79.55% 77.27% 77.12%)', // lch(80% 2.25 25)

FgMuted: 'rgb(57.57% 56.58% 54.63%)', // lch(60% 3 85)
FgMutedDarkScheme: 'rgb(38.49% 36.51% 36.38%)', // lch(40% 2.25 25)

Bg: 'rgb(94.2% 93.11% 90.97%)', // lch(94% 3 85)
BgDarkScheme: 'rgb(20.2% 18.51% 19.08%)', // lch(20% 2.25 355)

SelectionBg: '', //
SelectionBg: '',
SelectionBgDarkScheme: 'rgba(255, 222, 139, 0.4)', // lch(90% 132 85)

ModalBg: 'rgb(100%, 100%, 100%)', // lch(100% 0 0)
ModalBg: 'rgb(100% 100% 100%)', // lch(100% 0 0)
ModalBgDarkScheme: 'rgb(14.77% 14.77% 14.77%)', // lch(15% 0 0)

ModalBackdrop: 'rgba(100% 100% 100% / 40%)',
ModalBackdropDarkScheme: 'rgba(14.77% 14.77% 14.77% / 40%)',

Blue: 'rgb(0% 48.81% 81.83%)', // lch(50% 66 265)
BlueDarkScheme: 'rgb(43.72% 69.01% 100%)', // lch(70% 53 265)
BlueBrightMuted: 'rgb(58.43% 73.73% 96.07%)', // lch(75% 33 265)
Expand Down
Loading

0 comments on commit d6a664a

Please sign in to comment.