Update - solved, Thanks Konrad! I had text that was blocking the search bar, adding pointer-events: none; to the text fixed my issue.
I am learning react and trying to create a search bar. Right now, I just want to have the user's input to the search bar be logged to the console or pop up in a message when they submit text.
However, I cannot even enter text into my search bar right now.
I have tried looking at the react documentation (https://reactjs.org/docs/forms.html) and (https://reactjs.org/docs/state-and-lifecycle.html) and I think the issue has something to do with setting state but I am not sure where I am going wrong. I saw other people on stack overflow had this issue, but it was fixed for them when they added 'value=' to their <in bar which did not work for me.
Thank you for reading!
import React from 'react'
import './SearchBar.css'
class SearchBar extends React.Component { //
constructor(props){
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A value was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<div className='Container'>
<form className='SearchBar' onSubmit={this.handleSubmit}>
<input type="text" placeholder='Enter the link to your IMDB profile' value={this.state.value} onChange={this.handleChange} />
</form>
<p className='Warning'>Make sure your imdb profile is set to public!</p>
</div>
);
}
}
export default SearchBar
As pointed out by Konrad below, the isolated component works fine, so there must be some issue in my integration. When I comment out my App.css file, it also works fine, so it is some issue in those that is causing me an issue, does anyone know what I need to add?
Here is my app.css:
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
#media (prefers-reduced-motion: no-preference) {
.App-logo {
height: 20vmin;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(20px + 2vmin);
color: white;
}
.Wrapped{
position:absolute;
left: 40%;
height: 75%;
font-size: 75px;
transform: rotate(45deg);
font-family: "Apple Chancery", cursive;
color:deeppink
}
.App-link {
color: #61dafb;
}
#keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
and my app.js:
import logo from './Logo_2016.png';
import './App.css';
import SearchBar from './components/SearchBar';
function App() {
return (
<div className="App">
<header className="App-header">
<h1 className='Wrapped'> Wrapped </h1>
<img src={logo} className="App-logo" alt="logo" />
<p> Welcome! </p>
<SearchBar/>
</header>
</div>
);
}
export default App;
Related
In my Class component Field.jsx render(), I'm expanding my <Position> component using <Flipper>, (an abstracted flip animation), like so:
import { Flipper, Flipped } from 'react-flip-toolkit'
import { Position } from "./Position";
import "./css/Position.css";
class Field extends Component {
constructor(props) {
super(props);
this.state = {
fullScreen: false,
};
}
toggleFullScreen() {
this.setState({ fullScreen: !this.state.fullScreen });
}
...
render() {
const { players } = this.props;
const { fullScreen } = this.state;
if(players){
return (
<div className="back">
<div className="field-wrapper" >
<Output output={this.props.strategy} />
<Flipper flipKey={fullScreen}>
<Flipped flipId="player">
<div className="field-row">
{this.getPlayersByPosition(players, 5).map((player,i) => (
<Position
key={i}
className={fullScreen ? "full-screen-player" : "player"}
getPositionData={this.getPositionData}
toggleFullScreen={this.toggleFullScreen.bind(this)}
>{player.name}</Position>
))}
</div>
</Flipped>
</Flipper>
</div>
</div>
);
}else{
return null}
}
When I render it, I get clickable items from the mapped function getPlayersByPosition(), like so:
And if I click on each item, it expands to a div with player name:
Which is passed as props.children at component <div>
Position.jsx
import React from "react";
import "./css/Position.css";
export const Position = props => (
<div
className={props.className}
onClick={() => {
props.getPositionData(props.children);
props.toggleFullScreen();
console.log(props.getPositionData(props.children))
}}
>
{props.children}
</div>
);
getPositionData(), however, returns an object with many items on its turn, as seen by console above:
{matches: 7, mean: 6.15, price: 9.46, value: 0.67, G: 3, …}
QUESTION:
How do I pass and print theses other props keys and values on the expanded purple div as text?, so as to end with:
Patrick de Paula
matches: 7
mean: 6.15
price:9.46
....
NOTE:
Position.css
.position-wrapper {
height: 4em;
display: flex;
justify-content: center;
align-items: center;
font-weight: lighter;
font-size: 1.4em;
color: #888888;
flex: 1;
/*outline: 1px solid #888888;*/
}
.player {
height: 4em;
width: 4em;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
font-weight: lighter;
font-size: 1.4em;
/*background-color: #66CD00;*/
color: #ffffff;
}
.full-screen-player {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: pointer;
background-image: linear-gradient(
45deg,
rgb(121, 113, 234),
rgb(97, 71, 182)
);
}
Looks like the props are all set & ready to be print as seen on your console. You can access them via props.getPositionData(props.children).property_name_here or destructure them
export const Position = props => {
const { matches, mean, price } = props.getPositionData(props.children);
return (
<div
className={props.className}
onClick={() => {
props.getPositionData(props.children);
props.toggleFullScreen();
console.log(props.getPositionData(props.children))
}}
>
<p>Name: {props.children}</p>
<p>Matches: {matches}</p>
<p>Mean: {mean}</p>
<p>Price: {price}</p>
</div>
)
}
Regarding the issue on the fullScreen prop (see comments section):
Is there a way to print them ONLY after toggleFullScreen()
Since you already have a state on the Field component which holds your fullScreen value, on your Field component, you need to pass the fullScreen prop as well to the Position component. e.g., fullScreen={this.state.fullScreen}. Back on Position component, have some condition statements when you are rendering.
Example:
<>
{props.fullScreen &&
<p>Name: {props.children}</p>
}
</>
I would like to add some transition styling to my side navigation on my app. I am able to do this using normal classes however in this tutorial they use css modules and i am unsure how to do this using css modules.
I would like my nav to glide in and out, at the moment it jumps statically when the onClick function fires - toggleSideDrawer.
I have used this logic but I am not sure if it is doing anything:
className={props.toggleSideDrawer ? classes.SideDrawerOpen : classes.SideDrawer
Essentially i want that when the user clicks the toggle, the transform property switches from translateX(-100%) to translateX(0) but this is not happening.
Side nav code:
import React from "react";
import Logo from "../../Logo/Logo";
import NavigationItems from "../NavigationItems/NavigationItems";
import Backdrop from "../../UI/Backdrop/Backdrop";
import Aux from "../../../hoc/Aux";
import classes from "./SideDrawer.css";
const SideDrawer = props => {
return (
<Aux classname={classes.SideDrawer}>
<Backdrop
showBackdrop={props.showSideDrawer}
clicked={props.toggleSideDrawer}
/>
{props.showSideDrawer && (
<div
onClick={props.toggleSideDrawer}
className={
props.toggleSideDrawer ? classes.SideDrawerOpen : classes.SideDrawer
}
>
<div className={classes.Logo}>
<Logo />
</div>
<nav>
<NavigationItems />
</nav>
</div>
)}
</Aux>
);
};
export default SideDrawer;
Where the code is used in my Layout component:
import React, { useState } from "react";
import Aux from "../Aux";
import classes from "./Layout.css";
import Toolbar from "../../components/Navigation/Toolbar/Toolbar";
import SideDrawer from "../../components/Navigation/SideDrawer/SideDrawer";
const layout = props => {
const [showSideDrawer, setShowSideDrawer] = useState(false);
return (
<Aux>
<SideDrawer
showSideDrawer={showSideDrawer}
toggleSideDrawer={() => {
setShowSideDrawer(!showSideDrawer);
}}
/>
<Toolbar
onMenuClick={() => {
setShowSideDrawer(!showSideDrawer);
}}
/>
<main className={classes.mainContent}> {props.children} </main>
</Aux>
);
};
export default layout;
CSS:
.SideDrawer {
position: fixed;
width: 280px;
max-width: 70%;
height: 100%;
left: 0;
top: 0;
z-index: 200;
background-color: white;
padding: 32px 16px;
box-sizing: border-box;
transform: translateX(-100%);
}
#media (min-width: 500px) {
.SideDrawer {
display: none;
}
}
.Logo {
height: 11%;
text-align: center;
}
.SideDrawerOpen {
position: fixed;
width: 280px;
max-width: 70%;
height: 100%;
left: 0;
top: 0;
z-index: 200;
padding: 32px 16px;
box-sizing: border-box;
background-color: red;
transform: translateX(0);
transition: transform 0.3s ease-out;
}
The thing is that you need the element will has the transition rule all the time.
My suggestion is to set a static class which which will hold all the styles and addd another one only for overriding transform to make it move.
Something like that (it uses scss but it's easy to do it with css)
.SideDrawer {
position: fixed;
width: 280px;
max-width: 70%;
height: 100%;
left: 0;
top: 0;
z-index: 200;
background-color: white;
padding: 32px 16px;
box-sizing: border-box;
transition: transform .3s ease;
transform: translateX(-100%);
&.show {
transform: translateX(0);
}
}
export const App = () => {
const [showSideDrawer, setShowSideDrawer] = useState(false);
const sidebarClasses = classname([
styles.SideDrawer,
{
[styles.show]: showSideDrawer
}
]);
const ToggleSidebar = () => {
return (
<button onClick={() => setShowSideDrawer(!showSideDrawer)}>
Toggle Sidebar
</button>
);
};
return (
<Fragment>
<h1>App</h1>
<div className={sidebarClasses}>
<div>Sidebar content</div>
<ToggleSidebar />
</div>
<ToggleSidebar />
</Fragment>
);
};
https://codesandbox.io/s/xenodochial-framework-04sbe?file=/src/App.jsx
#MoshFeu helped me fix this.
The problem is that you render the drawer only when showSideDrawer so before it becomes true, the sidebar is not in the DOM yet so the transition is not affecting it.
The solution is to keep it in the DOM all the time but toggle . Open class to change the style.
There are libraries that knows to make the transition works even for elements that are not in the DOM but it's a bit more complicated.
code fix for SideDrawer.js without the conditional within the return
class SideDrawer extends Component {
render() {
let sideDrawerClass = [classes.SideDrawer];
// SideDrawer will now be an array with the side drawer classes and the open class
if (this.props.showSideDrawer) {
sideDrawerClass.push(classes.Open);
}
return (
<Aux classname={classes.SideDrawer}>
<Backdrop
showBackdrop={this.props.showSideDrawer}
clicked={this.props.toggleSideDrawer}
/>
<div
className={sideDrawerClass.join(" ")}
onClick={this.props.toggleSideDrawer}
>
<div className={classes.Logo}>
<Logo />
</div>
<nav>
<NavigationItems />
</nav>
</div>
</Aux>
);
}
}
export default SideDrawer;
I created a simple react app to try and play with react-monaco-editor. Here is my code.
import React, { Component } from 'react';
import MonacoEditor from 'react-monaco-editor';
import './App.css';
const code = `
import React from "react";
class App extends React.Component {
render() {
return (
<span>I mean really come one</span>
);
}
}
export default App;
`;
class App extends Component {
onChange = (value) => {
console.log(value);
}
editorDidMount = (editor, monaco) => {
console.log('editorDidMount', editor);
editor.focus();
}
render() {
const options = {
selectOnLineNumbers: true
};
return (
<div className="App">
<MonacoEditor
height="600"
width="600"
language="javascript"
theme="vs-dark"
value={code}
onChange={this.onChange}
editorDidMount={this.editorDidMount}
/>
</div>
);
}
}
export default App;
For some reason tho, the text in the editor is showing up in the middle, and my cursor is as the start of line as expected.
Here is a screenshot of the issue.
This might be an old question but in React in the default App.css there is a line which sets the text-align to center.
If it looks similar to this:
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #09d3ac;
}
you can just delete this part:
.App {
text-align: center;
}
I'm using react. Material-ui is for Cards. For Grid I'm using CSS Grid Layout. So far it looks like this:
But my goal is something like this:
And I have 2 problems:
I want to have all these cards the same height (415px). I tried height: 415px on .BeerListingScroll-info-box but it doesn't work.
Images of bottles and kegs are diffrent in size [keg (80px x 160px) vs. bottle (80px x 317px)]. Is there any way to make them more similar in rendered size?
-
Code:
BeerListingScroll
import React, { Component } from 'react';
import ReduxLazyScroll from 'redux-lazy-scroll';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { fetchBeers } from '../../actions/';
import BeersListItem from '../../components/BeersListItem';
import ProgressIndicator from '../../components/ProgressIndicator';
import './style.css';
class BeerListingScroll extends Component {
constructor(props) {
super(props);
this.loadBeers = this.loadBeers.bind(this);
}
loadBeers() {
const { skip, limit } = this.props.beers;
this.props.fetchBeers(skip, limit);
}
render() {
const { beersArray, isFetching, errorMessage, hasMore } = this.props.beers;
return (
<div className="container beers-lazy-scroll">
<ReduxLazyScroll
isFetching={isFetching}
errorMessage={errorMessage}
loadMore={this.loadBeers}
hasMore={hasMore}
>
<div className="BeerListingScroll-wrapper">
{beersArray.map(beer => (
<div key={beer.id} className="BeerListingScroll-info-box">
<BeersListItem beer={beer} />
</div>
))}
</div>
</ReduxLazyScroll>
<div className="row beers-lazy-scroll__messages">
{isFetching && (
<div className="alert alert-info">
<ProgressIndicator />
</div>
)}
{!hasMore &&
!errorMessage && (
<div className="alert alert-success">
All the beers has been loaded successfully.
</div>
)}
</div>
</div>
);
}
}
function mapStateToProps(state) {
return {
beers: state.beers,
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ fetchBeers }, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(BeerListingScroll);
BeerListingScroll css
.BeerListingScroll-wrapper {
display: grid;
margin: 0;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr) ) ;
background-color: #f7f7f7;
}
.BeerListingScroll-info-box {
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
width: 320px;
}
/* This applies from 600px onwards */
#media (min-width: 1820px) {
.BeerListingScroll-wrapper {
margin: 0 400px;
}
}
#media (min-width: 1620px) {
.BeerListingScroll-wrapper {
margin: 0 300px;
}
}
#media (min-width: 1366px) {
.BeerListingScroll-wrapper {
margin: 0 200px;
}
}
BeerListItem is the child of BeerListingScroll
import React from 'react';
import Card, { CardContent } from 'material-ui/Card';
import Typography from 'material-ui/Typography';
function BeerListItem(props) {
return (
<div>
<Card raised>
<CardContent>
<img src={props.beer.image_url} alt="beer" width="30%" />
<Typography variant="headline" component="h2">
{props.beer.name}
</Typography>
<Typography component="p">{props.beer.tagline}</Typography>
</CardContent>
</Card>
</div>
);
}
export default BeerListItem;
Full project on github -> Github
So for image sizes here I got great answer.
And I added:
.BeerListItem-img {
height: auto;
max-height: 250px;
width: auto;
max-width: 250px;
}
And for card size I just added inside BeerListItem class to Card like so (.BeerListItem-main-card):
function BeerListItem(props) {
return (
<div>
<Card raised className="BeerListItem-main-card">
<CardContent>
<img
src={props.beer.image_url}
alt="beer"
className="BeerListItem-img"
/>
<Typography variant="headline" component="h2">
{props.beer.name}
</Typography>
<Typography component="p">{props.beer.tagline}</Typography>
</CardContent>
</Card>
</div>
);
}
And here is corresponding css to that component.
.BeerListItem-main-card {
width: 320px;
height: 415px;
}
.BeerListItem-img {
height: auto;
max-height: 250px;
width: auto;
max-width: 250px;
}
With that two changes, I've managed to achieve my goal.
You should try exploring display:flex;
Here is a link to a fantastic code pen that may help you achieve what you want:
https://codepen.io/enxaneta/full/adLPwv
More specifically here is an example I've created with what you might be trying to achieve.
https://jsfiddle.net/dalecarslaw/sxdr3eep/
Here is the areas of code you should focus on:
display:flex;
align-items:space-between;
justify-content:space-between;
flex-wrap:wrap;
I'm building a personal site w/ React and trying to get some h2's to fade in after a couple of seconds after load. I'm using ReactCssTransitionGroup on the following Component:
import React, { Component } from 'react';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
class TitleArea extends Component {
constructor(props) {
super(props);
this.state = {
ids: ['h2-one', 'h2-two', 'h2-three'],
h2Texts: ['Text1', 'Text2', 'Text3']
};
}
render() {
const descriptionDivs = this.state.ids.map( (id, index)=> {
return(<h2 key={id} id={id}>
{this.state.h2Texts[index]}
</h2>)
})
return (
<div className='row odd'>
<h1> MYNAMEHERE </h1>
<div className='description-container'>
<ReactCSSTransitionGroup
transitionName="descriptions"
transitionEnterTimeout={500}
transitionLeaveTimeout={300}>
{descriptionDivs}
</ReactCSSTransitionGroup>
</div>
</div>
);
}
}
export default TitleArea;
CSS/SASS:
.site-container {
text-align: center;
font-family: 'Source Code Pro', monospace;
h1 {
font-size: 50px;
font-family: 'Arvo', serif;
h2 {
font-size: 25px;
}
}
.descriptions-enter {
opacity: 0.01;
}
.descriptions-enter.descriptions-enter-active {
opacity: 1;
transition: opacity 500ms ease-in;
}
I'd ideally want each h2 to transition in one after another, but I'm trying to get a handle on the react-addons first before I jump to staggering the fade-ins. Does anyone have any experience with css transitions in React. Tried following the docs but got a bit lost. Any insight greatly appreciated! Thanks