Skip to content

Commit

Permalink
feat: Add BarTheme
Browse files Browse the repository at this point in the history
This new component allows you to change the CozyTheme variant of the cozy-bar. The useContext is no longer exposed, as it can lead to infinite re-renders.
  • Loading branch information
cballevre committed Feb 15, 2024
1 parent daaacf9 commit ca5ce4f
Show file tree
Hide file tree
Showing 10 changed files with 57 additions and 211 deletions.
21 changes: 1 addition & 20 deletions src/components/Bar.jsx
Expand Up @@ -12,7 +12,6 @@ import Drawer from 'components/Drawer'
import Settings from 'components/Settings'
import Apps from 'components/Apps'
import {
getTheme,
hasFetched,
fetchApps,
fetchContext,
Expand All @@ -39,8 +38,6 @@ export const Bar = ({
fetchApps,
isPublic,
onDrawer,
theme,
themeOverrides,
barLeft,
barRight,
barCenter,
Expand Down Expand Up @@ -129,22 +126,8 @@ export const Bar = ({
return !isPublic ? <Settings onLogOut={onLogOut} /> : null
}

const {
primaryColor: pColor,
primaryContrastTextColor: pctColor
} = themeOverrides
const pStyle = pColor ? { '--cozBarThemePrimaryColor': pColor } : {}
const pctStyle = pctColor
? { '--cozBarThemePrimaryContrastTextColor': pctColor }
: {}
const themeStyle = { ...pStyle, ...pctStyle }

return (
<div
className={`coz-bar-wrapper coz-theme-${theme}`}
style={themeStyle}
data-testid="coz-bar-wrapper"
>
<div className="coz-bar-wrapper" data-testid="coz-bar-wrapper">
<div id="cozy-bar-modal-dom-place" />
<div className="coz-bar-container">
{barLeft || renderLeft()}
Expand Down Expand Up @@ -179,8 +162,6 @@ Bar.propTypes = {
}

export const mapStateToProps = state => ({
theme: getTheme(state).name,
themeOverrides: getTheme(state).overrides,
hasFetchedApps: hasFetched(state)
})

Expand Down
21 changes: 0 additions & 21 deletions src/components/Bar.spec.jsx
Expand Up @@ -30,8 +30,6 @@ describe('Bar', () => {
fetchContext = mockFetchContext,
fetchApps = mockFetchApps,
fetchSettingsData = mockFetchSettingsData,
theme = 'default',
themeOverrides = {},
isPublic = false,
hasFetchedApps = false,
client
Expand All @@ -42,8 +40,6 @@ describe('Bar', () => {
fetchContext={fetchContext}
fetchApps={fetchApps}
fetchSettingsData={fetchSettingsData}
theme={theme}
themeOverrides={themeOverrides}
isPublic={isPublic}
hasFetchedApps={hasFetchedApps}
onDrawer={jest.fn()}
Expand Down Expand Up @@ -94,23 +90,6 @@ describe('Bar', () => {
expect(mockFetchApps).toHaveBeenCalledTimes(2)
})

it('should change theme', () => {
setup({ theme: 'primary' })

const wrapper = screen.getByTestId('coz-bar-wrapper')

expect(wrapper.className).toBe('coz-bar-wrapper coz-theme-primary')
})

it.skip('should change allow theme overrides', () => {
setup({ theme: 'primary', themeOverrides: { primaryColor: 'red' } })

const wrapper = screen.getByTestId('coz-bar-wrapper')

// TODO : This not working because JSDom doesn't support CSS variables
expect(wrapper).toHaveStyle('--cozBarThemePrimaryColor: red')
})

it('should call re-fetch data when token is refreshed', () => {
const client = new CozyClient({})
setup({ client: client })
Expand Down
17 changes: 3 additions & 14 deletions src/components/BarComponent.jsx
@@ -1,12 +1,7 @@
import React, { useLayoutEffect, useState, useEffect } from 'react'
import { createPortal } from 'react-dom'

import {
onRealtimeCreate,
onRealtimeDelete,
setInfos,
setTheme
} from 'lib/reducers'
import { onRealtimeCreate, onRealtimeDelete, setInfos } from 'lib/reducers'

import {
getAppName,
Expand Down Expand Up @@ -97,7 +92,7 @@ const BarComponent = ({
onLogOut
}) => {
const barContext = useBarContext()
const { barSearch, barLeft, barCenter, barRight, theme, themeOverrides } =
const { barSearch, barLeft, barCenter, barRight, themeVariant } =
barContext || {}

const [wrapperElement, setWrapperElement] = useState(null)
Expand Down Expand Up @@ -142,19 +137,13 @@ const BarComponent = ({
}
}

useEffect(() => {
if (theme) {
reduxStore.dispatch(setTheme(theme, themeOverrides || {}))
}
})

return (
<ReactPortal
wrapperElement={wrapperElement}
setWrapperElement={setWrapperElement}
>
<Provider store={options.reduxStore}>
<CozyTheme>
<CozyTheme variant={themeVariant}>
<Bar
{...options}
barSearch={barSearch}
Expand Down
56 changes: 27 additions & 29 deletions src/components/BarProvider.jsx
@@ -1,4 +1,10 @@
import React, { createContext, useContext, useState, useCallback } from 'react'
import React, {
createContext,
useContext,
useState,
memo,
useMemo
} from 'react'

const BarContext = createContext()

Expand All @@ -10,37 +16,29 @@ const BarProvider = ({ children }) => {
const [barRight, setBarRight] = useState(null)
const [barLeft, setBarLeft] = useState(null)
const [barSearch, setBarSearch] = useState(null)
const [theme, setTheme] = useState()
const [themeOverrides, setThemeOverrides] = useState()
const [themeVariant, setThemeVariant] = useState('normal')

const handleThemeChange = useCallback((theme, overrides) => {
setTheme(theme)
if (overrides) {
setThemeOverrides(overrides)
}
}, [])

return (
<BarContext.Provider
value={{
barCenter,
setBarCenter,
barRight,
setBarRight,
barLeft,
setBarLeft,
barSearch,
setBarSearch,
setTheme: handleThemeChange,
themeOverrides,
theme
}}
>
{children}
</BarContext.Provider>
const value = useMemo(
() => ({
barCenter,
setBarCenter,
barRight,
setBarRight,
barLeft,
setBarLeft,
barSearch,
setBarSearch,
themeVariant,
setThemeVariant
}),
[barCenter, barLeft, barRight, barSearch, themeVariant]
)

return <BarContext.Provider value={value}>{children}</BarContext.Provider>
}

const useBarContext = () => useContext(BarContext)

export { BarProvider, BarContext, useBarContext }
export { BarContext, useBarContext }

export default memo(BarProvider)
22 changes: 22 additions & 0 deletions src/components/BarTheme.jsx
@@ -0,0 +1,22 @@
import { useEffect } from 'react'

import { useBarContext } from './BarProvider'

function BarTheme({ variant }) {
const barContext = useBarContext()

useEffect(() => {
if (barContext && barContext.setTheme !== undefined) {
barContext.setThemeVariant(variant)
return () => {
barContext.setThemeVariant('normal')
}
} else {
console.warn('You should not use BarTheme outside of a BarProvider')
}
}, [barContext, variant])

return null
}

export { BarTheme }
49 changes: 0 additions & 49 deletions src/components/__snapshots__/Bar.spec.jsx.snap

This file was deleted.

3 changes: 2 additions & 1 deletion src/index.jsx
Expand Up @@ -6,7 +6,8 @@ export { BarComponent } from './components/BarComponent'
export { BarLeft } from './components/BarLeft'
export { BarRight } from './components/BarRight'
export { BarCenter } from './components/BarCenter'
export { BarTheme } from './components/BarTheme'
export { BarSearch } from './components/BarSearch'
export { BarProvider, useBarContext } from './components/BarProvider'
export { default as BarProvider } from './components/BarProvider'

export const version = __VERSION__
15 changes: 2 additions & 13 deletions src/lib/reducers/index.js
@@ -1,5 +1,4 @@
import { combineReducers } from 'redux'
import * as theme from 'lib/reducers/theme'
import appsReducer, * as apps from 'lib/reducers/apps'
import settingsReducer, * as settings from 'lib/reducers/settings'
import contextReducer, * as context from 'lib/reducers/context'
Expand All @@ -10,22 +9,13 @@ const proxy = (attr, method) => {
}
}

const setTheme = theme.setTheme
const fetchApps = apps.fetchApps
const setInfos = apps.setInfos
const fetchSettingsData = settings.fetchSettingsData
const logOut = settings.logOut
const fetchContext = context.fetchContext
export {
setTheme,
fetchApps,
setInfos,
fetchSettingsData,
logOut,
fetchContext
}
export { fetchApps, setInfos, fetchSettingsData, logOut, fetchContext }

export const getTheme = proxy('theme', theme.getTheme)
export const getApps = proxy('apps', apps.getApps)
export const getHomeApp = proxy('apps', apps.getHomeApp)
export const isFetchingApps = proxy('apps', apps.isFetchingApps)
Expand All @@ -44,8 +34,7 @@ export const onRealtimeDelete = apps.deleteApp
export const reducers = {
apps: appsReducer,
context: contextReducer,
settings: settingsReducer,
theme: theme.reducer
settings: settingsReducer
}

export default combineReducers(reducers)
48 changes: 0 additions & 48 deletions src/lib/reducers/theme.js

This file was deleted.

0 comments on commit ca5ce4f

Please sign in to comment.