I'm trying to create a 3 Column Card Grid with Bulma in Nextjs. The data comes from JSON Endpoint.
I successfully fetched the data and it's fetching perfectly.
But, I can't find what I'm doing wrong in this case.
Is there anyway I can limit the column. In Bootstrap I did Col sm={4} to limit to 3 column. Not sure how to do that in Bulma
It's appearing like this.
I got the code for SplitEvery from this SO Question (Add new columns container every 3 column elements in React.js with Bulma.css)
This is exactly what I want. I just want 3 column (3 Cards in a row) like below
Here is the code of my index.js
import Head from "next/head";
import Image from "next/image";
import styles from "../styles/Home.module.css";
export const getStaticProps = async () => {
const res = await fetch("http://localhost:3000/lorem.json");
const data = await res.json();
console.log(data);
return {
props: { number: data },
};
};
//Below Part is referred from
//https://stackoverflow.com/questions/54187450/add-new-columns-container-every-3-column-elements-in-react-js-with-bulma-css
const splitEvery = (array, length) =>
array.reduce((result, item, index) => {
if (index % length === 0) result.push([]);
result[Math.floor(index / length)].push(item);
return result;
}, []);
const Home = ({ numbers }) => {
return (
<div>
{splitEvery(numbers, 3).map((number) => (
<div className="columns">
{numbers.map((number) => (
<div className="column" key={number.id}>
<div className="card">
<div className="card-content">
<p className="title is-4">๐ {number.name}</p>
</div>
</div>
</div>
))}
</div>
))}
</div>
);
};
export default Home;
Your problem arises because Bulma is based on Flexbox. With the code above, you are essentially calling your function (with what I'm assumming according to the picture posted) that acts on an array of numbers 1-7. By default, Flexbox items will all try to fit onto one line. Therefore it's spitting out a card for every number on one line.
From the documentation, (More Info Here) "Whenever you want to start a new line, you can close a columns container and start a new one. But you can also add the is-multiline modifier and add more column elements than would fit in a single row."
Therefore, all you have to do is add is-multiline to the div that contains className="columns" and also add is-one-third to the div that contains className="column" to define how much space each card takes up. This is one of the drawbacks with a framework like Bulma; you can be limited to certain things you want to do.
All in all it should look like something like:
const Home = ({ numbers }) => {
return (
<div>
{splitEvery(numbers, 3).map((number) => (
<div className="columns is-multiline">
{numbers.map((number) => (
<div className="column is-one-third" key={number.id}>
<div className="card">
<div className="card-content">
<p className="title is-4">๐ {number.name}</p>
</div>
</div>
</div>
))}
</div>
))}
</div>
);
};
Note: I recreated this on local machine and it worked fine.
You can rely on CSS to divide your columns. Like Bootstrap, Bulma also uses 12 column layouts - see column sizes and responsive columns.
You also need to add the is-multiline class name to get the items to wrap and remove the SplitEverything code - it's no longer needed.
const Home = ({ numbers }) => (
<div className="columns">
{numbers.map((number) => (
<div className="column is-multiline is-12-mobile is-6-tablet is-4-desktop" key={number.id}>
<div className="card">
<div className="card-content">
<p className="title is-4">๐ {number.name}</p>
</div>
</div>
</div>
))}
</div>
);