Grommet UI -- Custom Color Schemes - reactjs

I'm using grommet-ui with webpack and react.
How do I set my own color options.
Is there a way to use my own custom colors/color schemes in place of predefined colors like colorIndex="neutral-1".

Yes, there is a way to override them, but it is currently not documented. I would start checking the colors here:
https://github.com/grommet/grommet/blob/master/src/scss/grommet-core/_settings.color.scss
For example, neutral-1 is used from this array
$brand-neutral-colors: (#5d0cfb, #7026ff, #767676) !default;
In your index.scss you can replace that (!default allows replacement):
$brand-neutral-colors: (#333333, #7026ff, #767676)
We are working on adding documentation for custom theme variables.

For Grommet v2 users, you can leverage the theme capabilities and define a customTheme as a js object with your desired colors, following the current structure:
const customTheme = {
global: {
colors: {
// Overriding existing grommet colors
brand: "#4D4CDB",
"accent-1": "#6FFFB0",
"accent-2": "#7FFFB0",
"accent-3": "#8FFFB0",
"accent-4": "#9FFFB0",
"neutral-1": "#10873D",
"neutral-2": "#20873D",
"neutral-3": "#30873D",
"neutral-4": "#40873D",
focus: "#000",
// Setting new colors
blue: "#00C8FF",
green: "#17EBA0",
teal: "#82FFF2",
purple: "#F740FF",
red: "#FC6161",
orange: "#FFBC44",
yellow: "#FFEB59",
// you can also point to existing grommet colors
brightGreen: "accent-1",
deepGreen: "neutral-2"
}
}
};
...
export const Example = () => (
<Grommet theme={customTheme}>
<Box background="orange" >
<Text color="deepGreen">Custom Color</Text>
</Box>
</Grommet>
);
You can override any Grommet color that is mentioned in the docs in a similar fashion.
Wrapping your application with the Grommet component that is pointing to your customTheme object as shown on the example, will allow you full access to your custom colors across your application.

Check the pre-packed themes from https://github.com/grommet/grommet/tree/master/src/js/themes and choose the one that's closest to your goal
Then write your own, but only the parts you want to change
Roll your complete theme by merging the pre-packed with your prefs like so:
import React from 'reactn';
import { dark } from 'grommet/themes';
import { deepMerge } from 'grommet/utils';
import { generate } from 'grommet/themes/base';
import { FormDown } from 'grommet-icons';
const localTheme = {
global: {
font: {
family: 'Montserrat, Roboto, sans-serif',
size: '14px',
lineHeight: '20px'
},
colors: {
brand: '#4040DB',
focus: '#50c050',
[dark-5]: '#aaaaaa',
[dark-6]: '#bbbbbb',
// [light-1]: '#ededed', // has error "light not defined"
},
input: {
padding: '5px;', // this renders a 4px padding!
},
},
button: {
hoverIndicator: {
dark: { color: dark-6 },
light: { color: 'light-3' },
border: { radius: '5px' }
},
disabled: {
color: dark-4,
opacity: '0.6',
},
border: {
width: '1px',
color: 'rgb(238,238,238)',
radius: '4px'
},
padding: 'none',
},
select: {
background: 'dark-1',
icons: {
color: 'rgb(238,238,238)',
margin: '0px 0px',
down: <FormDown />,
},
control: {
open: {
color: 'rgb(238,238,0)'
}
},
options: {
container: {
pad: 'xxsmall',
background: 'dark-1'
},
text: {
margin: 'none',
size: 'small',
color: 'light-1',
},
},
container: {
extend: () => `
flex-grow: 1;
`,
}
},
textArea: {
// not working: background: ${ localTheme.global.colors[dark-2] }; // dark-2
extend: () => `
background: ${ '#333333' }; // dark-1
margin: 2px 0px;
height: 100px;
&:hover {
background: ${ '#555555' }; // dark-2
}
&:focus {
background: ${ '#555555' }; // dark-2
color: ${ '#ffffff' };
}
&::placeholder {
color: dark-5;
font-style: italic;
font-weight: 200;
}
`,
},
textInput: {
extend: `
background: ${ '#333333' }; // dark-1
margin: 2px 0px;
&:hover {
background: ${ '#555555' }; // dark-2
}
&:focus {
background: ${ '#555555' }; // dark-2
color: ${ '#ffffff' };
}
&::placeholder {
color: dark-5;
font-style: italic;
font-weight: 200;
}
`,
},
};
export default recipesTheme
Notice that some of the lines are failed experiments trying to overcome the flaky docs.
This exports a recipesTheme module to be used in the render method of App or whatever:
<Grommet full = { true } theme = { recipesTheme }>
There is this tool https://grommet-theme-builder.netlify.com/ that you can use to somehow see the effect of your changes.

Related

White-labeling in reactjs with Materail-UI and Tailwind

I have a react setup in which I am using Tailwind and Material-UI. I have a component library in the Storybook which has MUI Theme in it to style the variants like button outline. I am trying to find a way of how can I use these two things to make the react app white-labeled. Basically, Which properties I can set in my theme that it can be directly applied to the components by the user/providers/companies. Currently, my theme looks something like this in the component library.
import { createTheme, ThemeOptions } from '#mui/material/styles';
import { Colours } from '../common';
export const MyThemeOptions: ThemeOptions = {
palette: {
primary: {
main: Colours.primary,
},
secondary: {
main: Colours.secondary,
},
error: {
main: Colours.error,
},
warning: {
main: Colours.warning,
},
info: {
main: Colours.info,
},
success: {
main: Colours.success,
},
},
components: {
MuiButton: {
styleOverrides: {
root: {
borderRadius: '4px',
},
contained: {
padding: '4px 12px',
},
outlined: {
border: '1px solid #bdbdbd',
textTransform: 'none',
minWidth: 0,
color: '#212121',
},
outlinedSizeSmall: {
padding: '2px',
},
outlinedSizeMedium: {
padding: '6px',
},
outlinedSizeLarge: {
padding: '10px'
},
},
},
MuiButtonGroup: {
styleOverrides: {
grouped: {
minWidth: 0,
},
},
},
MuiCard: {
styleOverrides: {
root: {
boxShadow: '0 3px 7px 0 rgba(98, 125, 152, 0.16), 0 0 2px 0 rgba(36, 59, 83, 0.04)',
},
},
},
MuiToggleButton: {
styleOverrides: {
root: {
border: '1px solid #bdbdbd',
borderRadius: '4px',
textTransform: 'none',
color: '#212121',
minWidth: 0,
},
sizeSmall: {
padding: '2px',
},
sizeMedium: {
padding: '6px',
},
sizeLarge: {
padding: '10px',
}
}
}
},
};
const MyTheme = createTheme(MyThemeOptions);
export default MyTheme;
I am not able to find an article or tutorial or something which could lead me in a direction of how can I achieve the white labeling? If you know any knowledge asset in this direction, please share with me. Thank you!

Stepper vertical line detaches when label wraps over multiple lines?

The text inside my MaterialUI Stepper // StepLabel sometimes wraps over multiple lines.
I need to keep the vertical StepConnectors attached the StepIcons regardless of the number of lines of text in the label.
I've tried other solutions such as using CSS pseudo tags, but I hit a wall every time I try to work those changes into our existing solution.
Massive thanks in advance to anyone who can help.
Sandbox
https://codesandbox.io/s/practical-chebyshev-4hktl?file=/src/App.js
Current Screenshot
Existing ThemeOptions
import {
ThemeOptions,
createTheme,
ThemeProvider,
CssBaseline
} from "#material-ui/core";
export const themeOptions: ThemeOptions = {
overrides: {
MuiStepper: {
root: {
backgroundColor: "transparent" // remove set background
}
},
MuiStepConnector: {
vertical: {
padding: 0,
width: 5,
marginLeft: 8 // half icon
},
lineVertical: {
top: "calc(-50%)",
bottom: "calc(50%)",
borderLeftWidth: "2px",
marginLeft: "-1px", // center (1/2 width)
marginTop: "-6px", // add -ve margin to top and bottom ...
marginBottom: "-6px", // ... to hide gap due to smaller icon
borderColor: "lightgrey",
"$active &, $completed &": {
borderLeftWidth: "4px",
marginLeft: "-2px",
borderColor: "blue"
}
}
},
MuiStepLabel: {
label: {
textAlign: "left",
fontSize: "1.25rem",
"&$active": {
fontWeight: 400
},
"&$completed": {
fontWeight: 400
}
},
iconContainer: {
paddingRight: 12
}
},
MuiStepIcon: {
root: {
display: "block",
fontSize: "1rem",
color: "lightgrey",
"&$completed": {
color: "blue"
},
"&$active": {
color: "blue"
}
}
}
}
};
Just in case anyone finds this in the future, we compromised on the ​implementation to deliver the task.
Instead of having a variable height on the MuiStepLabel, it was given a fixed height to keep the StepIcons the same distance apart. If you imagine the below screenshot with a different font size + spacing, it ended up looking OK, but not ideal.
Before
// src/Theme/index.tsx
export const themeOptions: ThemeOptions = {
overrides: {
MuiStepConnector: {
marginTop: "-6px",
marginBottom: "-6px",
}
MuiStepLabel: {}
}
}
After
// src/Theme/index.tsx
export const themeOptions: ThemeOptions = {
overrides: {
MuiStepConnector: {
marginTop: "-2px",
marginBottom: "-4px",
minHeight: "calc(24px + 0.5rem)",
},
MuiStepLabel: {
height: "1.25rem",
lineHeight: "1.25rem",
}
}
}
Sandbox
https://codesandbox.io/s/epic-bohr-0p7fj?file=/src/Theme/index.ts

Material UI warning: You are trying to override a style that does not exist. Fix the `&$selected` key of `theme.overrides.MuiTab`

I'm trying to override some MUI styles in React Material UI. This is currently working for me:
MuiTab: {
root: {
color: '#284568',
},
textColorInherit: {
opacity: 1,
},
wrapper: {
textTransform: 'capitalize',
},
'&$selected': {
backgroundColor: '#000',
border: '1px solid #CFDCE8',
},
},
However, it gives me a warning on the console:
"getStylesCreator.js:42 Material-UI: You are trying to override a
style that does not exist. Fix the &$selected key of
theme.overrides.MuiTab."
I tried to convert to:
MuiTab: {
root: {
color: '#284568',
'&$selected': {
backgroundColor: '#000',
border: '1px solid #CFDCE8',
},
},
textColorInherit: {
opacity: 1,
},
wrapper: {
textTransform: 'capitalize',
},
},
The warning was gone, but the style won't apply anymore :(
Any suggestions?
Thanks.

Applying embedded styles to MUI components based on variants

I am trying to apply custom styling to the component based on its variants. However, a single component can have multiple variants specifying different style-properties. For this question, I will use code snippets from the Button component.
My wrapper of the Material UI Button component (defined here as MaterialButton):
import MaterialButton from '#material-ui/core/Button'
import './button-design-tokens.module.css'
export const Button: React.FC<ButtonProps> = (
props: ButtonProps
) => {
return (
<MaterialButton {...props}>{props.children}</MaterialButton>
)
}
I am trying to apply the following styles to this component in a Storybook environment using useStyles():
const useStyles = makeStyles({
contained: {
backgroundColor: 'var(--mdh-button-background-color)',
fontFamily: 'var(--mdh-button-font-family)',
'&.primary': {
color: 'var(--mdh-button-secondary-background-color)',
},
'&.secondary': {
color: 'var(--mdh-button-secondary-background-color)'
},
'&:hover': {
backgroundColor: 'var(--mdh-button-hover-background-color)',
color: 'var(--mdh-button-hover-text-color)'
},
'&:focus': {
backgroundColor: 'var(--mdh-button-focus-background-color)',
color: 'var(--mdh-button-focus-text-color)'
},
'&$disabled': {
backgroundColor: 'var(--mdh-button-disabled-background-color)'
}
},
outlined: {
borderRightColor: 'var(--mdh-button-background-color)',
borderLeftColor: 'var(--mdh-button-background-color)',
borderTopColor: 'var(--mdh-button-background-color)',
borderBottomColor: 'var(--mdh-button-background-color)',
'&:hover': {
borderRightColor: 'var(--mdh-button-hover-background-color)',
borderLeftColor: 'var(--mdh-button-hover-background-color)',
borderTopColor: 'var(--mdh-button-hover-background-color)',
borderBottomColor: 'var(--mdh-button-hover-background-color)'
},
'&:focus': {
borderRightColor: 'var(--mdh-button-focus-background-color)',
borderLeftColor: 'var(--mdh-button-focus-background-color)',
borderTopColor: 'var(--mdh-button-focus-background-color)',
borderBottomColor: 'var(--mdh-button-focus-background-color)'
}
},
outlinedPrimary: {
color: 'var(--mdh-button-background-color)'
},
outlinedSecondary: {
color: 'var(--mdh-button-secondary-background-color)'
},
textPrimary: {
color: 'var(--mdh-button-background-color)',
'&:hover': {
color: 'var(--mdh-button-disabled-background-color)'
},
'&:focus': {
color: 'var(--mdh-button-disabled-background-color)'
}
},
textSecondary: {
color: 'var(--mdh-button-secondary-background-color)',
'&:hover': {
color: 'var(--mdh-button-disabled-background-color)'
},
'&:focus': {
color: 'var(--mdh-button-disabled-background-color)'
}
}
})
As you can see, a Material UI button has the variants contained (a normal button), outlined (a button with only a coloured border) and text (a button consisting only of text). These variants can, in turn, have the primary, secondary and default variants which change the colour of the text inside the button.
The CSS variables seen in the JSON are defined in the css file imported in the Button wrapper. This file has the following contents:
:root {
--mdh-button-background-color: rgb(34, 123, 60);
--mdh-button-secondary-background-color: #EDBF07;
--mdh-button-focus-background-color: #9a6f1e;
--mdh-button-focus-text-color: white;
--mdh-button-hover-background-color: #9a6f1e;
--mdh-button-hover-text-color: white;
--mdh-button-disabled-background-color: #666;
--mdh-button-font-family: "TheMix", sans-serif;
}
.mdh-button {
background-color: var(--mdh-button-background-color);
font-family: var(--mdh-button-font-family);
}
.mdh-button--focus, .mdh-button:focus {
background-color: var(--mdh-button-focus-background-color);
color: var(--mdh-button-focus-text-color);
}
.mdh-button--hover, .mdh-button:hover {
background-color: var(--mdh-button-hover-background-color);
color: var(--mdh-button-hover-text-color);
}
.mdh-button--disabled {
background-color: var(--mdh-button-disabled-background-color);
}
As you can see, in order to style, for example, the outlined button in the primary variant, I would have to style this by combining the two variants in a class name (i.e. OutlinedPrimary). This is fine for minor changes, but I am developing a design system that is based on MUI and will have to re-style almost all the MUI components I am using in the system. This would lead to an insanely bloated and incomprehensible stylesheet for each component. Although this works, I am trying for a more compact and (in my humble opinion) logical approach. It is already defined in the JSON above, but I will highlight it below once more:
contained: {
backgroundColor: 'var(--mdh-button-background-color)',
fontFamily: 'var(--mdh-button-font-family)',
'&.primary': {
color: 'var(--mdh-button-secondary-background-color)',
},
'&.secondary': {
color: 'var(--mdh-button-secondary-background-color)'
},
'&:hover': {
backgroundColor: 'var(--mdh-button-hover-background-color)',
color: 'var(--mdh-button-hover-text-color)'
},
'&:focus': {
backgroundColor: 'var(--mdh-button-focus-background-color)',
color: 'var(--mdh-button-focus-text-color)'
},
'&$disabled': {
backgroundColor: 'var(--mdh-button-disabled-background-color)'
}
}
The primary variant is treated here as a 'subclass' of the contained variant of the Button. However, for some reason, this is not picked up by either Storybook or Material UI. I am applying the classes to the component like so:
const Template: Story<ButtonProps> = (args: any) => {
const classes = useStyles()
args.classes = {
contained: classes.contained,
outlined: classes.outlined,
// containedPrimary: classes.containedPrimary,
// containedSecondary: classes.containedSecondary,
textPrimary: classes.textPrimary,
textSecondary: classes.textSecondary,
outlinedPrimary: classes.outlinedPrimary,
outlinedSecondary: classes.outlinedSecondary
}
return <Button {...args}>Button</Button>
}
I have tried various and browsed through countless articles and blogs on the topic but have gotten none the wiser. Is there something I am missing? As far as I am aware, the syntax is correct.
Thank you in advance!

Self-host font added in Material-UI not working?

I'm working on a Material-UI based project and trying to add some self-hosted fonts, since they're not available as google fonts. I've followed both the Material-UI and JSS docs, and I've come up with the following, but I can't find the reason why it's still not working. There are no errors either to give me a clue as to what's wrong.
import { createMuiTheme } from "#material-ui/core/styles";
import Windlass from "./fonts/Windlass.eot";
import Windlass2 from "./fonts/Windlass.woff";
const theme = createMuiTheme({
...
typography: {
useNextVariants: true,
fontFamily: [
'Windlass',
'Helvetica Neue',
'Helvetica'
].join(','),
fontSize: 16,
fontWeightLight: 400,
fontWeightRegular: 400,
fontWeightMedium: 600,
fontWeightBold: 700},
overrides: {
MuiCssBaseline: {
'#global': {
'#font-face': {
fontFamily: 'Windlass',
src: `url(${Windlass})`,
fallbacks: [
{src: `url(${Windlass}?#iefix) format(embedded-opentype)`},
{src: `url(${Windlass2}) format(woff)`}
]
}
}
}
}
});
export default theme;
The font name does seem to show up in the css when I inspect the element as
font-family: Windlass,Helvetica Neue,Helvetica;
but the text shows up as Helvetica Neue.
In case someone stumbles on this post.
Here is another way to add fonts to the Material UI theme. I followed the steps from the MUI webiste.
https://material-ui.com/customization/typography/
///myAwesomeFont.ts
import myAwesomeFontEot from '../assets/fonts/myAwesomeFont.eot';
import myAwesomeFontWoff from '../assets/fonts/myAwesomeFont.woff';
import myAwesomeFontWoff2 from '../assets/fonts/myAwesomeFont.woff2';
import myAwesomeFontBoldEot from '../assets/fonts/myAwesomeFont-Bold.eot';
import myAwesomeFontBoldWoff from '../assets/fonts/myAwesomeFont-Bold.woff';
import myAwesomeFontBoldWoff2 from '../assets/fonts/myAwesomeFont-Bold.woff2';
const myAwesomeFontRegular = {
fontFamily: 'myAwesomeFont',
fontStyle: 'normal',
fontWeight: 400,
src: `local('myAwesomeFont-Regular'),
url(${myAwesomeFontEot}),
url(${myAwesomeFontWoff}) format('woff'),
url(${myAwesomeFontWoff2}) format('woff2')`,
};
const myAwesomeFontBold = {
fontFamily: 'myAwesomeFont',
fontStyle: 'normal',
fontWeight: 700,
src: `local('myAwesomeFont-Bold'),
url(${myAwesomeFontEot}),
url(${myAwesomeFontWoff}) format('woff'),
url(${myAwesomeFontWoff2}) format('woff2')`,
};
export default [myAwesomeFontRegular, myAwesomeFontBold]
In Your theme provider file.
//default.theme.ts
import { createMuiTheme, Theme } from '#material-ui/core/styles';
import myAwesomeFontArray from './myAwesomeFont';
const theme: Theme = createMuiTheme({
typography: {
fontFamily: "myAwesomeFont, sans-serif",
fontSize: 16
},
overrides: {
MuiCssBaseline: {
'#global': {
'#font-face': [...myAwesomeFontArray],
},
},
},
});
After you've set this up. Open up your developer tools on the browser and verify that they're indeed being downloaded. This worked for me. I hope it works for you.
this is my config and it work, you need declare the font in index.css like this.
theme.js
import { createMuiTheme } from "#material-ui/core/styles";
// import gliberPath from "./Gilbert_Bold-Preview_1004.woff2"; // this is no need to add
let palette1 = {
type: "light"
};
let palette2 = {
type: "light"
};
// this is no need to add
// const gliber = {
// fontFamily: "Gliber",
// fontStyle: "normal",
// fontDisplay: "swap",
// fontWeight: 400,
// src: `
// local('Gliber'),
// url(${gliberPath}) format('woff2')
// `,
// };
const typography = {
fontFamily: ["Gliber","Roboto"].join(","), // there need add Gliber reference,your font family name should be place the first position
// this is no need to add
// overrides: {
// MuiCssBaseline: {
// "#global": {
// "#font-face": ['Gliber']
// }
// }
// }
};
let theme1 = createMuiTheme({ palette: palette1, typography });
let theme2 = createMuiTheme({ palette: palette2, typography });
export { theme1, theme2 };
index.css
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
}
/*add self host font */
#font-face {
font-family: 'Gliber';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('./theme/Gilbert_Bold-Preview_1004.woff2') format('woff2');
}

Resources