mirror of
https://github.com/Steffo99/sophon.git
synced 2024-12-22 14:54:22 +00:00
🔧 Use "LookAndFeel" components to handle theme
This commit is contained in:
parent
4a55af35f9
commit
bde02c0928
5 changed files with 125 additions and 17 deletions
|
@ -1,24 +1,21 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {LayoutThreeCol} from "@steffo/bluelib-react";
|
import {LayoutThreeCol} from "@steffo/bluelib-react";
|
||||||
import {Router} from "./routes/Router";
|
import {Router} from "./routes/Router";
|
||||||
import {InstanceContextProvider} from "./components/legacy/login/InstanceContext";
|
import {LookAndFeel} from "./components/theme/LookAndFeel";
|
||||||
import {LoginContextProvider} from "./components/legacy/login/LoginContext";
|
|
||||||
import {InstanceBluelib} from "./components/legacy/login/InstanceBluelib";
|
|
||||||
|
|
||||||
function App() {
|
|
||||||
|
export default function App() {
|
||||||
return (
|
return (
|
||||||
<InstanceContextProvider>
|
<LookAndFeel>
|
||||||
<LoginContextProvider>
|
<LookAndFeel.Bluelib>
|
||||||
<InstanceBluelib>
|
<LookAndFeel.PageTitle/>
|
||||||
<LayoutThreeCol>
|
<LayoutThreeCol>
|
||||||
<LayoutThreeCol.Center>
|
<LayoutThreeCol.Center>
|
||||||
|
<LookAndFeel.Heading level={1}/>
|
||||||
<Router/>
|
<Router/>
|
||||||
</LayoutThreeCol.Center>
|
</LayoutThreeCol.Center>
|
||||||
</LayoutThreeCol>
|
</LayoutThreeCol>
|
||||||
</InstanceBluelib>
|
</LookAndFeel.Bluelib>
|
||||||
</LoginContextProvider>
|
</LookAndFeel>
|
||||||
</InstanceContextProvider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App;
|
|
||||||
|
|
52
frontend/src/components/theme/LookAndFeel.tsx
Normal file
52
frontend/src/components/theme/LookAndFeel.tsx
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
import * as React from "react"
|
||||||
|
import * as ReactDOM from "react-dom"
|
||||||
|
import {LookAndFeelBluelib} from "./LookAndFeelBluelib";
|
||||||
|
import {LookAndFeelHeading} from "./LookAndFeelHeading";
|
||||||
|
import {LookAndFeelPageTitle} from "./LookAndFeelPageTitle";
|
||||||
|
|
||||||
|
|
||||||
|
export interface LookAndFeelState {
|
||||||
|
bluelibTheme: "sophon" | "royalblue" | "paper" | "hacker",
|
||||||
|
pageTitle: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface LookAndFeelContextData extends LookAndFeelState {
|
||||||
|
setLookAndFeel: React.Dispatch<React.SetStateAction<LookAndFeelState>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const LookAndFeelContext = React.createContext<LookAndFeelContextData>({
|
||||||
|
bluelibTheme: "sophon",
|
||||||
|
pageTitle: "Sophon",
|
||||||
|
|
||||||
|
setLookAndFeel: () => console.error("Can't setLookAndFeel outside a lookAndFeelContext.")
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
export interface LookAndFeelProps {
|
||||||
|
children: React.ReactNode,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function LookAndFeel({children}: LookAndFeelProps): JSX.Element {
|
||||||
|
const [lookAndFeel, setLookAndFeel] =
|
||||||
|
React.useState<LookAndFeelState>({
|
||||||
|
bluelibTheme: "sophon",
|
||||||
|
pageTitle: "Sophon",
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<LookAndFeelContext.Provider value={{
|
||||||
|
...lookAndFeel,
|
||||||
|
setLookAndFeel,
|
||||||
|
}}>
|
||||||
|
{children}
|
||||||
|
</LookAndFeelContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LookAndFeel.Bluelib = LookAndFeelBluelib
|
||||||
|
LookAndFeel.Heading = LookAndFeelHeading
|
||||||
|
LookAndFeel.PageTitle = LookAndFeelPageTitle
|
20
frontend/src/components/theme/LookAndFeelBluelib.tsx
Normal file
20
frontend/src/components/theme/LookAndFeelBluelib.tsx
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import * as React from "react"
|
||||||
|
import {useContext} from "react";
|
||||||
|
import {LookAndFeelContext} from "./LookAndFeel";
|
||||||
|
import {Bluelib} from "@steffo/bluelib-react";
|
||||||
|
|
||||||
|
|
||||||
|
interface LookAndFeelBluelibProps {
|
||||||
|
children: React.ReactNode,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function LookAndFeelBluelib({children}: LookAndFeelBluelibProps): JSX.Element {
|
||||||
|
const lookAndFeel = useContext(LookAndFeelContext)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Bluelib theme={lookAndFeel.bluelibTheme}>
|
||||||
|
{children}
|
||||||
|
</Bluelib>
|
||||||
|
)
|
||||||
|
}
|
21
frontend/src/components/theme/LookAndFeelHeading.tsx
Normal file
21
frontend/src/components/theme/LookAndFeelHeading.tsx
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import * as React from "react"
|
||||||
|
import {HeadingProps} from "@steffo/bluelib-react/dist/components/common/Heading";
|
||||||
|
import {Heading} from "@steffo/bluelib-react";
|
||||||
|
import {useContext} from "react";
|
||||||
|
import {LookAndFeelContext} from "./LookAndFeel";
|
||||||
|
|
||||||
|
|
||||||
|
interface LookAndFeelHeadingProps extends HeadingProps {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function LookAndFeelHeading({...props}: LookAndFeelHeadingProps): JSX.Element {
|
||||||
|
const lookAndFeel = useContext(LookAndFeelContext)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Heading {...props}>
|
||||||
|
{lookAndFeel.pageTitle}
|
||||||
|
</Heading>
|
||||||
|
)
|
||||||
|
}
|
18
frontend/src/components/theme/LookAndFeelPageTitle.tsx
Normal file
18
frontend/src/components/theme/LookAndFeelPageTitle.tsx
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import * as React from "react"
|
||||||
|
import * as ReactDOM from "react-dom"
|
||||||
|
import {useContext} from "react";
|
||||||
|
import {LookAndFeelContext} from "./LookAndFeel";
|
||||||
|
|
||||||
|
|
||||||
|
export function LookAndFeelPageTitle(): null {
|
||||||
|
const lookAndFeel = useContext(LookAndFeelContext)
|
||||||
|
|
||||||
|
React.useEffect(
|
||||||
|
() => {
|
||||||
|
document.title = lookAndFeel.pageTitle === "Sophon" ? "Sophon" : `${lookAndFeel.pageTitle} - Sophon`
|
||||||
|
},
|
||||||
|
[lookAndFeel.pageTitle]
|
||||||
|
)
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
Loading…
Reference in a new issue