Skip to content

Commit

Permalink
chore: refactor the theme hoook
Browse files Browse the repository at this point in the history
- previously, pretty much all the keys on the keyboard can trigger the theme toggle when it is focused. we don't want that. Instead we should only limit it to specific keys (spacebar & enter).
- include all the varying colors when the theme is dark on all routes
- extend the Box component to use the theme value instead of explicitly passing it in the style prop across the codebase
  • Loading branch information
kaf-lamed-beyt committed Feb 12, 2025
1 parent f0c5ad4 commit b4b1c95
Show file tree
Hide file tree
Showing 14 changed files with 119 additions and 53 deletions.
6 changes: 5 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import Connected from './components/connected/Connected.js'
import TourHelper from './components/tour/TourHelper.js'
import FilesExploreForm from './files/explore-form/files-explore-form.tsx'
import { ThemeProvider, ThemeContext } from './context/theme-provider'
import { ThemeToggle } from './components/theme-toggle/toggle'

export class App extends Component {
static propTypes = {
Expand Down Expand Up @@ -74,13 +75,16 @@ export class App extends Component {
{ canDrop && isOver && <div className='h-100 top-0 right-0 fixed appOverlay' style={{ background: 'rgba(99, 202, 210, 0.2)' }} /> }
<div className='flex flex-row-reverse-l flex-column-reverse justify-end justify-start-l' style={{ minHeight: '100vh' }}>
<div className='flex-auto-l'>
<div className='flex items-center ph3 ph4-l' style={{ WebkitAppRegion: 'drag', height: 75, background: '#F0F6FA', paddingTop: '20px', paddingBottom: '15px' }}>
<div className='flex items-center ph3 ph4-l webui-header' style={{ WebkitAppRegion: 'drag', height: 75, background: '#F0F6FA', paddingTop: '20px', paddingBottom: '15px' }}>
<div className='joyride-app-explore' style={{ width: 560 }}>
<FilesExploreForm onBrowse={doFilesNavigateTo} />
</div>
<div className='dn flex-ns flex-auto items-center justify-end'>
<TourHelper />
<Connected className='joyride-app-status' />
<div className='pa3'>
<ThemeToggle />
</div>
</div>
</div>
<main className='bg-white pv3 pa3 pa4-l'>
Expand Down
4 changes: 4 additions & 0 deletions src/components/api-address-form/ApiAddressForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import { connect } from 'redux-bundler-react'
import { withTranslation } from 'react-i18next'
import Button from '../button/button.tsx'
import { checkValidAPIAddress } from '../../bundles/ipfs-provider.js'
import { useTheme } from '../../hooks/theme'

const ApiAddressForm = ({ t, doUpdateIpfsApiAddress, ipfsApiAddress, ipfsInitFailed }) => {
const [value, setValue] = useState(asAPIString(ipfsApiAddress))
const initialIsValidApiAddress = !checkValidAPIAddress(value)
const [showFailState, setShowFailState] = useState(initialIsValidApiAddress || ipfsInitFailed)
const [isValidApiAddress, setIsValidApiAddress] = useState(initialIsValidApiAddress)
const { darkTheme: isDarkTheme } = useTheme()

// Updates the border of the input to indicate validity
useEffect(() => {
Expand Down Expand Up @@ -46,12 +48,14 @@ const ApiAddressForm = ({ t, doUpdateIpfsApiAddress, ipfsApiAddress, ipfsInitFai
onChange={onChange}
onKeyPress={onKeyPress}
value={value}
style={{ background: isDarkTheme ? 'var(--filter-peers-dark)' : '', border: isDarkTheme ? '0.4px solid var(--border-color)' : '' }}
/>
<div className='tr'>
<Button
minWidth={100}
height={40}
className='mt2 mt0-l ml2-l tc'
style={{ background: isDarkTheme ? 'var(--input-btn-bg)' : '' }}
disabled={!isValidApiAddress || value === ipfsApiAddress}>
{t('actions.submit')}
</Button>
Expand Down
5 changes: 4 additions & 1 deletion src/components/box/Box.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import React from 'react'
import { useTheme } from '../../hooks/theme'
import ErrorBoundary from '../error/ErrorBoundary.js'

export const Box = ({
className = 'pa4',
style,
themed,
children,
...props
}) => {
const { darkTheme: isDarkTheme } = useTheme()
return (
<section className={className} style={{ background: '#fbfbfb', ...style }}>
<section className={className} style={{ background: isDarkTheme ? 'var(--element-bg)' : 'var(--element-bg-light)', ...style }}>
<ErrorBoundary>
{children}
</ErrorBoundary>
Expand Down
6 changes: 5 additions & 1 deletion src/components/public-gateway-form/PublicGatewayForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import { connect } from 'redux-bundler-react'
import { withTranslation } from 'react-i18next'
import Button from '../button/button.tsx'
import { checkValidHttpUrl, checkViaImgSrc, DEFAULT_PATH_GATEWAY } from '../../bundles/gateway.js'
import { useTheme } from '../../hooks/theme'

const PublicGatewayForm = ({ t, doUpdatePublicGateway, publicGateway }) => {
const [value, setValue] = useState(publicGateway)
const initialIsValidGatewayUrl = !checkValidHttpUrl(value)
const [showFailState, setShowFailState] = useState(initialIsValidGatewayUrl)
const [isValidGatewayUrl, setIsValidGatewayUrl] = useState(initialIsValidGatewayUrl)

const { darkTheme: isDarkTheme } = useTheme()
// Updates the border of the input to indicate validity
useEffect(() => {
setShowFailState(!isValidGatewayUrl)
Expand Down Expand Up @@ -60,6 +61,7 @@ const PublicGatewayForm = ({ t, doUpdatePublicGateway, publicGateway }) => {
onChange={onChange}
onKeyPress={onKeyPress}
value={value}
style={{ background: isDarkTheme ? 'var(--filter-peers-dark)' : '', border: isDarkTheme ? '0.4px solid var(--border-color)' : '' }}
/>
<div className='tr'>
<Button
Expand All @@ -68,6 +70,7 @@ const PublicGatewayForm = ({ t, doUpdatePublicGateway, publicGateway }) => {
height={40}
bg='bg-charcoal'
className='tc'
style={{ background: isDarkTheme ? 'var(--input-btn-bg)' : '' }}
disabled={value === DEFAULT_PATH_GATEWAY}
onClick={onReset}>
{t('app:actions.reset')}
Expand All @@ -77,6 +80,7 @@ const PublicGatewayForm = ({ t, doUpdatePublicGateway, publicGateway }) => {
minWidth={100}
height={40}
className='mt2 mt0-l ml2-l tc'
style={{ background: isDarkTheme ? 'var(--input-btn-bg)' : '' }}
disabled={!isValidGatewayUrl || value === publicGateway}>
{t('actions.submit')}
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import { connect } from 'redux-bundler-react'
import { withTranslation } from 'react-i18next'
import Button from '../button/button.tsx'
import { checkValidHttpUrl, checkSubdomainGateway, DEFAULT_SUBDOMAIN_GATEWAY } from '../../bundles/gateway.js'
import { useTheme } from '../../hooks/theme'

const PublicSubdomainGatewayForm = ({ t, doUpdatePublicSubdomainGateway, publicSubdomainGateway }) => {
const [value, setValue] = useState(publicSubdomainGateway)
const initialIsValidGatewayUrl = !checkValidHttpUrl(value)
const [isValidGatewayUrl, setIsValidGatewayUrl] = useState(initialIsValidGatewayUrl)
const { darkTheme: isDarkTheme } = useTheme()

// Updates the border of the input to indicate validity
useEffect(() => {
Expand Down Expand Up @@ -64,6 +66,7 @@ const PublicSubdomainGatewayForm = ({ t, doUpdatePublicSubdomainGateway, publicS
onChange={onChange}
onKeyPress={onKeyPress}
value={value}
style={{ background: isDarkTheme ? 'var(--filter-peers-dark)' : '', border: isDarkTheme ? '0.4px solid var(--border-color)' : '' }}
/>
<div className='tr'>
<Button
Expand All @@ -72,6 +75,7 @@ const PublicSubdomainGatewayForm = ({ t, doUpdatePublicSubdomainGateway, publicS
height={40}
bg='bg-charcoal'
className='tc'
style={{ background: isDarkTheme ? 'var(--input-btn-bg)' : '' }}
disabled={value === DEFAULT_SUBDOMAIN_GATEWAY}
onClick={onReset}>
{t('app:actions.reset')}
Expand All @@ -80,6 +84,7 @@ const PublicSubdomainGatewayForm = ({ t, doUpdatePublicSubdomainGateway, publicS
id='public-subdomain-gateway-submit-button'
minWidth={100}
height={40}
style={{ background: isDarkTheme ? 'var(--input-btn-bg)' : '' }}
className='mt2 mt0-l ml2-l tc'
disabled={!isValidGatewayUrl || value === publicSubdomainGateway}>
{t('actions.submit')}
Expand Down
7 changes: 6 additions & 1 deletion src/components/theme-toggle/theme-toggle.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.theme-toggle {
--size: 2rem;
--size: 1.55rem;
--icon-fill: hsl(210, 22%, 22%);
--icon-fill-hover: hsl(210, 22%, 12%);

Expand All @@ -20,11 +20,16 @@
inline-size: 100%;
block-size: 100%;
stroke-linecap: round;
color: #378085;
}

[data-theme='dark'] .theme-toggle {
--icon-fill: hsl(25, 100%, 50%);
--icon-fill-hover: hsl(25, 100%, 40%);

svg {
color: #fff;
}
}

.theme-toggle:hover,
Expand Down
3 changes: 1 addition & 2 deletions src/context/theme-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,11 @@ export const ThemeProvider = ({ children }: ThemeProviderProps) => {
return event.type === 'keydown'
}
if (isKeyboardEvent(event)) {
if (event.key === 'Enter' || event.key === ' ') {
if (event.key === ' ') {
event.preventDefault()
setDarkTheme((prevTheme) => !prevTheme)
}
}
setDarkTheme((prevTheme) => !prevTheme)
}
}
const values: ThemeContextValues = {
Expand Down
8 changes: 5 additions & 3 deletions src/files/explore-form/files-explore-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Button from '../../components/button/button'
import './files-explore-form.css'
// @ts-expect-error - need to fix types for ipfs-webui since we are a CJS consumer...
import { useExplore } from 'ipld-explorer-components/providers'
import { useTheme } from '../../hooks/theme'

/**
* @type {React.FC<{ onBrowse: (evt: { path: string }) => void }>} *
Expand All @@ -15,6 +16,7 @@ const FilesExploreForm = ({ onBrowse: onBrowseProp }) => {
const [path, setPath] = useState('')
const { doExploreUserProvidedPath } = useExplore()
const { t } = useTranslation('files')
const { darkTheme: isDarkTheme } = useTheme()

const trimmedPath = useMemo(() => {
return path.trim()
Expand Down Expand Up @@ -71,7 +73,7 @@ const FilesExploreForm = ({ onBrowse: onBrowseProp }) => {
<div data-id='FilesExploreForm' className='sans-serif black-80 flex'>
<div className='flex-auto'>
<div className='relative'>
<input id='ipfs-path' className={`input-reset bn pa2 mb2 db w-100 f6 br-0 placeholder-light ${inputClass}`} style={{ borderRadius: '3px 0 0 3px' }} type='text' placeholder='QmHash/bafyHash' aria-describedby='ipfs-path-desc' onChange={onChange} onKeyDown={onKeyDown} value={path} />
<input id='ipfs-path' className={`input-reset bn pa2 mb2 db w-100 f6 br-0 placeholder-light ${inputClass}`} style={{ borderRadius: '3px 0 0 3px', background: isDarkTheme ? 'var(--input-bg-dark)' : '' }} type='text' placeholder='QmHash/bafyHash' aria-describedby='ipfs-path-desc' onChange={onChange} onKeyDown={onKeyDown} value={path} />
<small id='ipfs-path-desc' className='o-0 absolute f6 black-60 db mb2'>Paste in a CID or IPFS path</small>
</div>
</div>
Expand All @@ -81,7 +83,7 @@ const FilesExploreForm = ({ onBrowse: onBrowseProp }) => {
disabled={!isValid}
danger={!isValid}
title={t('app:actions.inspect')}
style={{ borderRadius: '0 3px 3px 0' }}
style={{ borderRadius: '0 3px 3px 0', background: isDarkTheme ? 'var(--input-btn-bg)' : '' }}
onClick={onInspect}
bg='bg-teal'
className='ExploreFormButton button-reset pv1 ph2 ba f7 fw4 white overflow-hidden tc' >
Expand All @@ -92,7 +94,7 @@ const FilesExploreForm = ({ onBrowse: onBrowseProp }) => {
minWidth={0}
disabled={!isValid}
danger={!isValid}
style={{ borderRadius: '0' }}
style={{ borderRadius: '0', background: isDarkTheme ? 'var(--input-btn-bg)' : '' }}
title={t('app:actions.browse')}
onClick={onBrowse}
className='ExploreFormButton button-reset pv1 ph2 ba f7 fw4 white bg-gray overflow-hidden tc' >
Expand Down
22 changes: 13 additions & 9 deletions src/files/info-boxes/add-files-info/AddFilesInfo.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import React from 'react'
import { withTranslation, Trans } from 'react-i18next'
import Box from '../../../components/box/Box.js'
import { useTheme } from '../../../hooks/theme'

const AddFilesInfo = ({ t }) => (
<div className='mv4 tc navy f5' >
<Box style={{ background: 'rgba(105, 196, 205, 0.1)' }}>
<Trans i18nKey='addFilesInfo' t={t}>
<p className='ma0'>No files here yet! Add files to your local IPFS node by clicking the <strong>Import</strong> button above.</p>
</Trans>
</Box>
</div>
)
const AddFilesInfo = ({ t }) => {
const { darkTheme: isDarkTheme } = useTheme()
return (
<div className='mv4 tc navy f5' >
<Box style={{ background: isDarkTheme ? 'var(--teal-dark)' : 'rgba(105, 196, 205, 0.1)' }}>
<Trans i18nKey='addFilesInfo' t={t}>
<p className='ma0'>No files here yet! Add files to your local IPFS node by clicking the <strong>Import</strong> button above.</p>
</Trans>
</Box>
</div>
)
}

export default withTranslation('files')(AddFilesInfo)
36 changes: 33 additions & 3 deletions src/index.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
@import './reset.css';
@import "./reset.css";
@import "../node_modules/tachyons";
/* They forgot to include word break: https://github.com/tachyons-css/tachyons/issues/563 */
@import "../node_modules/tachyons/src/_word-break.css";
@import "../node_modules/ipfs-css";

:root {
--input-bg-dark: #121212;
--input-btn-bg: #2b2e30;
--teal-dark: #2b79801a;
--box-dark: #1a1c1e;
--world-map-text-dark: #e8e6e3;
--charcoal-muted: #9d9488;
--filter-peers-dark: #121212;
--element-bg-light: #fbfbfb;
--dataset-name: #d3dce4;
}

body {
overflow-y: scroll;
}
Expand All @@ -15,9 +27,14 @@ body {
--navy-dark: #0b3a53;
--navy-text-color: rgb(202, 198, 191);
--snow-muted: rgb(28, 30, 31);
--border-color: rgba(140, 130, 115, 0.5);

body {
transition: background .3s ease-in;
transition: background 0.3s ease-in;
}

h2, .black, .montserrat {
color: var(--world-map-text-dark) !important;
}

/* from inspecting the DOM, most of the classes here are from tachyon and ipfs-css
Expand All @@ -32,7 +49,7 @@ body {
}

section {
background: var(--element-bg) !important;
background: var(--element-bg);
}

.navy {
Expand All @@ -42,6 +59,19 @@ body {
.joyride-app-explore < div {
border: 1px solid red;
}

.webui-header {
background: var(--snow-muted) !important;
}

.ReactVirtualized__Table__headerRow {
background: var(--box-dark);
border-bottom: 1px solid var(--border-color);
}

.ReactVirtualized__Table__row {
border-bottom: 1px solid var(--border-color);
}
}

html #root {
Expand Down
4 changes: 0 additions & 4 deletions src/navigation/NavBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import StrokeIpld from '../icons/StrokeIpld.js'

// Styles
import './NavBar.css'
import { ThemeToggle } from '../components/theme-toggle/toggle'

const NavLink = ({
to,
Expand Down Expand Up @@ -74,9 +73,6 @@ export const NavBar = ({ t }) => {
</div>
</div>
<div className='dn db-l navbar-footer mb2 tc center f7 o-80 glow'>
<div className='mb4'>
<ThemeToggle />
</div>
{ gitRevision && <div className='mb1'>
<a className='link white' href={revisionUrl} target='_blank' rel='noopener noreferrer'>{t('app:terms.revision')} {gitRevision}</a>
</div> }
Expand Down
Loading

0 comments on commit b4b1c95

Please sign in to comment.