I'm trying to return a number of divs and dynamically place them in a grid. I've never tried this before, and I think my syntax may be off. None of the divs are appearing. The template is working, and the divs should currently fill grid container and turn it black with a button.
export const DayColumn = ({ day }) => {
const { timeColumn } = useTableContext();
return (
<Wrapper gridInterval={timeColumn.length}>
<h2>{day}</h2>
{timeColumn.forEach((_, index) => {
index++;
return (
<div
key={index}
className='task-slot'
style={{ gridArea: `${index + 1} / 1 / ${index + 2} / 2;` }}
>
<h1>text</h1>
<BsPlusSquareFill />
</div>
);
})}
</Wrapper>
);
};
The styled component
const Wrapper = styled.div`
height: 100%;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: ${(props) => `100px repeat(${props.gridInterval}, 1fr);`};
grid-gap: 3px;
background-color: var(--clr-background-dark3);
border-radius: 7px;
h2 {
justify-self: center;
font-family: 'Oswald', sans-serif;
letter-spacing: 4px;
font-size: 2rem;
font-weight: 200;
color: var(--clr-text-light);
text-transform: capitalize;
}
.task-slot {
height: 100%;
width: 100%;
background-color: black;
}
`;
I fixed it. Needed to use map instead of forEach
Related
import styled from "styled-components";
import pic from "./assets/images/bg-sidebar-desktop.svg";
const App=()=> {
const [index, setIndex] = useState(0);
const navitems = [
{
step: "Step 1",
value: "Your info",
},
{
step: "Step 2",
value: "Select plan",
},
{
step: "Step 3",
value: "Add-ons",
},
{
step: "Step 4",
value: "Summary",
},
];
return (
<Container>
<Navbar imgUrl={pic}>
{navitems.map((item, key) => {
return (
<>
<Index onClick={(key)=>setIndex(key)}>{key + 1}</Index>
<Heading>{item.step}</Heading>
<Content>{item.value}</Content>
</>
);
})}
</Navbar>
</Container>
);
}
const Container = styled.div`
height: 70.5vh;
width: 55vw;
margin: auto;
margin-top: calc(100vh / 7);
border-radius: 1em;
background-color: white;
overflow: hidden;
font-size: .9em;
`;
const Navbar = styled.div`
border: 1px solid black;
background-image: url(${(props) => props.imgUrl});
background-repeat: no-repeat;
background-position: 100% 100%;
height: 66.7vh;
width: 15.5vw;
border-radius: 1em;
margin-top: calc((3.6vh) / 2);
margin-left: 0.8em;
color: #ffffff;
text-transform: uppercase;
`;
const Heading = styled.div`
// border: 1px solid red;
color: hsl(231, 11%, 63%);
text-indent: 5.5em;
letter-spacing: .005em;
font-size: .9em;
`;
const Content = styled.div`
// border: 1px solid white;
text-indent: 5em;
letter-spacing: .1em;
font-weight: bolder;
`;
const Index = styled.span`
border: 1px solid white;
display: inline-block;
border-radius: 50%;
height: 2em;
width: 2em;
text-align: center;
padding-top: 0.3em;
box-sizing: border-box;
position: relative;
top: 7%;
left: 10%;
`;
export default App;
NOTE: There is an Index component and a useState variable whose name is also index. Don't get confused.
I want that everytime I click on the Index component the index useState variable gets updated to that particular key value .The above code applies the inline event handler to Index component but index state variable is not changed correctly on clicking that.On console logging the index a string gets output .Here's the string
"SyntheticBaseEvent {_reactName: 'onClick', _targetInst: null, type: 'click', nativeEvent: PointerEvent, target: span.sc-eDvSVe.iTaECf, …}"
Do this:
<Index onClick={() => setIndex(key)}>{key + 1}</Index>
Explaination:
// Normal syntax for onClick:
onClick = {(event) => someFunc()}
// Your Code
// here you pass key as an argument so key here means click event
// so what you give setIndex is the click event and not the key
onClick = {(key) => setIndex(key)}
In your case "key" is event, which returns from the button:
onClick={(key)=>setIndex(key)
just remove then "key" from params of func, then key will be take from array index:
<Navbar imgUrl={pic}>
{navitems.map((item, index) => {
return (
<>
<Index onClick={()=>setIndex(index)}>{index + 1}</Index>
<Heading>{item.step}</Heading>
<Content>{item.value}</Content>
</>
);
})}
</Navbar>
I'm having trouble with the responsiveness of rendered items from an array of objects that are loaded by clicking a 'Load More' button. On every click 3 extra items are visible. So far so good. But when the screen-width gets smaller I want to render only two items per click and in the end only one item. The problem is that media queries, css-grid or flex-box and the load functionality presets, in the component, cancel each other out. If I want two items rendered I have to adjust the CSS rules and the actual JS code presets like the posts-per-page. In other words how to create a responsive 'Load More' functionality in react (hooks).
The component
const [ soldProperties, setSoldProperties ] = useState([])
const [ loadBtn, setLoadBtn ] = useState('Show More')
const [ currentSlice, setCurrentSlice ] = useState(3)
const [ perPage, setPerPage ] = useState(3)
useEffect(()=> {
setSoldProperties(soldProps.slice(0, currentSlice))
}, [currentSlice, soldProperties.length])
const loadMore = () => {
setCurrentSlice(currentSlice + perPage)
if (soldProperties.length === 6) {
setLoadBtn('Show Less')
}
if (soldProperties.length === soldProps.length){
setCurrentSlice(currentSlice - 6)
setLoadBtn('Show More')
}
}
return (
<div className="soldprops">
<div className="soldprops_header">Sold Properties:</div>
<div className="soldprops_grid">
{soldProperties && soldProperties.map(property => {
const { img, name, price, id } = property
return <div className="soldprops_grid_imageBox" key={id}>
<div className="image"><img src={process.env.PUBLIC_URL + `/soldProps/${img}`} alt="" style={{ width: '100%', height: 'auto' }} /></div>
<div className="footer"><span className="soldChateau">{name}</span><span className="soldPrice">${price},-</span></div>
</div>
})}
</div>
<button type="button" className="loadmoreBtn" onClick={loadMore} >{loadBtn}</button>
</div>
)
}
The scss
.soldprops {
position: relative;
max-width: 1920px;
margin: 0 auto;
height: auto;
#include center-content-column;
&_header {
width: 100%;
height: 50px;
color:rgb(163, 149, 184);
padding: 0 20px;
font-size: 1.2rem;
font-family: Arial, Helvetica, sans-serif;
#include center-content-row-start;
}
&_grid {
width: 100%;
padding: 0 20px;
margin-bottom: 50px;
height: auto;
#include center-content-row;
flex-wrap: wrap;
gap: 15px;
// display: grid;
// grid-template-columns: repeat(3, 1fr);
// grid-template-rows: repeat(1, 1fr);
// gap: 20px;
&_imageBox {
position: relative;
width:32%;
height: auto;
line-height: 0;
box-shadow: 0px 4px 4px rgb(11, 9, 14);
.image {
width: 100%;
height: auto;
opacity: 1;
}
}
}
Been searching on how to make a excel like filter using react-data-table-component, and found something interesting, like Data Table filtering using react-data-table-component.
Unfortunately, the FilterComponent Component seems to be deprecated, since I can't find anything regarding it but broken links, which is weird for such a interesting feature.
My code is the following:
const columns = Properties.columns;
const getSubHeaderComponent = () => {
return (
<FilterComponent
onFilter={(e) => {
let newFilterText = e.target.value;
filteredItems = statements.filter(
(item) =>
item.name &&
item.name.toLowerCase().includes(newFilterText.toLowerCase())
);
this.setState({ filterText: newFilterText });
}}
onClear={handleClear}
filterText={filterText}
/>
);
};
return (
<div>
<div className="row justify-content-md-center statements-table">
<div className="col-md-10">
<DataTable
columns={columns}
data={statements}
customStyles={Properties.customStyles}
fixedHeader
fixedHeaderScrollHeight="47em"
pagination
subheader
subHeaderComponent={getSubHeaderComponent()}
paginationPerPage={100}
paginationRowsPerPageOptions={[100, 500, 1000]}
subHeader
noHeader
/>
</div>
</div>
Any suggestions?
FilterComponent could be something as simple as
const FilterComponent = ({ filterText, onFilter, onClear }) => (
<div>
<input
type="text"
value={filterText}
onChange={onFilter}
/>
<button type="button" onClick={onClear}>
X
</button>
</div>
);
However, I found following official implementation of FilterComponent on Examples/Filtering | React Data Table Components (also referred Button.js) if you need it like that.
const TextField = styled.input`
height: 32px;
width: 200px;
border-radius: 3px;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border: 1px solid #e5e5e5;
padding: 0 32px 0 16px;
&:hover {
cursor: pointer;
}
`;
const ButtonStyle = styled.button`
background-color: #2979ff;
border: none;
color: white;
padding: 8px 32px 8px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
border-radius: 3px;
&:hover {
cursor: pointer;
}
`;
const Button = ({ children, ...rest }) => <ButtonStyle {...rest}>{children}</ButtonStyle>;
const ClearButton = styled(Button)`
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
height: 34px;
width: 32px;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
`;
const FilterComponent = ({ filterText, onFilter, onClear }) => (
<>
<TextField
id="search"
type="text"
placeholder="Filter By Name"
aria-label="Search Input"
value={filterText}
onChange={onFilter}
/>
<ClearButton type="button" onClick={onClear}>
X
</ClearButton>
</>
);
I have a styled.button that works perfectly on desktop view, but when on my desktop I toggle to mobile view it doesn't work at all.
Button:
const DateElement = styled.button`
background-color: ${(props) => (props.primary ? '#DEE2FF' : '#696B86')};
color: ${(props) => (props.primary ? 'black' : '#dedee4')};
box-shadow: none;
padding: 9px;
width: 90px;
text-align: center;
height: 90px;
user-select: none;
border: 1px solid rgba(20, 79, 118, 0.2);
& :hover {
cursor: pointer;
}
& :focus {
display: none;
}
${(theme) => theme.theme.breakpoints.down('sm')} {
padding: 3px;
width: 70px;
text-align: center;
height: 70px;
}
`;
render:
return (
<DateElement
key={date.getTime()}
primary={isSelected}
onClick={() => handleClick(date)}
className={clsx({
[classes.crossed]: date.getTime() + endTimeMilli < today.getTime(),
[classes.containerWidth]: dates.length > 4,
})}
>
<Typography className={classes.date}>{getWeekDay(date)}</Typography>
<Typography className={classes.month}>{getMonth(date)}</Typography>
<Typography className={classes.day}>{date.getDate()}</Typography>
</DateElement>
);
What is the issue?
How can I fix this?
I end up fixing it changing the styled component from button to div, I just changed it and it work, I still don't understand why or how but it worked.
const DateElement = styled.div`
Is it because you are using theme.theme?
${(theme) => theme.theme.breakpoints.down('sm')} {..
I could be wrong but not how it usually looks according to the docs: https://mui.com/customization/breakpoints/
I want line up items in item-list.
This is item-list block and css
const ItemListBlock = styled.div`
display: flex;
width: 90%;
flex-direction: row;
margin-top: 3rem;
flex-wrap: wrap;
`;
<ItemListBlock>
<div>
{items.map(item => (
<Item className="item" item={item} key={item.id} />
))}
</div>
</ItemListBlock>
and This is item block and css (It's a little abbreviated.)
const PostItemBlock = styled.div`
display: flex;
width: 352px;
flex-direction: column;
padding-top: 0;
padding-bottom: 3rem;
p {
margin-top: 2rem;
}
h3 {
width: 352px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.subdesc {
align-self: flex-end;
}
`;
const Item = ({ item }) => {
return (
<ItemBlock>
<h3>
title.
</h3>
<p1 className="subdesc">subdesc.</p1>
</ItemBlock>
);
};
I want display item list like this :
But It actually display like this :
I wrote flex-direction:row. But It still line up vertically. How can I line up items horizontally??
PostItemBlock should be inline currently it is block: Change it to display: inline-flex