Override margin in Separator Component of Fluent UI using React - css

I'm trying to override the margin attribute of a Separator component using Microsoft's Fluent UI using React. The top-margin appears to default to 15px and I would like it to be less than that.
Here's a screenshot:
The beige color section above is defaulting to 15px and I'd like to shrink it but I can't seem to find the correct css to do so.
Here's the code I have thus far:
const separatorStyles = {
root: [
{
margin: 0,
padding: 0,
selectors: {
'::before': {
background: 'black',
top: '0px'
}
}
}
]
};
export default class Home extends Component {
render() {
return (
<Stack verticalAlign="center" verticalFill gap={15}>
<Component1/>
<Separator styles={separatorStyles} />
<Component2 />
</Stack>
);
}
}
I've tried placing the margin: 0 where it currently is at the root level and also nested below the ::before but neither have worked.
The only other potential clue I have comes from an inspection of the styles in Chrome's DevTools which yields:
Any ideas would truly be appreciated!
Thanks for your time!

The 15px actually came from the gap prop that was passed to the Stack component. It takes care of adding that css class to children elements to ensure the proper margins exist.
I believe removing it altogether should solve your concern, such as in this example (link to working code):
<Stack verticalAlign="center" verticalFill>
<button>Button1</button>
<Separator>no margin</Separator>
<button>Button2</button>
<Separator />
<button>Button3</button>
</Stack>
However, it is worth noting that the Separator expects to render some text, so you might have trouble getting it to be the exact height you want (as font-size is a concern for the Separator). If that's the case, you might be better off just making your own control to render a 1px line with a simple div or span.

Also you can you use this approach with styled-component:
import React from 'react'
import {Separator} from '#fluentui/react'
import styled from 'styled-components'
const StyledSeparator = styled(Separator)`
&::before {
margin-top: 15px;
}
div {
//any styles for separator-content
}
`
export const Divider = ({children}) => {
return <StyledSeparator>{children}</StyledSeparator>
}

Related

Prevent a style (accidently loaded globally) from applying to a control

I'm trying to use TextField of Fluent UI.
import React from 'react';
import { TextField } from '#fluentui/react';
class Try extends React.Component {
render() {
return (
<TextField label="With auto" multiline autoAdjustHeight/>
);
}
}
export default Try;
Then, I realize that there is no space between the label and the text area. I check the CSS and understand that it is due to a label { margin-bottom: 5px; height: 22px } defined in index.css of another component XXX. Many tags and classes are defined in XXX/index.css such as form, label, input, button. Because I have import ./index.css in the component XXX and import ../XXX/index.css in several other components, XXX/index.css is loaded globally. And this XXX/index.css disturbs label of TextField of Fluent UI inside Try.
Does anyone know what I could do to Try component such that its TextField is not disturbed by XXX/index.css?
You may do this.
create another css file and load that css globally or just change that particular css only this the following.
label:not(#dont-apply-label *) { margin-bottom: 5px; height: 22px }
Now when you call the Fluent-Ui component, give a id
<TextField id="dont-apply-label" label="With auto" multiline autoAdjustHeight/>
This might not be best solution out of the box. But worth trying.
Another way can be triggering with class name like the following but not sure gonna work.
label:not(.ms-TextField *) { margin-bottom: 5px; height: 22px }

CSS Specificity with CSS Module

First, let me say I understand that I have a custom component "Card" that I use in one of my routes, "Home".
Card.js
import s from 'Card.css';
class Card {
...
render(){
return (<div className={cx(className, s.card)}>
{this.props.children}
</div>);
}
}
Card.css
.card {
display: block;
}
Home.js
<Card className={s.testCard}>
...
</Card>
Home.css
.testCard { display: none; }
A problem I faced here, is that the card remained visible even though I set the display to none, because of seemingly random CSS ordering in the browser. This ordering did not change even if Javascript was disabled.
To get .testCard to correctly load after .card, I used "composes:":
Home.css
.testCard {
composes: card from 'components/Card.css';
display: none;
}
Apparently this causes css-loader to recognize that .testCard should load after .card. Except, if I disable Javascript, the page reverts back to the old behavior: the .card is loaded after .testCard and it becomes visible again.
What is the recommended way to get our page to prioritize .testCard over card that behaves consistently with or without Javascript enabled?
As I'm using CSS modules, charlietfl solution wouldn't really work as is. .card is automatically mangled to a name like .Card-card-l2hne by the css-loader, so referencing it from a different component wouldn't work. If I import it into the CSS file of Home.css, that also doesn't work, because it creates a new class with a name like .Home-card-lnfq, instead of referring to .Card-card-l2hna.
I don't really think there's a great way to fix this so I've resorted to being more specific using a parent class instead.
As an example, Home.js:
import s from 'Home.css';
import Card from './components/Card';
class Home {
...
render(){
return (
<div className={s.root}>
<Card className={s.testCard}>Hi</Card>
</div>
);
}
}
Home.css
.root {
margin: 10px;
}
.root > .testCard {
display: none;
}
This way, we don't need to know what class names component Card is using internally, especially since in cases like CSS Modules or styled components, the class name is some unique generated name.
I don't think I would have come to this solution if it wasn't for charlieftl's solution, so thank you very much for that.
Just make the testCard rule more specific by combining classes
.card {display: block;}
.card.testCard { display: none; }

How to make a block appear in reactjs?

Hi and thanks for the great work here. I'm pretty new in reactjs and I'm struggling to make it work with sandbox like jsfiddle.
I have a div called "app-content" tht is supposed to appear in the middle of the document just like the following :
For some reasons , I cant make the following thing on my sandbox , and I get the following : https://jsfiddle.net/w7sf1er6/8/
JS here
export default class App extends React.Component {
render() {
return (
<div className="app-content">
</div>
);
}
};
ReactDOM.render (
<App />,
document.getElementById('root')
);
and CSS here
html {
background-color: #e3e3e3;
font-family: regular, arial, sans-serif; }
body {
margin: 0 !important;
padding: 0 !important; }
a {
text-decoration: none; }
.app-content {
width: 1200px;
height: 500px;
margin-left: auto;
margin-right: auto;
background-color: white; }
What am I mising ? I need to make it work on JSfiddle so I can share it with others developers. I wuld appreciate some help from our community.
Thanks.
You must install react-blocks via npm first if you haven't already.
Like so, npm install react-blocks
Once you have done this, you will need to import/require react-blocks within your react code.
// using an ES6 transpiler
import Block from 'react-blocks';
// not using an ES6 transpiler
var Block = require('react-blocks');
Next, the layout:
// Normal Flex layout
const App = () => {
return (
<Block layout>
<div>Alpha</div>
<div>Beta</div>
</Block>
);
};
// Reverse Flex layout
const Reverse = () => {
let { reverse } = styles;
return (
<Block style={reverse.block} layout vertical reverse>
<div>Alpha</div>
<div flex>Beta</div>
</Block>
);
};
Feel free to read more on the process here.
Hope this helps!
Your React component is not rendering to the div. You can see errors in the console log and doing "view frame source" on the HTML output pane will show you that the "div" element hasn't been replaced.
As Chris suggested, just start from a JSFiddle example that sets up React correctly.
The example above mainly differs from your code in that it imports React definitions.
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js" />

Component is briefly rendering without styles on first render

When I open my react app, the component below flashes with width:100%, probably because it inherits it from the material-ui card.
In my react app there are a lot of these components being rendered, each with their own width which are based on the parent component's data. I set the width with an inline style based on the props.
As I understand, the component has the inline style as it is created and there should be no delay to apply it. However I see all the SceneThumb components with 100% width for a a fraction of a second, before they apply the given inline style.
If I change the css of scene-thumb-parent to include some width, say 10% for example, then I'll see them all with 10% for a fraction of a second, before the inline style is applied. That makes me think there is a delay in applying inline css, but it really puzzles me..
Is this to be expected of react? Or of html in general? Is there any way to reduce this inline style application delay? Maybe it's something to do with the dev hot reloading setup I get from create-react-app?
SceneThumb.js (code that is irrelevant to the question has been omitted):
import React, { Component } from 'react';
import './scene-thumb.css';
import Card from 'material-ui/Card';
class SceneThumb extends Component {
render() {
return (
<div
className='scene-thumb-parent'
style={{width:this.props.width, left:this.props.left}}
>
<Card
className={this.props.selected?'scene-thumb-selected':'scene-thumb'}
>
<span>
Hello world!
</span>
</Card>
</div>
);
}
}
export default SceneThumb;
scene-thumb.css:
.scene-thumb-parent {
position:relative;
text-overflow:clip;
white-space:nowrap;
overflow:hidden;
min-width: 12px;
}
.scene-thumb-selected {
border: 2px solid red;
border-radius: 5px;
}
.scene-thumb,.scene-thumb-selected {
padding: 2px;
margin:2px;
position:relative;
}
The width prop is initially null or some other value. A moment later, the prop is updated which triggers another render. This is why you're seeing the flash you're talking about.
You can test this by adding the following to your render() function:
console.log(this.props.width)
You'll probably see it logging at least twice with different values.
There are many ways you can fix this. What makes most sense would depend on the rest of the application, and your personal preference. Regardless, here's one way:
render() {
if(!this.props.width) return null; //if it's null, render nothing.
return (
<div className='scene-thumb-parent' style={{width:this.props.width, left:this.props.left}}>
<Card className={this.props.selected?'scene-thumb-selected':'scene-thumb'}>
<span>Hello world!</span>
</Card>
</div>
);
}

material-ui change the height of the drawer

I'm using react and material-ui in my project and I have come across a simple issue that I just dont't know how to solve.
I want to create a drawer and set its height in a way that when it will open, it wont open over the app bar.
There is no parameter in the Drawer component for the height, I also tried to override its style and setting up the height on the style object like this :
<Drawer style={{height:'90%'}} />
But it didn't work.
The only way I can think of, is editing the code of the Drawer component, but ofcourse I want to avoid that.
Any idea on how I can define the height?
Here you go:
<Drawer open={this.state.open} containerStyle={{height: 'calc(100% - 64px)', top: 64}}>
<MenuItem>Menu Item</MenuItem>
<MenuItem>Menu Item 2</MenuItem>
</Drawer>
containerStyle is prohibited in version 1.0 and above
So you need to use props classes instead
Here is an example to this nontrivial case
import {withStyles, createStyleSheet} from 'material-ui/styles'
const styleSheet = createStyleSheet({
paper: {
height: 'calc(100% - 64px)',
top: 64
}
})
class CustomDrawer extends Component {
...
render () {
const classes = this.props.classes
return (
<Drawer
classes={{paper: classes.paper}}
>
...
)
}
CustomDrawer.propTypes = {
classes: PropTypes.object.isRequired
}
export default withStyles(styleSheet)(CustomDrawer)

Resources