Challenges arise when attempting to share a theme across different repositories within a Storybook monorepo that utilizes

In my unique project setup, I have a singular repository containing atoms, molecules, and organisms along with storybooks to develop a custom components library. This library is based on MUI framework with a customized theme applied, all built with TypeScript.

While using MUI has simplified the development of custom components, it has also led to time-consuming efforts in resolving various issues that arise during the build process.

About the Theme

Within the 'atoms' repository, I have included our custom theme JSON file which is utilized by other repositories ('molecules' and 'organisms') as well as exported as part of the atom's library for external projects. The base theme is derived from MUI but has been enhanced with branding changes and custom colors, causing some challenges. To address this, I have created a createPalette.d.ts file in the 'Theme/' folder to declare these additional colors:

import '@mui/material/styles';

declare module '@mui/material/styles' {
  interface Palette {
    myColor: Palette['primary'];
  }

  interface PaletteOptions {
    myColor?: PaletteOptions['primary'];
  }
}

// Updated Button's props to include the custom color
declare module '@mui/material/Button' {
  interface ButtonPropsColorOverrides {
    myColor: true;
  }
}

This theme configuration is then applied in each repository's '.storybook/preview.js' file as shown below:

import { ThemeProvider as MUIThemeProvider, createTheme } from '@mui/material/styles';
import { ThemeProvider } from 'emotion-theming';
import theme from '../stories/Theme';
import { withThemes } from '@react-theming/storybook-addon';

const providerFn = ({ theme, children }) => {
  // fix for compatibility between emotion and mui theming
  const serialTheme = JSON.parse(JSON.stringify(theme));
  const muiTheme = createTheme(serialTheme);

  return (
    <MUIThemeProvider theme={muiTheme}>
      <ThemeProvider theme={muiTheme}>{children}</ThemeProvider>
    </MUIThemeProvider>
  );
};
const themingDecorator = withThemes(null, [theme], {
  providerFn,
});

export const decorators = [themingDecorator];

Although everything appears to function properly, there is still an underlying issue. Every time I attempt to access the custom colors like theme.palette.myColor.main, I encounter the following error:

Property 'myColor' does not exist on type 'Palette'.ts(2339)

I have discovered that while copying the 'createPalette.d.ts' file to another repository resolves the autocomplete issue, it still results in an error during the build process:

stories/ComponentFolder/index.tsx: error TS2339: Property 'myColor' does not exist on type 'Palette'.

My Considerations

  1. The most apparent solution seems to be importing/extending 'createPalette.d.ts' in other repositories, yet implementing this approach raises concerns about potential building errors.
  2. I am uncertain if importing the theme into other projects will yield positive results, especially regarding the 'not existing on type 'Palette'' property error.
  3. Perhaps there is a better strategy for storing and applying the theme within the application. What would be the ideal method for handling such a scenario?

Additional Notes

To tackle the publishing issue, I export the Theme as part of the library. However, incorporating the theme into external applications poses similar challenges, affecting any React app attempting to utilize the library. I am currently importing it as follows:

import theme from '@mylibrary/atoms/lib/Theme'
and applying it with <ThemeProvider />. While the problem remains consistent, it now extends beyond internal repositories to impact any external applications relying on the library.

I earnestly hope for insights or shared experiences from individuals who have encountered similar obstacles in their development process!

Answer №1

It appears that you are incorporating an interface and utilizing it as a theme. It is recommended to utilize a theme object instead, similar to the example provided in Using with Material-UI

const theme = {
  palette: {
    primary: {
      main: '#556cd6',
    },
    secondary: {
      main: '#19857b',
    },
    error: {
      main: red.A400,
    },
    background: {
      default: '#fff',
    },
  },
};

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

The dependency that was installed in the node_modules directory is now showing as missing the

I have encountered an issue with 2 TS packages. The first package, project-1, is installed as a dependency in the second package, project-2. While I am able to import and access all type definitions of project-1 in project-2, the dependencies (node_modules ...

The React App deployed on the S3 bucket is only displaying the homepage, and it seems like the Hash router is

After deploying my react app on an S3 bucket, I encountered an issue where only the home page would display and all other pages would result in a 404 error. Despite switching from browserHistory to hashHistory, the problem persisted. The console showed a ...

Key distinctions between lit-element Web Components and React

Upon examination of React code, it appears to be quite similar to "Lit-Element" code. Both are utilized in the creation of web components. Can someone kindly provide insight into the key distinctions between React and Lit-element? ...

Discovering the technique to unearth a specific value within an array nested within another array

I am encountering an issue with finding a value in one array inside another array and utilizing the resulting value to update the state using setState(). Here is the initial state: this.state = { initialStudents:[ {name:"str1",tags;["str","s ...

Guide on integrating Chakra Provider and Material UI in React JS - a step-by-step tutorial

Our team is currently working on a project to create a clone of flipkart.com. We have divided the tasks among team members, with one individual focusing on the landing page using material UI and myself working on the product page with chakra UI. However, a ...

Ways to resolve the recurring npm ERR! code that appears whenever I enter npm start in the terminal

As I work on creating an application in React, I encountered an issue when trying to run "npm start" in the command line. The error message I received is shown below: npm ERR! code ENOENT npm ERR! syscall open npm ERR! path /Users/a1234/Downloads/meditati ...

A new form of error emerges: "InvalidOperation: outcomes.map lacks functionality. Operation.displayStaff

I encountered an error while attempting to display API data using a ReactJS application. I followed the code below, but it keeps showing the following error: TypeError: results.map is not a function Function.renderemployeeTable In this case, `res ...

What is the best way to set a variable as true within a pipeline?

Could someone assist me with a coding issue I'm facing? If the id is null, I need variable x to be true. I am unable to use if and else statements within the pipe. Any guidance would be greatly appreciated. private x = false; private y = false; n ...

Creating a React Native project without the use of TypeScript

Recently I dived into the world of React Native and decided to start a project using React Native CLI. However, I was surprised to find out that it uses TypeScript by default. Is there a way for me to create a project using React Native CLI without TypeS ...

Guide: Writing code that caters to different types of media in React using Material-UI

After reviewing the documentation, I believed that the optimal solution in later versions of material-ui was to use useMediaQuery, but unfortunately, I am unable to implement it correctly. My objective is to hide a menu when the page is being printed, so I ...

I am having trouble with data populating in an Array within the UseEffect hook in React

Within my useEffect function, I am populating two arrays, each containing two elements. However, only one element from each array is displaying on the page. https://i.stack.imgur.com/ZUeow.png This is the contents of the useEffect function: useEffect(( ...

What is the process for creating an executable file from a React.js and Node.js application?

I have developed an application using ReactJS for the frontend and NodeJS for the backend. I am now looking to convert this project into an .exe file. Is there a way to package my app as a .exe? If so, please provide guidance on how to achieve this. Than ...

What is the best way to transmit a React context from a lower scope to a higher scope in React?

I have specific requirements regarding database and authentication contexts, as shown below. Please disregard the language aspect, as that is not a concern for me. root.render( <Router> <LangContextProvider> <DBContextContext ...

I've been stuck for hours, is there anything I should include?

I'm attempting to access http://localhost:4200/Personnes/view/:2, but I encountered the following error (ERROR TypeError: Cannot read property 'nom' of undefined) "My personnnes.service.component.ts" `export class PersonnesService { baseUr ...

How can I retrieve routing parameters in a Vue.js/Nuxt/TypeScript app?

In the process of developing my website based on the Nuxt TypeScript Starter template, I've encountered a challenge. Specifically, I have created a dynamically routed page named _id.vue within my pages folder and am looking to access the id property i ...

Converting a Next 13.4.4 Js Project into a Progressive Web App (PWA): A Step-by-

Looking for some guidance on turning my Next Js 13 project into a PWA. I've been referring to the next-pwa documentation, but applying it to my Next 13 project's structure has proven challenging. Although the project is functioning well, I need ...

What is the term for specifying a variable's data type using a set of values instead of a traditional type?

Recently, I stumbled upon some code that introduces a class with specific variables defined in an unconventional manner. export class Foo { id: string = "A regular string" bar: '>' | '<' | '=' | '<=' | ...

Create an option to export data from material-UI DataGrid to an Excel file, using a designated Export

I have a code where I need to export details from a datagrid by creating a button and passing an onClick function to it. Although the datagrid Toolbar component can be used for this purpose, I prefer not to use it. Can someone guide me on how to export r ...

Troubleshooting: Angular 2 View not reflecting changes after array push

I have encountered an issue with my two child components. They are both meant to share data from a json file that I load using the http.get/subscribe method. Oddly enough, when I try to push new data into the array, it doesn't seem to update in the vi ...

The problem I am facing is with the React Ant d Modal Component, where I am unable to render the

Hey there! I'm currently working with React Js and the 'Ant design Modal Component'. When I click on a button, the modal should open and display the content of each user with their unique ID. However, I'm facing an issue where all modal ...