fluent ui styling, border is not defined - reactjs

i am using fluent ui which uses Griffel for styling. When i try to provide border: "none" it's throwing error that string not assignable to undefined
import {makeStyles} from "#fluentui/react-components";
export const settingsButtonStyle = makeStyles({
root: {
border: "none",
background: "#E5E5E5",
marginRight: "13px"
},
rootHovered: {
background: "#E5E5E5",
}
});

GriffelJS tries to make Atomic CSS classes, so they don't support CSS shorthands (like border or background) right away. But there is a helper function called shorthands to manage some of theses. Background is not included in the helper function, so there you should use the specific CSS proprety. So your code should look like this:
const useStyles = makeStyles({
root: {
...shorthands.border("0"),
// or
...shorthands.borderStyle("none"),
backgroundColor: "#E5E5E5",
marginRight: "13px"
},
})
You find more infos to shorthands in GriffelJS in their documentation shorthands - GriffelJS

Related

how to use vanilla-extract for `style` attribute?

Have a following sample of code which I want migrate to vanilla-extract, my main question is how to generate styles for style attribute in this case?
// in ColorToken.tsx
function ColorToken(props: { name: string; value?: string }) {
return (
<div
style={{
backgroundColor: `var(${props.value})`,
border: 'solid 1px var(--color-border-neutral)',
borderRadius: '100%',
width: '70px',
height: '70px',
}}
>
{props.name}
</div>
);
}
I tried two approaches:
First
// ColorToken.css.ts
import { style } from '#vanilla-extract/css';
export function colorSelector(bgColor: string) {
return style({
backgroundColor: bgColor,
border: 'solid 1px var(--color-border-neutral)',
borderRadius: '100%',
width: '70px',
height: '70px',
});
}
// ColorToken.tsx
import * as selectors from './Colors.css';
function ColorToken(props: { name: string; value?: string }) {
const color: string = // dynamically piking color based on props.
return (
<div className={selectors.colorSelector(color)}>
Error / issue:
error - ./pages/styles/tokens/Colors.css.ts
Error: Invalid exports.
You can only export plain objects, arrays, strings, numbers and null/undefined.
at Array.map (<anonymous>)
Second
// ColorToken.css.ts
export const colorSelector = {
border: 'solid 1px var(--color-border-neutral)',
borderRadius: '100%',
width: '70px',
height: '70px',
};
// ColorToken.tsx
import { style } from '#vanilla-extract/css';
import * as selectors from './Colors.css';
function ColorToken(props: { name: string; value?: string }) {
const color: string = // dynamically piking color based on props.
return (
<div className={style({ ...selectors.colorSelector, backgroundColor: color })}>
Note: here I'm using style function because I think VE might apply some extra things (e.g add vendor prefixes, optimizations etc).
Error / issue:
Unhandled Runtime Error
Error: Styles were unable to be assigned to a file. This is generally caused by one of the following:
- You may have created styles outside of a '.css.ts' context
- You may have incorrect configuration. See https://vanilla-extract.style/documentation/setup
Note: using VE via NextJS setup.
The key to keep in mind here is that vanilla works at build time. It outputs a plain CSS stylesheet, so trying to substitute values in at runtime isn't what it's built for.
If you have a clearly defined set of background colours that you want to use, you could use a recipe, or you could start to build up some atomic CSS with sprinkles.
If it needs to be truly dynamic, impossible to know at build time, you can take advantage of CSS variables using vanilla's dynamic package.

Target CSS child selector created by in material ui

I have styles like this:
const useStyles = makeStyles(theme => ({
root: {
margin: 5
},
container: {
backgroundColor: 'red'
},
active: {
// here I want to target the 'container' className I created above like
'& .container': {
backgroundColor: 'green'
}
}
});
I want to target the container className I created inside of the active className. The above won't work because in the DOM, MUI will generate a unique name so I won't be targeting the right class. Wasn't able to find any SO answer or blog or documentation addressing this.
$ rulename is used for this purpose. Here is the documentation of it on Material-UI.
CSS in JS documentation also explains this feature.
container: {
//other styles
},
active: {
"& $container": {
background: "green",
color: "#fff"
}
}
Here one thing which is important that for referencing 'containerrule, it should be defined in the rules object. trying to use"& $containerwithout defining thecontainerrule inside themakeStyles` will not work.
Here is the working demo:
You can refer using $
You will have to modify your DOM little bit such that the active className is not the parent of container. Instead add the active className to the conatiner element itself.
so your css style might look like below
const useStyles = makeStyles(theme => ({
root: {
margin: 5
},
container: {
backgroundColor: 'red',
'&$active': {
backgroundColor: 'green'
}
},
});
I think this is what you are looking for $rulename
How to Use $ruleName to reference a local rule within the same style sheet
In your case i think the solution would be
const useStyles = makeStyles(theme => ({
root: {
margin: 5
},
container: {
backgroundColor: 'red'
},
active: {
.container: {
backgroundColor: 'green'
}
}
});
Which should compile to
.root.container.active{}
and on the target tag taking a example of button here
<Button
classes={{
root: classes.root,
container: classes.container,
active: classes.active,
}}>
Havent worked with MUI yet but even in vue or react the way this is achived is by setting a dynamic name on the tag that is targeted via script.

Define Multiple Styles React

Is it possible to define multiples classes in React just like in CSS?
const useStyles = makeStyles((theme) => ({
header1,
header2,
header3,
header4: {
display: 'flex',
justifyContent: 'center',
},
}));
I'm afraid #material-ui/styles library usage does not work that way. Each key in the object you define represents one class name.
So trying to do something like this:
const useStyles = makeStyles((theme) => ({
'header1, header2, header3, header4': {
display: 'flex',
justifyContent: 'center'
},
}));
Will result in unusable or invalid class names when the code gets compiled to CSS, because the library will try to compile 'header1, header2, header3, header4' into one class, and since the name contains a space character, the result is garbage.
To solve your problem, the closest thing I can come up with is to define the styles object as its own constant, then assign it to the needed keys. You can also override the original object using spread syntax. Something like:
const headerStyles = {
display: 'flex',
justifyContent: 'center'
};
const useStyles = makeStyles((theme) => ({
header1: headerStyles,
header2: headerStyles,
header3: headerStyles,
header4: {
...headerStyles,
color: 'red'
}
}));
I hope this is a close-enough compromise for you.
You're currently defining an object in the makeStyles method. this ain't CSS.
If you prefer CSS syntax over JSS, you can use the jss-plugin-template plugin.
And write something like this:
const useStyles = makeStyles({
root: `
.header1,
.header2,
.header3,
.header4 {
display: flex;
justifyContent: center;
}
`
});
Reference: https://material-ui.com/styles/advanced/#string-templates

Dynamic values in material ui's makeStyles

I have some styles stored in a database so users can restyle their components - along the lines of:
const stylesFromDatabase = {
backgroundColor: "blue",
color: "red"
}
Is it possible to bring these styles into material UI's makeStyles - perhaps something like this?- edited -
const useStyles = makeStyles(theme => ({
textField: stylesFromDatabase => ({
width: "100%",
...stylesFromDatabase
}),
Alternatively, is there anything I can use to smoosh together the classes generated by makeStyles and a javascript object?
Yes, It's absolutely possible to include a JavaScript object into makeStyles.Thanks to the spread operator.
Advice is to spread over the object first, so that you can easily override any styles.
Therefore it's preferred to do as follows.
const useStyles = makeStyles(theme => ({
textField: {
...stylesFromDatabase, // object
width: "100%",
color: "green", // this would override "red" (easier fine tuning)
},
});
For the benefit of future posters, the code in my original post worked perfectly, I just had something overriding it later! (Without the callback function it was undefined) – H Capello just

How can I customize material-ui V1 components across entire application when creating a theme?

in material-ui v0, when creating a theme with const muiThemeV0 = getMuiTheme(theme);
i can simply add a property to the themeOptions for each component based on this file:
https://github.com/mui-org/material-ui/blob/master/src/styles/getMuiTheme.js (currently on the master branch when writing this question), and can customize not only colors but the theme border-radius etc, and specific components sizes and colors.
for example:
const theme = {
slider: {
selectionColor: colors.primary1Color,
handleFillColor: colors.primary1Color,
trackSize: 6,
}
}
I tried going through the https://material-ui-next.com/customization/overrides/ docs, but can't see examples and/or a list of options in the source code like MUI-v0 when i want to use const muiThemeV1 = createMuiTheme(theme);
are there any docs for this kind of customization in v1?
is this even possible?
In v1, you can use the theme overrides property to customize the styles of a specific component type. Instead of providing theme options for individual components, this feature allows you to customize every style that material-ui injects into the DOM.
You can find a list of the CSS classes for each component on the website (in component API section).
The following example customizes the appearance of the Button component
const theme = createMuiTheme({
overrides: {
MuiButton: {
// override root styles for the button component.
root: {
// Name of the rule
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
borderRadius: 3,
color: 'white',
height: 48,
padding: '0 30px',
marginRight: 32,
},
// Custom styles for the raised button variant
raised: {
borderRadius: 50,
color: 'white',
// Custom hover styles for raised button
'&:hover': {
boxShadow: shadows[4],
},
// Custom active styles for raised button
'&:active': {
boxShadow: `${shadows[24]} !important`,
},
},
},
}
});
Live example on code sandbox
Documentation on theme overrides

Resources