Files
oxygen-ui/src/components/ReactPlayground/Provider.tsx

96 lines
2.5 KiB
TypeScript

import React from 'react'
import { IFiles, IPlaygroundContext, ITheme } from '@/components/ReactPlayground/shared.ts'
import { MAIN_FILE_NAME } from '@/components/ReactPlayground/files.ts'
import {
fileNameToLanguage,
setPlaygroundTheme,
strToBase64
} from '@/components/ReactPlayground/utils.ts'
const initialContext: Partial<IPlaygroundContext> = {
selectedFileName: MAIN_FILE_NAME
}
export const PlaygroundContext = createContext<IPlaygroundContext>(
initialContext as IPlaygroundContext
)
interface ProviderProps extends React.PropsWithChildren {
saveOnUrl?: boolean
}
const Provider: React.FC<ProviderProps> = ({ children, saveOnUrl }) => {
const [files, setFiles] = useState<IFiles>({})
const [theme, setTheme] = useState(initialContext.theme!)
const [selectedFileName, setSelectedFileName] = useState(initialContext.selectedFileName!)
const [filesHash, setFilesHash] = useState('')
const addFile = (name: string) => {
files[name] = {
name,
language: fileNameToLanguage(name),
value: ''
}
setFiles({ ...files })
}
const removeFile = (name: string) => {
delete files[name]
setFiles({ ...files })
}
const changeFileName = (oldFileName: string, newFileName: string) => {
if (!files[oldFileName] || !newFileName) {
return
}
const { [oldFileName]: value, ...other } = files
const newFile: IFiles = {
[newFileName]: {
...value,
language: fileNameToLanguage(newFileName),
name: newFileName
}
}
setFiles({
...other,
...newFile
})
}
const changeTheme = (theme: ITheme) => {
setPlaygroundTheme(theme)
setTheme(theme)
}
useEffect(() => {
const hash = strToBase64(JSON.stringify(files))
if (saveOnUrl) {
window.location.hash = hash
}
setFilesHash(hash)
}, [files])
return (
<PlaygroundContext.Provider
value={{
theme,
filesHash,
files,
selectedFileName,
setTheme,
changeTheme,
setSelectedFileName,
setFiles,
addFile,
removeFile,
changeFileName
}}
>
{children}
</PlaygroundContext.Provider>
)
}
export default Provider