Semantic UI React: how to add a transition to Popup? - reactjs

I'm building a "hovering" menu, using semantic-ui-react's Popup, and want to add a simple show-hide transition, how it can be done?

this is probably coming in too late for this specific OP, but might be useful for someone else trying to figure same out.
I believe you can use the TransionablePortal as shown in the example. Just for fun, I adapted that example to what I think you are trying to do:
import React, { Component } from 'react'
import { Button, Menu, TransitionablePortal } from 'semantic-ui-react'
export default class TransitionablePortalExamplePortal extends Component {
state = { open: false }
handleOpen = () => this.setState({ open: true })
handleClose = () => this.setState({ open: false })
render() {
const { open } = this.state
return (
<TransitionablePortal
closeOnTriggerClick
onOpen={this.handleOpen}
onClose={this.handleClose}
transition={{animation: "fade left", duration: 500 }}
openOnTriggerClick
trigger={
<Button circular basic
icon="ellipsis vertical"
negative={open}
positive={!open}
/>
}
>
<Menu vertical style={{ right: '1%', position: 'fixed', top: '0%', zIndex: 1000}}>
<Menu.Item>Menu Item 1</Menu.Item>
<Menu.Item>Menu Item 2</Menu.Item>
</Menu>
</TransitionablePortal>
)}}
You should be able to make the transition use onMouseEnter and onMouseLeave if you want same transition to be on hover, instead of on click.

You can find in their official documentation example where you can make custom style for popup
import React from 'react'
import { Button, Popup } from 'semantic-ui-react'
const style = {
borderRadius: 0,
opacity: 0.7,
padding: '2em',
}
const PopupExampleStyle = () => (
<Popup
trigger={<Button icon='eye' />}
content='Popup with a custom style prop'
style={style}
inverted
/>
)
export default PopupExampleStyle
You can try to add transition property here

Related

Manage the reload of a component through another component located in a different route in REACT

I am having difficulties with my react application. I have a component that cyclically calls iframes, making them visible for a few seconds. The "reload" takes place via a button.
However, I need to check the iframe reload from another page. For example, create a "configuration.js" component in which there is a button which, once clicked, activates the "reload" function.
The iframe reload is however rendered in "http: // localhost: 3000 / simulatoretv", while the button that starts the reload is present in "http: // localhost: 3000 / configurator".
I hope I've been sufficiently clear. I attach the script of the component "Advertising", through which I run the reload of the iframes.
import React, { Component } from "react";
class Pubblicità extends Component {
state = {
index: 0,
iframeSrcs: ["/300x250", "/160x600", "/468x60"],
visibility: false
};
reload = () => {
const iframeLength = this.state.iframeSrcs.length;
if (this.state.index < iframeLength) {
this.setState({
index: this.state.index + 1,
visibility: true
});
} else {
this.setState({ index: 0, visibility: true }); //starting again
}
setTimeout(() => {
this.setState({ visibility: false });
}, 15000);
};
render() {
return (
<div>
<button
style={{
position: "absolute",
left: 0,
right: 0,
top: 500
}}
onClick={this.reload}
>
pubblicità
</button>
{this.state.visibility ? (
<iframe
style={{
position: "absolute",
left: 500,
right: 0,
top: 10
}}
key={this.state.index}
title="AdSlot"
src={this.state.iframeSrcs[this.state.index]}
height="100%"
width="100%"
scrolling="no"
frameborder="0"
/>
) : (
""
)}
</div>
);
}
}
export default Pubblicità;
This is the other component, where I would like the controlled iframes to be shown by the "Pubblicità" component.
The route of this component is "http: // localhost: 3000 / platformOTT".
import React, { Component } from "react";
import SimulatoreTV from "./SimulatoreTV";
import Pubblicità from "./Pubblicità";
class PiattaformaOTT extends Component {
render() {
return (
<div>
<SimulatoreTV />
<Pubblicità />
</div>
);
}
}
export default PiattaformaOTT;
Thanks to those who want to help me.

Reactjs autoscroll to bottom of container

I'm trying to make a basic chat application where the use enters a message, then it appears on the screen. Like a normal messaging system I'd like the scroll bar to be at the bottom point by default. I've attempted to that that with the code below.
Here is the sandbox:
https://codesandbox.io/s/unruffled-pasteur-nz32o
And the code:
import React, { Component } from "react";
export default class Messages extends Component {
setScroll() {
this.messagesEnd.scrollIntoView({ behavior: "auto" });
}
componentDidMount() {
this.setScroll();
}
componentDidUpdate() {
this.setScroll();
}
render() {
return this.props.messages.map(message => {
return (
<div>
<h2>{message.message}</h2>
<div
style={{ float: "left", clear: "both" }}
ref={el => {
this.messagesEnd = el;
}}
/>
</div>
);
});
}
}
It works fine, however if there is a scrollbar in a component outside that container it also sets that to the bottom as well. Is there any way I can only set the scroll bar of the container to bottom (independent of any other scroll bars on the screen)?
Update your setScroll to include block: 'end' as an option for scrollIntoView:
setScroll() {
this.messagesEnd.scrollIntoView({ behavior: "auto", block: "end" });
}
https://codesandbox.io/s/wispy-water-463xy

react-custom-scrollbars jumps to top on any action

I am using react-custom-scrollbars in a react web app because I need to have two independant scroll bars, one for the main panel and one for the drawer panel. My issue is that the content in the main panel is dynamic and whenever I take some action in the main panel that changes state the scroll bar jumps to the top of the panel again.
UPDATE:
I believe I need to list for onUpdate and handle the scroll position there. If it has changed then update if not do not move the position?
In code, I have a HOC call withScrollbar as follows:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import AutoSizer from 'react-virtualized-auto-sizer';
import { Scrollbars } from 'react-custom-scrollbars';
import { colors } from '../../theme/vars';
import { themes } from '../../types';
// This is a Higher Order Component (HOC) used to
// provide a scroll bar to other components
export default (ChildComponent, styling) => {
class ComposedComponent extends Component {
state = {
// position: ??
};
handleUpdate = () => {
//update position
//this.scrollbar.scrollToBottom();
};
render() {
return (
<AutoSizer>
{
({ width, height }) => (
<Scrollbars
style={{ width, height, backgroundColor: colors.WHITE, overflow: 'hidden', ...styling }}
onUpdate={() => this.handleUpdate()}
renderThumbVertical={props => <Thumb {...props} />}
autoHide
autoHideTimeout={1000}
autoHideDuration={200}
>
<ChildComponent {...this.props} />
</Scrollbars>
)
}
</AutoSizer>
);
}
}
return ComposedComponent;
};
const Thumb = styled.div`
background-color: ${props =>
props.theme.theme === themes.LIGHT ? colors.BLACK : colors.WHITE};
border-radius: 4px;
`;
in my MainView component I just wrap the export like this:
export default withScrollbar(LanguageProvider(connect(mapStateToProps, null)(MainView)));
I have read a few similar issues on this like this one: How to set initial scrollTop value to and this one scrollTo event but I cannot figure out how to implement in my case. Any tips or suggestions are greatly appreciated.
So I found a way to get this to work and it feels like a complete hack but I'm posting in hopes it might help someone else.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import AutoSizer from 'react-virtualized-auto-sizer';
import { Scrollbars } from 'react-custom-scrollbars';
import { colors } from '../../theme/vars';
import { themes } from '../../types';
// This is a Higher Order Component (HOC) used to
// provide a scroll bar to other components
export default (ChildComponent, styling) => {
class ComposedComponent extends Component {
state = {
stateScrollTop: 0,
};
onScrollStart = () => {
if (this.props.childRef) { // need to pass in a ref from the child component
const { scrollTop } = this.props.childRef.current.getValues();
const deltaY = Math.abs(scrollTop - this.state.stateScrollTop);
if (deltaY > 100) { // 100 is arbitrary. It should not be a high value...
this.props.childRef.current.scrollTop(this.state.stateScrollTop);
}
}
};
handleUpdate = () => {
if (this.props.childRef) {
const { scrollTop } = this.props.childRef.current.getValues();
this.setState({ stateScrollTop: scrollTop });
}
};
render() {
return (
<AutoSizer>
{
({ width, height }) => (
<Scrollbars
ref={this.props.childRef}
style={{ width, height, backgroundColor: colors.WHITE, overflow: 'hidden', ...styling }}
onScrollStart={e => this.onScrollStart(e)}
onUpdate={e => this.handleUpdate(e)}
renderThumbVertical={props => <Thumb {...props} />}
autoHide
autoHideTimeout={1000}
autoHideDuration={200}
>
<ChildComponent {...this.props} />
</Scrollbars>
)
}
</AutoSizer>
);
}
}
return ComposedComponent;
};
const Thumb = styled.div`
background-color: ${props =>
props.theme.theme === themes.LIGHT ? colors.BLACK : colors.WHITE};
border-radius: 4px;
`;
I use this HOC like this:
create a ref for the component you want to use it with
pass the ref to the component that will use the HOC:
class SomeChildComponent extends Component {
...
viewRef = React.createRef();
...
render() {
return ( <MainView childRef={this.viewRef} />)
}
import and wrap the component
import withScrollbar from '../../hoc/withScrollbar';
...
export default withScrollbar(MainView);
I tried the above solution and it didn't seem to work for me.
However what did work was making sure that my child components inside Scrollbars were wrapped in a div with a height of 100%:
<Scrollbars>
<div style={{ height: '100%' }}>
<ChildComponent />
<ChildComponent />
</div>
</Scrollbars>

Custom Read More in React.js

As you can see this image, "+Las mor" is a "see more" button, which when clicked expands the whole paragraph written above.
I need React code for this to be functional. Any help will be appreciated.
I am also attaching the code upon which this functionality is to be applied.
<section id="section-2">
<h4>Om mig</h4>
<p className="para">
{about}
</p>
</section>
<p style={{color:'#d39176'}}>
<img src={plus1} />
Läs mer
</p>
You probably want a button that toggles the state of expanded text onClick. Upon hitting the button you would set the state to the opposite of what it was. Here's a working example I wrote with React and Reactstrap. I just tested it locally. Here's a video demo of what you will see: https://screencast.com/t/in5clDiyEcUs
import React, { Component } from 'react'
import { Container, Button } from 'reactstrap'
class App extends Component {
constructor(props) {
super(props)
this.state = {
expanded: false //begin with box closed
}
}
//function that takes in expanded and makes it the opposite of what it currently is
showButton = () => {
this.setState({ expanded: !this.state.expanded })
}
render() {
const { expanded } = this.state
return (
<Container style={ { justifyContent: 'center', alignItems: 'center' } }>
<div>Always visable text.</div>
<Button onClick={ this.showButton }>Expand</Button>
{
expanded && //show if expanded is true
<div>Extended Text Here</div>
}
</Container>
)
}
}
export default App

admin on rest hide resource component in sidebar

I need a resource with all its configuration, but I don't want it to be showed in sidebar
You can omit the list prop for a Resource if you want to hide it in the sidebar menu.
<Resource name="posts" />
I found a different "hacky" way
You can add in your css the following to hide from the menu the resource
.MuiDrawer-root a[href^='#/resource-to-exclude'] {
display: none;
}
As explained in the documentation, you can provide your Menu component to the Admin component using it's menu prop. See
https://marmelab.com/react-admin/Admin.html#menu
Please note that this prop will be deprecated soon in favor of appLayout but you'll still use this custom menu in your custom layout anyway.
// in src/Menu.js
import React from 'react';
import { connect } from 'react-redux';
import { MenuItemLink, getResources } from 'react-admin';
import { withRouter } from 'react-router-dom';
import Responsive from '../layout/Responsive';
const Menu = ({ resources, onMenuClick, logout }) => (
<div>
{resources
.filter(resource => resource.name !== 'excluded-resource')
.map(resource => (
<MenuItemLink to={`/${resource.name}`} primaryText={resource.name} onClick={onMenuClick} />
))
}
<Responsive
small={logout}
medium={null} // Pass null to render nothing on larger devices
/>
</div>
);
const mapStateToProps = state => ({
// Rerieve all known resources
resources: getResources(state),
});
export default withRouter(connect(mapStateToProps)(Menu));
If your goal is to hide the entire sidebar, and make it not visible to the user, in your theme.js
try add the following code:
RaSidebar: {
drawerPaper: {
display: 'none',
},
},
eg.
const baseTheme = createTheme({
overrides: {
...<components you want override etc>...,
// React-admin
RaSidebar: {
drawerPaper: {
display: 'none',
},
},
},
});

Resources