Created
January 9, 2022 20:30
-
-
Save koistya/54320473a36e1bdc30a20e164804a914 to your computer and use it in GitHub Desktop.
React.js, Material UI, TypeScript Playground https://stackblitz.com/edit/react-material-ui-typescript?file=src%2Findex.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* SPDX-FileCopyrightText: 2021-present Konstantin Tarkus (hello@endtest.dev) */ | |
/* SPDX-License-Identifier: MIT */ | |
import * as React from "react"; | |
import { TextField, Autocomplete } from "@mui/material"; | |
import type { AutocompleteProps } from "@mui/material"; | |
import { projects } from "./data"; | |
type Option = { id: string; label: string }; | |
type ComboboxProps = Omit< | |
AutocompleteProps<Option, undefined, undefined, undefined, undefined>, | |
"renderInput" | "options" | |
>; | |
/** | |
* TODO: Build a combobox based on Material UI Autocomplete component. | |
* | |
* @see https://mui.com/components/autocomplete/ | |
*/ | |
function Combobox(props: ComboboxProps): JSX.Element { | |
const { sx, ...other } = props; | |
const renderInput = React.useCallback( | |
(props) => <TextField placeholder="Select a project..." {...props} />, | |
[] | |
); | |
return ( | |
<Autocomplete | |
sx={{ /* CSS */ ...sx }} | |
options={projects} | |
renderInput={renderInput} | |
{...other} | |
/> | |
); | |
} | |
export { Combobox }; | |
export type { ComboboxProps }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* SPDX-FileCopyrightText: 2021-present Konstantin Tarkus (hello@endtest.dev) */ | |
/* SPDX-License-Identifier: MIT */ | |
const projects = [ | |
{ | |
id: "1", | |
label: "google.com", | |
}, | |
{ | |
id: "2", | |
label: "facebook.com", | |
}, | |
{ | |
id: "3", | |
label: "github.com", | |
}, | |
{ | |
id: "4", | |
label: "apple.com", | |
}, | |
{ | |
id: "5", | |
label: "amazon.com", | |
}, | |
{ | |
id: "6", | |
label: "youtube.com", | |
}, | |
{ | |
id: "7", | |
label: "wikipedia.org", | |
}, | |
{ | |
id: "8", | |
label: "reddit.com", | |
}, | |
{ | |
id: "9", | |
label: "bing.com", | |
}, | |
{ | |
id: "10", | |
label: "ebay.com", | |
}, | |
{ | |
id: "11", | |
label: "twitter.com", | |
}, | |
{ | |
id: "12", | |
label: "instagram.com", | |
}, | |
]; | |
export { projects }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="root"></div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* SPDX-FileCopyrightText: 2021-present Konstantin Tarkus (hello@endtest.dev) */ | |
/* SPDX-License-Identifier: MIT */ | |
import * as React from "react"; | |
import * as ReactDOM from "react-dom"; | |
import { Typography, CssBaseline, Container } from "@mui/material"; | |
import { Combobox } from "./combobox"; | |
import { AppToolbar } from "./toolbar"; | |
import { ThemeProvider } from "./theme"; | |
/** | |
* The top-level (root) React component. | |
* | |
* @see https://reactjs.org/ | |
* @see https://mui.com/core/ | |
*/ | |
function App(): JSX.Element { | |
return ( | |
<ThemeProvider> | |
<CssBaseline /> | |
<AppToolbar /> | |
<Container sx={{ my: 4 }}> | |
<Typography sx={{ mb: 2 }} variant="body2"> | |
Material UI Autocomplete playground 😁 See{" "} | |
<b> | |
<code>./src/combobox.tsx</code> | |
</b> | |
</Typography> | |
<Combobox /> | |
</Container> | |
</ThemeProvider> | |
); | |
} | |
ReactDOM.render(<App />, document.getElementById("root")); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "app", | |
"version": "0.0.0", | |
"private": true, | |
"scripts": { | |
"start": "webpack serve" | |
}, | |
"dependencies": { | |
"@babel/core": "^7.16.7", | |
"@babel/preset-react": "^7.16.7", | |
"@babel/preset-typescript": "^7.16.7", | |
"@emotion/react": "^11.7.1", | |
"@emotion/styled": "^11.6.0", | |
"@mui/icons-material": "^5.2.5", | |
"@mui/material": "^5.2.7", | |
"@types/react": "^17.0.38", | |
"@types/react-dom": "^17.0.11", | |
"babel-loader": "^8.2.3", | |
"html-webpack-plugin": "^5.5.0", | |
"react": "^17.0.2", | |
"react-dom": "^17.0.2", | |
"typescript": "^4.5.4", | |
"webpack": "^5.65.0", | |
"webpack-cli": "^4.9.1", | |
"webpack-dev-server": "^4.7.2" | |
}, | |
"prettier": { | |
"singleQuote": false | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* SPDX-FileCopyrightText: 2021-present Konstantin Tarkus (hello@endtest.dev) */ | |
/* SPDX-License-Identifier: MIT */ | |
import * as React from "react"; | |
import { | |
PaletteMode, | |
ThemeProvider as MuiThemeProvider, | |
useTheme as useMuiTheme, | |
} from "@mui/material"; | |
import type { Theme } from "@mui/material"; | |
import { createTheme as createMuiTheme } from "@mui/material/styles"; | |
type ThemeProviderProps = { children: React.ReactNode }; | |
const ToggleThemeContext = React.createContext(() => {}); | |
/** | |
* Creates a customized version of Material UI theme. | |
* | |
* @see https://mui.com/customization/theming/ | |
* @see https://mui.com/customization/default-theme/ | |
*/ | |
function createTheme(mode: PaletteMode): Theme { | |
return createMuiTheme({ | |
palette: { | |
mode, | |
background: { | |
default: mode === "light" ? "rgba(242,246,252,1)" : "#121212", | |
}, | |
}, | |
}); | |
} | |
function ThemeProvider(props: ThemeProviderProps): JSX.Element { | |
const [theme, setTheme] = React.useState(() => createTheme("light")); | |
const changeTheme = React.useCallback(() => { | |
setTheme(createTheme(theme.palette.mode === "light" ? "dark" : "light")); | |
}, [theme.palette.mode]); | |
return ( | |
<MuiThemeProvider theme={theme}> | |
<ToggleThemeContext.Provider value={changeTheme}> | |
{props.children} | |
</ToggleThemeContext.Provider> | |
</MuiThemeProvider> | |
); | |
} | |
function useTheme(): [Theme, () => void] { | |
return [useMuiTheme(), React.useContext(ToggleThemeContext)]; | |
} | |
export { ThemeProvider, useTheme }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* SPDX-FileCopyrightText: 2021-present Konstantin Tarkus (hello@endtest.dev) */ | |
/* SPDX-License-Identifier: MIT */ | |
import * as React from "react"; | |
import { Typography, Toolbar, AppBar, IconButton } from "@mui/material"; | |
import { LightMode, DarkMode } from "@mui/icons-material"; | |
import type { ToolbarProps } from "@mui/material"; | |
import { useTheme } from "./theme"; | |
type AppToolbarProps = Omit<ToolbarProps, "children">; | |
/** | |
* Application toolbar. | |
* | |
* @see https://mui.com/components/app-bar/ | |
*/ | |
function AppToolbar(props: AppToolbarProps): JSX.Element { | |
const [theme, toggleTheme] = useTheme(); | |
return ( | |
<React.Fragment> | |
<AppBar {...props}> | |
<Toolbar> | |
<Typography sx={{ fontSize: "1.5rem", flexGrow: 1 }} variant="h3"> | |
Material UI Playground | |
</Typography> | |
<IconButton color="inherit" onClick={toggleTheme}> | |
{theme.palette.mode === "light" ? <DarkMode /> : <LightMode />} | |
</IconButton> | |
</Toolbar> | |
</AppBar> | |
<Toolbar /> | |
</React.Fragment> | |
); | |
} | |
export { AppToolbar }; | |
export type { AppToolbarProps }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Show hidden characters
{ | |
"compilerOptions": { | |
"target": "ESnext", | |
"module": "ESNext", | |
"jsx": "preserve", | |
"allowJs": true, | |
"noImplicitAny": true, | |
"noEmit": true, | |
"moduleResolution": "node", | |
"sourceMap": true | |
}, | |
"include": ["src/**/*.ts", "src/**/*.tsx"] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* SPDX-FileCopyrightText: 2021-present Konstantin Tarkus (hello@endtest.dev) */ | |
/* SPDX-License-Identifier: MIT */ | |
const HtmlWebpackPlugin = require("html-webpack-plugin"); | |
module.exports = { | |
entry: "./src/index", | |
mode: "development", | |
output: { | |
publicPath: "auto", | |
}, | |
resolve: { | |
extensions: [".tsx", ".ts", ".js"], | |
}, | |
module: { | |
rules: [ | |
{ | |
test: /\.tsx?$/, | |
loader: "babel-loader", | |
exclude: /node_modules/, | |
options: { | |
presets: [ | |
[ | |
"@babel/preset-react", | |
{ | |
jsx: "react-jsx", | |
jsxImportSource: "@emotion/react", | |
}, | |
], | |
"@babel/preset-typescript", | |
], | |
plugins: ["@emotion"], | |
}, | |
}, | |
], | |
}, | |
plugins: [ | |
new HtmlWebpackPlugin({ | |
template: "./public/index.html", | |
}), | |
], | |
devServer: { | |
port: 3000, | |
}, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment