React & Material-UI – Custom theme within custom component - reactjs

I have React app (functional components) and I use Material-UI. I have custom theme also and I use theme provider. I have created custom component (e.g. MySuperContainer) and I need to connect it with particular styles (object) in my theme
export const myTheme = { …, components: { MySuperContainer: { padding: “10px“, … } … }
I don’t want to import it to component to sx via useTheme hook. I don’t want to use styled components nor anything similar. Finally I want to write <MySuperContainer /> and it should already find its own custom styles in myTheme.
How can I achieve this? Is there any example or tutorial how to do this? I cannot find anything.

Related

How to apply chakra-ui styles to custom components? (react-datepicker)

I'd like to define styles for my Datepicker component through the Chakra-ui styles.
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import { chakra } from '#chakra-ui/react';
const StyledDatepicker = chakra(DatePicker);
I've used the chakra factory function to be able to give the StyledDatepicker some styles through props, as shown in the code above, but I'd like to define everything in a separate styles .ts file like I've done for the built-in chakra components.
I've made a Datepicker.ts file with some style definitions and added it to the overrides object which is exported here as styles:
const styles = extendTheme(overrides);
export { styles };
which is imported in App.tsx and assigned to the theme prop of my ChakraProvider.
I've made some custom components which was fine, though not exactly what I'm looking for, and I'm looking to change the styles of the header container, the element with classname react-datepicker__header - no examples of making a custom component for this on react-datepicker website. I know I can do it with CSS files, but I'd really like to do all of it in the styles file for consistency.
The answer turned out to be fairly straightforward, but imo, chakra could have made it a bit easier to learn about this possibility.
To target a css class, you just add the classname into your styles object like this:
const DatepickerStyles = {
baseStyle: {
color: 'black',
'.react-datepicker__header': {
background: 'white',
},
},
};
Then do something like this where you want to use the component (In my case, the datepicker, but this will work for any component):
function MyDatePickerComponent(props) {
const datepickerStyles = useStyleConfig('Datepicker');
return (
<Datepicker
__css={datepickerStyles}
//some required props omitted for simplicity
/>
);
}
You can use sx instead of __css, I use __css for readability.
For react-datepicker and my case of styling the header specifically, I had to use a custom calendarContainer component, where I also applied the style in a similar manner by using useMultiStyleConfig instead of useStyleConfig. Hope this can be of help to someone.

How to share custom-styled Ionic components in bit.dev

Could you please help with the following?
We use Ionic with React in a team having 2 distinct projects.
We need to style these Ionic components a little differently.
I need to share these a-little-differently-styled Ionic components with another team for code re-use.
I would like to showcase these styled Ionic components using Storybook to the UX team and say "this is how a button looks like"
To begin with I just added the styling in a css file and imported that file in the root React page.
But it would be nice to just encapsulate component + styling in a re-usable isolated component that other people can re-use without having to import custom css files.
I am thinking of :
import { IonButton } from "#ionic/react";
import styled from "styled-components";
const StyledIonButton = styled(IonButton)`
// some custom css styling here
`;
const MyIonButton = () => <StyledIonButton {...props} />;
export default MyIonButton;
Now, I can track/export above component using e.g Bit.dev and have the other team consume it via npm-install.
However, I dislike :
a) changing the name from "IonButton" to "MyIonButton"
b) having to wrap each and every Ionic component as shown above
I would like myself and the other team to just use Ionic components in the standard way e.g
import { IonButton } from "#ionic/react";
...
<IonButton>Close</IonButton>
BUT having these base building-blocks/components styled in a certain way.
Could you please describe to me the right approach please? Many thanks for your time

Reusing custom styles in material-ui

New to material-ui here and trying to work out the best way of using the css in js. I can see from the demo code that inserting styles as classes is pretty easy using 'withStyles' but if I do the following I'd need to re-create the 'grow' and 'defaultPadding' styles in every component.
import React from 'react';
import { withStyles } from '#material-ui/core/styles';
import Paper from '#material-ui/core/Paper';
function Dashboard(props) {
const { classes } = props;
return (
<Paper className={classes.defaultPadding}>
Hello
</Paper>
);
}
const styles = theme => ({
grow: {
flexGrow: 1
},
defaultPadding: {
padding: theme.spacing.unit * 3 + 'px'
}
});
export default withStyles(styles)(Dashboard);
I could easily create a factory method in an external file that returns a massive object containing all my default styles but I'd need to be able to pass the existing theme to it if I want to use things like 'theme.spacing.unit'.
So, is there a way to create a bunch of re-usable styles of my own, using theme values, then import them into any component?
Bonus question: Is it possible to create nested objects so I can do things like this? ...
className={classes.layout.header}
I think creating an external factory method would work or you could also create a ThemeProvider to pass your theme to every component that needs the same styles.
In the Codesandbox I created two Dashboard components. One with styled-components just to show how a ThemeProvider works and the other component is using withStyles.
For withStyles factory I called it sharedStyles in the demo and with this you can create a new style object inside your components by calling it and spreading it to a new style (just if you need to add more styles).
Nesting inside styles seems not supported. You could create keys like layout.heading or flatten the object before using it (see code in the demo). Both not perfect and I wouldn't use it.
I'm personally prefering styled-components but you don't need to switch to it. You can look at the source code how they implemented it and use it in your code to pass the theme to your component.
The ThemeProvider is using React Context-Api.

How to access custom namespaced (react-)JSS theme from components?

I'm creating a react/redux app, and want to utilize JSS theming to style my app/components. I'm also using other libraries that use JSS theming, e.g. Material UI, thus I need to create a namespaced theme as described in http://cssinjs.org/react-jss?v=v8.1.0#theming to avoid conflicts with other themes.
Does this mean that I have to import my namespaced theme in every component I want to style with that theme, and pass it to injectSheet? I.e:
import React from 'react
import injectSheet, {ThemeProvider} from 'react-jss
// import my custom namespaced theming object...
import theming from '../path/to/my/custom/theming'
const styles = theme => ({
container: {
background: theme.background,
}
})
const Demo = () => (
<div className={props.classes.container}>
//...
</div>
)
// injectSheet with my custom namespaced theming object..
export default injectSheet(styles, {theming})(Demo)
This feels very cumbersome. Is it another way that one should do this? Am I missing something? Thanks in advance :)
You could wrap your injectSheet function in a central place and always pass the theming there.

What is the preferred way to theme a composed component using styled-components?

Can anyone recommend the best way to compose styled-components that need to be themed?
Here's my code: https://gist.github.com/aaronmcadam/7bfd63a6bc4cfc36f9947a449c6f494a.
I have an Avatar component which composes an Image component, which is itself a styled-component.
If I use Avatar.styled.js with <ThemeProvider>, the theme can be successfully overridden.
If I use Avatar.withTheme.js, the theme can only be overridden if I use withTheme.
Which is the preferred way of doing things like these?
from the official docs: https://github.com/styled-components/styled-components/blob/master/docs/theming.md
We export a component that takes a theme prop. The
theme you provide there is injected into your styled components via
props.theme
If you ever need to get the current theme outside styled components
(e.g. inside big components), you can use the withTheme Higher Order
Component
import { withTheme } from 'styled-components'
class MyComponent extends React.Component {
render() {
const { theme } = this.props
console.log('Current theme: ', theme);
// ...
}
}
export default withTheme(MyComponent)

Resources