React Semantic UI - Sticky Sidebar - semantic-ui

Is there any way to use react-semantic-ui's <Sidebar> to have a sticky sidebar?
One way to achieve the sticky behavior is to just skip and not use <Sidebar.Pushable>, but then I can't use <Sidebar.Pusher>'s dimmed prop.
Other than the method I stated above, I found no other method that's not too hacky.

I was looking for this a while back. Here is how I did it:
my-sidebar.css:
.pushable {
height: auto;
}
.pushable > .pusher {
min-height: fit-content;
}
It was long time ago so let me know if it didn't work so I can update this.

Sticky with sidebar
I wanted to have a sticky error message overflowing the content with a vertical sidebar pushable on the left.
I tried for hours with sticky but I have not been able to make it.
The cleanest solution I found is to use Portal and to add css to push it at the top.
This is my message component (next to the pushable sidebar)
class AppAlert extends React.Component{
getColor(){
return 'green';
}
render(){
return (
<TransitionablePortal open={true} transition={{ animation: 'swing down', duration:1000 }} closeOnDocumentClick={false}>
<Sidebar style={{position: 'fixed', top: '0'}} direction="top" animation="overlay">
<Message color={this.getColor()}>
My message<br/>
My message<br/>
My message<br/>
</Message>
</Sidebar>
</TransitionablePortal>
)
}
}
export default AppAlert;
Screenshot of the result

Related

Vuetify navbar (v-app-bar) overlap scrollbar

The same problem as this post except it is Vuetify.
Is there any solution that use provided API? CSS would be the last option I choose.
codepen demo
<template>
<v-app-bar app dark absolute class="navbar-bg" >
<v-app-bar-nav-icon #click="toggleSidebar" />
<v-toolbar-title>Homepage</v-toolbar-title>
</v-app-bar>
</template>
Currently, there's no a single prop in API.
But you may help yourself a lot with a built-in vuetify classes and directives.
First of all, you (sadly) need to write some CSS to manually disable initial page scrolling:
html {
overflow-y: hidden;
}
.scrollable {
overflow-y: scroll;
}
Then you need to add <v-main> component to your application with scrollable pt-0 mt-16 classes and wrap all of your future app components into it. This classes will adjust the padding from the default <v-app-bar> and enable scrolling directly in <v-main>.
Finally, you should add v-resize directive to <v-main> to automatically recalculate your page size when user will resize a page:
<v-main class="scrollable pt-0 mt-16" v-resize="onResize">
...your application data...
</v-main>
...
methods: {
onResize() {
//64px is v-app-bar height in your case
document.querySelector(".scrollable").style.height = (window.innerHeight - 64) + 'px';
}
},
That's it. You may then create your custom component to wrap <v-main> and forget about such manipulations.
Codepen link with an example

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>
);
}

className on Drawer component doesnt work

I'm using react and material-ui and I have come across an issue, I want to define some css behavior for the drawer component, and I have read that it is quite simple, that all I have to do is use the className property, but for some reason it doesn't work.
Here is my css:
.drawer {
width: 200px
}
.drawer:hover {
background-color: black
}
Here is my usage of the drawer:
<Drawer open={this.state.isLeftNavOpen}
docked={false}
className='drawer'
onRequestChange={this.changeNavState}>
<MenuItem primaryText='Men'
onTouchTap={() => browserHistory.push({pathname: '/products', query: {category: MEN}})}/>
<MenuItem primaryText='Women'
onTouchTap={() => browserHistory.push({pathname: '/products', query: {category: WOMEN}})}/>
<MenuItem primaryText='Kids'
onTouchTap={() => browserHistory.push({pathname: '/products', query: {category: KIDS}})}/>
</Drawer>
I tried wrapping the Drawer with div but still no success.
Any idea what I'm doing wrong?
The library does seem to be adding the className, but this issue you are seeing seems to be a consequence of material-ui setting styles directly on the element, which take priority over those on the class you've added. There are a couple of options until the library makes some changes/fixes, such as:
1) set the width and styles inline with the style and/or width properties: (fiddle)
<Drawer open={this.state.isLeftNavOpen}
docked={false}
width={200}
style={{'background-color': 'black'}}
className='drawer'>
Unfortunately this approach doesn't allow for :hover styling though, and their current inline styling solution is likely to be changed in the near future (see issue 1951 and those that follow it). That means that your only real solution at the moment to this specific problem is to:
2) mark the styles in the css as !important to override those set on the element by the library: (fiddle)
.drawer {
width: 200px !important;
}
.drawer:hover {
background-color: black !important;
}
You can also use a combination of the two, passing the width as a prop and only having the hover background style be !important.
(Using LeftNav (the older version of Drawer) in the fiddles because it's in the easiest-to-consume package I could find at time of writing for material-ui, found it on this comment).

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)

bootstrap 3 - not pushing footer to the bottom of page

I received a task at work to create some mini-webpage layout with bootstrap. I decided to base on already done layout (Amoeba). Here is the preview: Amoeba bootstrap link
Well, on localhost almost works except one thing - footer. Just take a look on provided link and then: click Portfolio (from navigation) and then filter the gallery by Photography.
When you will scroll down you will see ugly space. And this is my issue. I dont want that. So i thought that I need a footer OR portfolio div class which will automatically resize to proper size. BUt I dont how how to achieve that. Any tips?
You need only to change the code of modernizr slightly. Change forceHeight to false and will work good.
if (Modernizr.mq("screen and (max-width:1024px)")) {
jQuery("body").toggleClass("body");
} else {
var s = skrollr.init({
mobileDeceleration: 1,
edgeStrategy: 'set',
forceHeight: false,
smoothScrolling: true,
smoothScrollingDuration: 300,
easing: {
WTF: Math.random,
inverted: function(p) {
return 1-p;
}
}
});
}
Im not sure why, but your body element gets some height inline styling. Anyways here is the solution of your problem:
body {
height:100% !important; // inline styles, so you need to add "!important" here
position:relative;
}
#footer {
position: absolute;
width: 100%;
bottom: 0px;
}
You can also add wrapper div if you don't want to add position:relative and height:100%!important properties to your body element. Just see how it works and choose a better option for you.

Resources