Enhancing Material UI v4 Themes using TypeScript

I am attempting to implement my own custom palette option in the theme section, but I am struggling with how to do the augmentation part using TypeScript.

So far, I have created a file named "material-ui.d.ts" and inside it, I only have:

import { PaletteOptions } from "@material-ui/core/styles/createPalette";

declare module "@material-ui/core/styles/createPalette" {}

On the Theme level, I want to introduce a new element called kzprimary, which will have its own color properties that I can use instead of the default primary and secondary colors provided by Material UI.

import { createTheme, ThemeProvider, colors } from "@material-ui/core";

const basic = createTheme({});

const alternative = createTheme({
    palette: {
        primary: {
            main: colors.purple[500],
        },
        secondary: {
            main: colors.pink[500],
        },
    },
});

const kaizenTest = createTheme({
    palette: {
        primary: {
            main: colors.blue[500],
        },
        kzprimary: {
            main: colors.pink[500],
        },
    },
});

const applyTheme = (label: string) => {
    switch (label) {
        default:
        case "basic":
            return basic;
        case "alternative":
            return alternative;
        case "kaizen":
            return kaizenTest;
    }
};

export default applyTheme;
export { ThemeProvider, applyTheme };

I am unsure about what needs to be edited within material-ui.d.ts to make this functionality work.

Could someone please provide me with guidance? The kaizenTest is the theme I pass to my ThemeProvider at the app level, where it applies the themes. It's worth noting that I am working with version 4 of Material UI as mandated by my company, so I hope Augmentation is achievable in v4.

Below is my APP index.tsx file:

import KaizenRouter from "router";
import { BrowserRouter } from "react-router-dom";
import CssBaseline from "@material-ui/core/CssBaseline";
import comms from "components/comms/class";
import CommsContext, { useSelector } from "components/comms";
import { Provider } from "react-redux";
import { store } from "./store";
import { getSettings } from "./selectors";
import { applyTheme, ThemeProvider } from "themes";
import { SnackbarProvider } from "notistack";

const App = () => {
    return (
        <CommsContext.Provider value={comms}>
            <Storage />
        </CommsContext.Provider>
    );
};

const Storage = () => {
    return (
        <Provider store={store}>
            <Theme />
        </Provider>
    );
};
const Theme = () => {
    const { theme } = useSelector(getSettings);
    return (
        <ThemeProvider theme={applyTheme("kaizenTest")}>
            <SnackbarProvider
                maxSnack={3}
                preventDuplicate
                anchorOrigin={{
                    vertical: "top",
                    horizontal: "center",
                }}
            >
                <BrowserRouter>
                    <CssBaseline />
                    {/* <StrictMode> */}
                    <KaizenRouter />
                    {/* </StrictMode> */}
                </BrowserRouter>
            </SnackbarProvider>
        </ThemeProvider>
    );
};

export default App;

Answer №1

I have finally come to a solution.

All you need to do is include the interfaces in your file and then the augmentation process will function properly.

import { createTheme, ThemeProvider, colors } from "@material-ui/core";

const basic = createTheme({});

const alternative = createTheme({
    palette: {
        primary: {
            main: colors.purple[500],
        },
        kzprimary: {
            main: colors.orange[500]
        },
        secondary: {
            main: colors.pink[500],
        },

    },
});

const kaizenTest = createTheme({
    palette: {
        primary: {
            main: "#1A2846",
        },
        kzprimary: {
            main: colors.orange[500],
        },
        background: {
            default: '#DDDDDD'
        }
    },
});

declare module '@material-ui/core/styles/createPalette' {
    interface Palette {
        kzprimary?: Palette['primary'],
    }
    interface PaletteOptions {
        kzprimary?: PaletteOptions['primary'],
    }
}

const applyTheme = (label: string) => {
    switch (label) {
        default:
        case "basic":
            return basic;
        case "alternative":
            return alternative;
        case "kaizen":
            return kaizenTest;
    }
};

export default applyTheme;
export { ThemeProvider, applyTheme };

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I am experiencing difficulty in successfully transmitting a variable from my jQuery code to my PHP code

I've been attempting to pass a variable from my jQuery code to my HTML/PHP code using AJAX and POST. However, I'm encountering an error message stating "Notice: Undefined index: testData in C:\xampp\htdocs\teszt\test1.php on l ...

Substitute this.bindMethod for function component

I have a class component that is structured like this: interface MyProps { addingCoord: any resetCoords: any } interface MyState { x: any y: any } class DrawerOld extends React.Component<MyProps, MyState> { width: number height: number ...

Angular tutorial: Organizing data by date only

This is my first time building an Angular app. I am fetching JSON data from an API using a factory service to get football match fixtures. My goal is to group these fixtures by date while disregarding the time component. The date string in the JSON is fo ...

React-mdl Error: Assertion failed: You must avoid using <Link> outside of a <Router>. The website is not properly being directed

index.js import React from 'react'; import {BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom'; import home from './home'; import about from './about'; import menu from './menu'; impor ...

Tips for calculating the canvas-relative mouse position on a CSS 3D transformed canvas

Recently decided to challenge myself by experimenting with drawing on 3D transformed canvases. After some trial and error, I managed to get it partially working. const m4 = twgl.m4; [...document.querySelectorAll('canvas')].forEach((canvas) =& ...

Getting row data in datatables after a button click: A step-by-step guide

Could somebody provide assistance with retrieving a single row of data on a click event? This table is dynamically populated after the AJAX call's Success function is executed <div class="table-responsive table-wrap tableFixHead container-flu ...

Storing additional data from extra text boxes into your database can be achieved using AJAX or PHP. Would you

A dynamic text box has been created using Jquery/JavaScript, allowing users to click on an "Add More" button to add additional input boxes for entering data. However, a challenge arises when attempting to store this user-generated data in a database. Assi ...

"Encountering issue with componentDidMount() not functioning as expected, despite debugger being

Hello everyone! This is my first time sharing something here, so I'm eager to hear your feedback on both how I've posted and the content itself. I've only been programming for 8 weeks now, so I'm sure there are plenty of mistakes in wha ...

Using jQuery to determine if the child element is a <ul> tag

HTML: <ul class="menu"> <li><a href="http://example.com">Text</a> <ul> <li><a href="http://example.com">Text</a> <li><a href="#">Text</a> <li><a href="# ...

Running the JavaScript code on a webpage using Selenium WebDriver

I am currently in the process of creating an automated test for a website, and I am encountering some difficulty trying to execute a specific function within the site's code. Upon inspecting the developer tools, I have identified the function I need ...

Inferring types in a generic function with multiple parameters

In my attempt to configure a generic with the parameter serving as the key of another object, I have found success using extends keyof when both types are provided as parameters to the function. However, I encountered an issue when the type that provides ...

What is the process for evaluating the variable `results` in this scenario?

Can anyone provide some insight on how this code is functioning? I grasp the concept of callbacks but during a tutorial video, I encountered this code snippet: function addAndHandle(n1, n2, cb) { const result = n1 + n2; cb(result); } addAndHandle ...

The JSONP request failed with an error stating: ReferenceError: document is not defined

My internship project involves developing a mobile application based on the website www.claroline.net using Nativescript and Angular 2. I have successfully implemented the login function, allowing users to sign in to the app. Next, I need to integrate not ...

Leverage the power of JavaScript validation combined with jQuery

Hello, I'm relatively new to the world of Javascript and jQuery. My goal is to create a suggestion box that opens when a user clicks on a specific button or div element. This box should only be visible to logged-in users. I have some knowledge on how ...

"The 'BillInvoice' object must be assigned a primary key value before it is ready for this relationship" - Error Message

There is an issue in my Django project related to the creation of a BillInvoice and its associated BillLineItem instances. The error message I'm receiving states: "'BillInvoice' instance needs to have a primary key value before this re ...

Executing child processes in the Mean Stack environment involves utilizing the `child_process`

I am working on a Mean application that utilizes nodejs, angularjs and expressjs. In my setup, the server is called from the angular controller like this: Angular Controller.js $http.post('/sample', $scope.sample).then(function (response) ...

Tips for implementing AngularJS on a webpage transfer

I am a beginner in learning AngularJS. I have gone through the basic tips on W3Schools, but now I am stuck on implementing the login function. When I click the "sign in" button, the webpage should redirect to the login page of the website. However, I am ...

Testing a click event in Angular that triggers only the navigateByUrl function, utilizing Jasmin and Karma

Need help writing unit test cases for click events in Angular using Jasmine & Karma onClickCancel(): any { this.router.navigateByUrl('login'); } Seeking advice on how to write unit tests for click events that open Material dia ...

Using Angular promises and the $http service

ng.module('app') .service('CardService', ['$http', CardService]) function CardService($http) { this.$http = $http; var self = this; $http.get('http://localhost:3000/db').success(function(data) { ...

Issues with using hooks in a remote module in Webpack 5 module federation

I am attempting to create a dynamic system at runtime using Module Federation, a feature in webpack 5. Everything seems to be working well, but I encounter a multitude of 'invalid rule of hooks' errors when I add hooks to the 'producer' ...