I have an app in React Native and I can only see half of my app on the android phone, the components show up on the web version.
There have been many suggestions made on Stack Overflow which do not work for me, not limited to:
flex grow 1
flex 1
onStartShouldSetResponder={() => true}
import { ScrollView } from 'react-native-gesture-handler';
Wrapping ScrollView in a View component
nestedScrollEnabled={true}
Is there a way to force scroll or android or is it just impossible?
Here is the code:
import { StyleSheet, Text, View, TextInput, Pressable, ScrollView } from 'react-native';
import {useState, useEffect} from 'react'
import axios from 'axios'
import SelectDropdown from 'react-native-select-dropdown'
import { Formik } from 'formik'
export default function App() {
const [price, setPrice] = useState();
const options = ["ARS", "ARD", "BRL", "CAD", "CHF", "CLP", "CNY", "CZK", "DKK", "EUR", "GBP", "HKD", "HRK", "HUF", "INR", "ISK", "JPK", "KRW", "NZD", "PLN", "RON", "RUB", "SEK", "SGD", "THB", "TRY", "TWD", "USD"]
const [selected, setSelected] = useState(options[0])
const [amount, setAmount] = useState('')
const [calculatedAmount, setCalculatedAmount] = useState()
useEffect(() => {
axios.get('https://blockchain.info/ticker')
.then(data => {
setPrice(data)
})
}, [])
const fetchData = () => {
axios.get(`https://blockhain.info/tobtc?currency=${selected}&value=${amount}`)
.then(data => {
setCalculatedAmount(data.data)
console.log(calculatedAmount)
})
}
const handleSubmit = (e) => {
e.preventDefault()
fetchData()
}
const handleAmountChange = (e) => {
e.preventDefault()
setAmount(e.target.value)
}
if (!price || price === undefined ) {
return null
}
const Form = ({ onSubmit }) => {
<View>
<Text className="py-10 text-xl">Enter value: <TextInput className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" id="amount" placeholder="Enter value in selected currency" value={amount} onChange={handleAmountChange} data-cy="amount"></TextInput></Text>
<Text className="text-center"><Pressable className="p-5 mb-2 mr-2 overflow-hidden text-2xl text-gray-900 rounded-lg group bg-gradient-to-br from-purple-600 to-blue-500 group-hover:from-purple-600 group-hover:to-blue-500 hover:text-white text-black font-bold focus:ring-4 focus:outline-none focus:ring-blue-300 dark:focus:ring-blue-800" id="convert-button" type="submit"><Text>Calculate!</Text></Pressable></Text>
<Text id="#calculatedamount" className="text-xl py-8 bg-gray-100 px-2 font-bold rounded-md" data-cy="submit">Value: {calculatedAmount} BTC</Text>
</View>
}
return (
<ScrollView className="h-screen bg-blue-100" nestedScrollEnabled={true}>
<View className="py-10">
<Text className="text-xl text-center m-auto text-black font-bold">Current Prices</Text>
</View>
<View className="md:flex justify-around h-full">
<View className="text-center text-2xl m-auto bg-gray-100 p-20 rounded-md shadow-2xl max-w-[75%]">
<Text className="text-md font-bold">(£) {price.data.GBP.symbol} {price.data.GBP.last} BTC</Text>
</View>
<View className="text-center text-2xl m-auto bg-gray-100 p-20 rounded-md shadow-2xl max-w-[75%]">
<Text className="text-md font-bold">(€) {price.data.EUR.symbol} {price.data.EUR.last} BTC</Text>
</View>
<View className="text-center text-2xl m-auto bg-gray-100 p-20 rounded-md shadow-2xl max-w-[75%]">
<Text className="text-md font-bold">($) {price.data.USD.symbol} {price.data.USD.last} BTC</Text>
</View>
</View>
<View className="h-screen flex ">
<View className="m-auto bg-blue-300 p-20 rounded-md shadow-2xl">
<Text className="text-3xl font-bold py-10">Convert Currency into BTC</Text>
<Text className="text-xl"> Select a currency: <SelectDropdown className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
id='currency'
value={selected}
data-cy="select"
onChange={(e) => setSelected(e.target.value)}>
{options.map((value) => (<Text>
<Text value={value} key={value}>
<Text> {value}</Text>
</Text>
</Text>))}
</SelectDropdown></Text>
<Formik initialValues={{ amount: '' }} onSubmit={handleSubmit}>
{({ handleSubmit }) => <Form onSubmit={handleSubmit} />}
</Formik>
</View>
</View>
</ScrollView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Related
I wanted to try out Strapis guide to create a Trello Clone
https://strapi.io/blog/build-a-trello-clone-application-with-react-and-strapi-1
But right now I'm having a bit of an issue moving my cards...
The cards do show up when moving them but for some reason it doesn't seem to be switching the "state".
this is what my Board.js looks like:
import { ReactSortable } from "react-sortablejs";
import { useState, useEffect } from "react";
import axios from "axios";
const Board = () => {
const [tasks, settasks] = useState([]);
const [drafts, setdrafts] = useState([]);
const [progresstasks, setprogresstasks] = useState([]);
const [approvals, setapprovals] = useState([]);
const [finished, setfinished] = useState([]);
const [onholds, setonholds] = useState([]);
const [newTask, setnewTask] = useState("");
const addTask = async () => {
if(newTask !== ""){
let res = await axios
.post("http://localhost:1337/api/tasks", {
data :{
state: "draft",
Description: newTask,
}
})
.catch((err) => alert("Error occured"));
}
await getTasks();
setnewTask("");
};
const getTasks = async () => {
let Tasks = await axios.get("http://localhost:1337/api/tasks?populate=*");
// return;
settasks(Tasks.data.data);
// For Drafts
let Drafts = tasks.filter((res) => {
return res.attributes.state=== "draft";
});
setdrafts(Drafts);
// For Progress
let Progress = tasks.filter((res) => {
return res.attributes.state === "progress";
});
setprogresstasks(Progress);
// For Finished
let Finished = tasks.filter((res) => {
return res.attributes.state === "finished";
});
setfinished(Finished);
// For Approval
let Approval = tasks.filter((res) => {
return res.attributes.state === "approval";
});
setapprovals(Approval);
// For Onhold
let Onhold = tasks.filter((res) => {
return res.attributes.state=== "onhold";
});
setonholds(Onhold);
};
const getCustomers = async () => {
let Customers = await axios.get("http://localhost:1337/api/customers?populate=*");
}
useEffect(() => {
getTasks();
getCustomers();
});
return (
<>
<div className="container mt-5 mb-5">
<div
className="row"
style={{
height: "80vh",
}}
>
<div className="col mx-2 px-2 py-3 bg-light border rounded">
<h6>Entwurf</h6>
<div
style={{
minHeight: "500px",
}}
>
<ReactSortable
list={tasks}
setList={setdrafts}
groupp={"group-1"}
group={{ name: "group-1", put: true }}
>
{tasks.filter((task) => task.attributes.state === "draft")
.map((filteredTask) => (
<div
className="card p-3 border rounded mt-2"
key={filteredTask.id}
>
{filteredTask.attributes.Description}
</div>
))}
</ReactSortable>
</div>
<div>
<textarea
rows={"1"}
cols={30}
style={{ float: "left", borderBlockColor: "#007bff" }}
value={newTask}
onChange={(event) => setnewTask(event.target.value)}
></textarea>
<button
type="button"
style={{ float: "right", marginTop: "2px" }}
class="btn btn-primary btn-sm"
onClick={addTask}
>
Add Task
</button>
</div>
</div>
<div className="col mx-2 px-2 py-3 bg-light border rounded">
<h6>In Bearbeitung</h6>
<div
style={{
minHeight: "500px",
}}
>
<ReactSortable
list={tasks}
setList={setprogresstasks}
grouppp={"group-1"}
// group={{ name: "group-1", put: true }}
>
{tasks.filter((task) => task.attributes.state === "progress")
.map((filteredTask) => (
<div
className="card p-3 border rounded mt-2"
key={filteredTask.id}
>
{filteredTask.attributes.Description}
</div>
))}
</ReactSortable>
</div>
</div>
<div className="col mx-2 px-2 py-3 bg-light border rounded">
<h6>Fertig</h6>
<div
style={{
minHeight: "500px",
}}
>
<ReactSortable
list={tasks}
setList={setfinished}
groupppp={"group-1"}
// group={{ name: "group-1", put: true }}
>
{tasks.filter((task) => task.attributes.state === "finished")
.map((filteredTask) => (
<div
className="card p-3 border rounded mt-2"
key={filteredTask.id}
>
{filteredTask.attributes.Description}
</div>
))}
</ReactSortable>
</div>
</div>
<div className="col mx-2 px-2 py-3 bg-light border rounded">
<h6>On-Hold</h6>
<div
style={{
minHeight: "500px",
}}
>
<ReactSortable
list={tasks}
setList={setonholds}
grouppppp={"group-1"}
// group={{ name: "group-1", put: true }}
>
{tasks.filter((task) => task.attributes.state === "onhold")
.map((filteredTask) => (
<div
className="card p-3 border rounded mt-2"
key={filteredTask.id}
>
{filteredTask.attributes.Description}
</div>
))}
</ReactSortable>
</div>
</div>
<div className="col mx-2 px-2 py-3 bg-light border rounded">
<h6>Wartet auf Freigabe</h6>
<div
style={{
minHeight: "500px",
}}
>
<ReactSortable
list={tasks}
setList={setapprovals}
groupppppp={"group-1"}
// group={{ name: "group-1", put: true }}
>
{tasks.filter((task) => task.attributes.state === "approval")
.map((filteredTask) => (
<div
className="card p-3 border rounded mt-2"
key={filteredTask.id}
>
{filteredTask.attributes.Description}
</div>
))}
</ReactSortable>
</div>
</div>
</div>
</div>
</>
);
};
export default Board;
Is there something I'm missing like executing a function when moving the cards?
Stack: NextJS, JavaScript, React, Tailwind, Framer Motion
I've scoured the web for answers to this but mostly the answers were saying that the <div> that wraps the image must have a position of relative. I tried this and it didn't change anything.
Code for the text and images:
import React from "react";
import { motion } from "framer-motion";
import Image from "next/image";
export default function Card({ image, name, description }) {
return (
<motion.div
className="flex justify-center mt-5"
initial="hidden"
animate="visible"
variants={{
hidden: { scale: 0.9, opacity: 0 },
visible: {
scale: 1,
opacity: 1,
transition: { delay: 0.3, ease: [0.17, 0.67, 0.83, 0.67] },
},
}}
>
<div className="relative">
<Image
className="rounded-full absolute"
src={image}
width={100}
height={100}
alt="Leader profile picture"
/>
</div>
<div>
<motion.h1
className="text-xl pl-1 font-bourton"
initial="hidden"
animate="visible"
variants={{
hidden: { scale: 0.9, opacity: 0 },
visible: {
scale: 1,
opacity: 1,
transition: { delay: 0.35, ease: [0.17, 0.67, 0.83, 0.67] },
},
}}
>
{name}
</motion.h1>
<motion.p className="text-sm p-3 text-wrap w-48 text-slate-600 font-bourton">
{description}
</motion.p>
</div>
</motion.div>
);
}
The code for the sidebar:
import { useState } from "react";
import { motion } from "framer-motion";
import classnames from "classnames";
import { useRouter } from "next/router";
const path01Variants = {
open: { d: "M3.06061 2.99999L21.0606 21" },
closed: { d: "M0 9.5L24 9.5" },
};
const path02Variants = {
open: { d: "M3.00006 21.0607L21 3.06064" },
moving: { d: "M0 14.5L24 14.5" },
closed: { d: "M0 14.5L15 14.5" },
};
const Sidebar = () => {
const [showSidebar, setShowSidebar] = useState(false);
const [animation, setAnimation] = useState("closed");
const router = useRouter();
const onClick = () => {
setAnimation("moving");
setTimeout(() => {
setAnimation(animation === "closed" ? "open" : "closed");
}, 200);
setShowSidebar(!showSidebar);
};
return (
<>
{showSidebar ? (
<button
className="flex justify-center relative z-100 items-center w-12 h-12 border border-black rounded-full"
onClick={onClick}
>
<svg width="24" height="24" viewBox="0 0 24 24">
<motion.path
stroke="#fff"
animate={animation}
variants={path01Variants}
/>
<motion.path
stroke="#fff"
animate={animation}
variants={path02Variants}
/>
</svg>
</button>
) : (
<button
className="flex justify-center top-12 right-12 items-center w-12 h-12 border border-black rounded-full"
onClick={onClick}
>
<svg width="24" height="24" viewBox="0 0 24 24">
<motion.path
stroke="#000"
animate={animation}
variants={path01Variants}
/>
<motion.path
stroke="#000"
animate={animation}
variants={path02Variants}
/>
</svg>
</button>
)}
<div
className={` bg-unionred border-black opacity-90 top-0 right-0 lg:w-[35vw] sm:w-[50vw] p-10 pl-20 fixed text-white h-full ease-in-out duration-300 ${
showSidebar ? "translate-x-0" : "translate-x-full"
}`}
>
<button
className="flex justify-center absolute top-8 right-8 items-center w-12 h-12 border border-white rounded-full"
onClick={onClick}
>
<svg width="24" height="24" viewBox="0 0 24 24">
<motion.path
stroke="#fff"
animate={animation}
variants={path01Variants}
/>
<motion.path
stroke="#fff"
animate={animation}
variants={path02Variants}
/>
</svg>
</button>
<h3 className="mt-20 text-4xl underline font-bourton text-white">
<button className="underline" onClick={() => router.push("whoweare")}>
Who We Are
</button>
</h3>
<h3 className="mt-20 text-4xl font-bourton text-white">
<button
className="underline"
onClick={() => router.push("ourleaders")}
>
Our Leaders
</button>
</h3>
<h3 className="mt-20 text-4xl font-bourton text-white">
<button className="underline">News</button>
</h3>
</div>
</>
);
};
export default Sidebar;
Before opening sidebar
After opening sidebar
Any help would be appreciated! Thank you.
It looks like you're not applying a z-index to the sidebar itself. That <div> is the container that needs to overlap the main content, so that is where you need to add the utility class.
Additionally, it looks like you're trying to use z-100 which is not one of the Tailwind defaults (see: https://tailwindcss.com/docs/z-index). You can either add that new value to your tailwind.config.js or try z-50, which is the highest default.
For example:
<div className={`z-50 bg-unionred border-black opacity-90 top-0 right-0 lg:w-[35vw] sm:w-[50vw] p-10 pl-20 fixed text-white h-full ease-in-out duration-300 ${showSidebar ? "translate-x-0" : "translate-x-full"}`}>
So My page looks like below
I have written a logic to open a modal using headlessui on clicking one of the sub hoodie images.
This works perfectly , but after I close it, the scrolling of the page disables and an extra
style="overflow: hidden; padding-right: 16px;"
is getting added to my main html tag.
Below is the reference
How do i stop the modal to automatically apply padding and overflow.
A lot of people have had this problem with bootstrap but i am not able to find this issue resolved in tailwind. Please help
below is the code for my modal
import React from 'react'
import { Dialog, Transition } from '#headlessui/react'
import { Fragment } from 'react'
import {XIcon} from '#heroicons/react/solid'
import {useRecoilState} from 'recoil'
import {openState} from '../../../atoms/modalAtom'
const product = {
name: "Women's Basic Tee",
price: '$32',
rating: 3.9,
reviewCount: 512,
href: '#',
imageSrc: 'https://tailwindui.com/img/ecommerce-images/product-page-01-featured-product-shot.jpg',
imageAlt: "Back of women's Basic Tee in black.",
colors: [
{ name: 'Black', bgColor: 'bg-gray-900', selectedColor: 'ring-gray-900' },
{ name: 'Heather Grey', bgColor: 'bg-gray-400', selectedColor: 'ring-gray-400' },
],
sizes: [
{ name: 'XXS', inStock: true },
{ name: 'XS', inStock: true },
{ name: 'S', inStock: true },
{ name: 'M', inStock: true },
{ name: 'L', inStock: true },
{ name: 'XL', inStock: true },
{ name: 'XXL', inStock: false },
],
}
export function DesignQuickView ({design}) {
const [open, setOpen] = useRecoilState(openState)
return (
<Transition.Root show={open} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={() => setOpen(false)}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="hidden fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity md:block" />
</Transition.Child>
<div className="fixed z-10 inset-0 overflow-y-auto">
<div className="flex items-stretch md:items-center justify-center min-h-full text-center md:px-2 lg:px-4">
{/* This element is to trick the browser into centering the modal contents. */}
<span className="hidden md:inline-block md:align-middle md:h-screen" aria-hidden="true">
</span>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 translate-y-4 md:translate-y-0 md:scale-95"
enterTo="opacity-100 translate-y-0 md:scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 translate-y-0 md:scale-100"
leaveTo="opacity-0 translate-y-4 md:translate-y-0 md:scale-95"
>
<Dialog.Panel className="flex text-base text-left transform transition w-full md:max-w-2xl md:px-4 md:my-8 lg:max-w-4xl">
<div className="w-full relative flex items-center bg-white px-4 pt-14 pb-8 overflow-hidden shadow-2xl sm:px-6 sm:pt-8 md:p-6 lg:p-8">
<button
type="button"
className="absolute top-4 right-4 text-gray-400 hover:text-gray-500 sm:top-8 sm:right-6 md:top-6 md:right-6 lg:top-8 lg:right-8"
onClick={() => setOpen(false)}
>
<span className="sr-only">Close</span>
<XIcon className="h-6 w-6" aria-hidden="true" />
</button>
<div className="w-full grid grid-cols-1 gap-y-8 gap-x-6 items-start sm:grid-cols-12 lg:items-center lg:gap-x-8">
<div className="aspect-w-3 aspect-h-4 rounded-lg bg-gray-100 overflow-hidden sm:col-span-4 lg:col-span-5">
<img src={design.url} alt={design.name} className="object-center object-cover" />
</div>
<div className="sm:col-span-8 lg:col-span-7">
<h2 className="text-xl font-medium text-gray-900 sm:pr-12">Hoodie</h2>
<section aria-labelledby="information-heading" className="mt-1">
<h3 id="information-heading" className="sr-only">
Product information
</h3>
<p className="font-medium text-gray-900">{product.price}</p>
</section>
<section aria-labelledby="options-heading" className="mt-8">
<h3 id="options-heading" className="sr-only">
Product options
</h3>
<form>
{/* Color picker */}
<div>
<h4 className="text-sm font-medium text-gray-900">Color</h4>
{/* <RadioGroup value={selectedColor} onChange={setSelectedColor} className="mt-2">
<RadioGroup.Label className="sr-only">Choose a color</RadioGroup.Label>
<div className="flex items-center space-x-3">
{product.colors.map((color) => (
<RadioGroup.Option
key={color.name}
value={color}
className={({ active, checked }) =>
classNames(
color.selectedColor,
active && checked ? 'ring ring-offset-1' : '',
!active && checked ? 'ring-2' : '',
'-m-0.5 relative p-0.5 rounded-full flex items-center justify-center cursor-pointer focus:outline-none'
)
}
>
<RadioGroup.Label as="span" className="sr-only">
{color.name}
</RadioGroup.Label>
<span
aria-hidden="true"
className={classNames(
color.bgColor,
'h-8 w-8 border border-black border-opacity-10 rounded-full'
)}
/>
</RadioGroup.Option>
))}
</div>
</RadioGroup> */}
</div>
{/* Size picker */}
<div className="mt-8">
<div className="flex items-center justify-between">
<h4 className="text-sm font-medium text-gray-900">Size</h4>
<a href="#" className="text-sm font-medium text-indigo-600 hover:text-indigo-500">
Size guide
</a>
</div>
{/* <RadioGroup value={selectedSize} onChange={setSelectedSize} className="mt-2">
<RadioGroup.Label className="sr-only">Choose a size</RadioGroup.Label>
<div className="grid grid-cols-7 gap-2">
{product.sizes.map((size) => (
<RadioGroup.Option
key={size.name}
value={size}
className={({ active, checked }) =>
classNames(
size.inStock
? 'cursor-pointer focus:outline-none'
: 'opacity-25 cursor-not-allowed',
active ? 'ring-2 ring-offset-2 ring-indigo-500' : '',
checked
? 'bg-indigo-600 border-transparent text-white hover:bg-indigo-700'
: 'bg-white border-gray-200 text-gray-900 hover:bg-gray-50',
'border rounded-md py-3 px-3 flex items-center justify-center text-sm font-medium uppercase sm:flex-1'
)
}
disabled={!size.inStock}
>
<RadioGroup.Label as="span">{size.name}</RadioGroup.Label>
</RadioGroup.Option>
))}
</div>
</RadioGroup> */}
</div>
</form>
</section>
</div>
</div>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition.Root>
)
}
export default DesignQuickView
In the closeModal function, you can override the style of the html tag:
function closeModal() {
setOpen(false);
setTimeout(() => {
const html = document.body.parentNode as HTMLElement | null;
html.classList.add('modal_close');
}, 50);
}
function openModal() {
setOpen(true);
const html = document.body.parentNode as HTMLElement | null;
html.classList.remove('modal_close');
}
<Dialog as="div" className="relative z-10" onClose={closeModal}><
<button
type="button"
className="absolute top-4 right-4 text-gray-400 hover:text-gray-500 sm:top-8 sm:right-6 md:top-6 md:right-6 lg:top-8 lg:right-8"
onClick={closeModal}
>
style.css
.modal_close {
overflow: auto !important;
padding-right: 0px !important;
}
just having issues with populating the JSON into my chart. I'm seeing the response in the console log with API status with no errors, but for some reason, it's not populating it. Using Axios to fetch the example API to populate the emp sal and age. I have a feeling that I need to move the "UseEffect" somewhere but not sure where that needs to go.
import React, { useState, useEffect } from "react";
import { Link } from 'react-router-dom';
import LineChart from '../../charts/LineChart01';
import Icon from '../../images/icon-01.svg';
import EditMenu from '../EditMenu';
import axios from "axios";
// Import utilities
import { tailwindConfig, hexToRGB } from '../../utils/Utils';
const DashboardCard01 = () => {
const [chartData, setChartData] = useState({});
const [employeeSalary, setEmployeeSalary] = useState([]);
const [employeeAge, setEmployeeAge] = useState([]);
const chart = () => {
let empSal = [];
let empAge = [];
axios
.get("http://dummy.restapiexample.com/api/v1/employees")
.then(res => {
console.log(res);
for (const dataObj of res.data.data) {
empSal.push(parseInt(dataObj.employee_salary));
empAge.push(parseInt(dataObj.employee_age));
}
setChartData({
labels: empAge,
datasets: [
{
label: empAge,
data: empSal,
//backgroundColor: ["rgba(75, 192, 192, 0.6)"],
borderWidth: 4
}
]
});
})
.catch(err => {
console.log(err);
});
console.log(empSal, empAge);
datasets: [
// Indigo line
{
data: empAge,
fill: true,
backgroundColor: `rgba(${hexToRGB(tailwindConfig().theme.colors.blue[500])}, 0.08)`,
borderColor: tailwindConfig().theme.colors.indigo[500],
borderWidth: 2,
tension: 0,
pointRadius: 0,
pointHoverRadius: 3,
pointBackgroundColor: tailwindConfig().theme.colors.indigo[500],
clip: 20,
},
// Gray line
{
data: empSal,
borderColor: tailwindConfig().theme.colors.slate[300],
borderWidth: 2,
tension: 0,
pointRadius: 0,
pointHoverRadius: 3,
pointBackgroundColor: tailwindConfig().theme.colors.slate[300],
clip: 20,
},
]
};
useEffect(() => {
chart();
}, []);
return (
<div className="flex flex-col col-span-full sm:col-span-6 xl:col-span-4 bg-white shadow-lg rounded-sm border border-slate-200">
<div className="px-5 pt-5">
<header className="flex justify-between items-start mb-2">
{/* Icon */}
<img src={Icon} width="32" height="32" alt="Icon 01" />
{/* Menu button */}
<EditMenu className="relative inline-flex">
<li>
<Link className="font-medium text-sm text-slate-600 hover:text-slate-800 flex py-1 px-3" to="#0">Option 1</Link>
</li>
<li>
<Link className="font-medium text-sm text-slate-600 hover:text-slate-800 flex py-1 px-3" to="#0">Option 2</Link>
</li>
<li>
<Link className="font-medium text-sm text-rose-500 hover:text-rose-600 flex py-1 px-3" to="#0">Remove</Link>
</li>
</EditMenu>
</header>
<h2 className="text-lg font-semibold text-slate-800 mb-2">Acme Plus</h2>
<div className="text-xs font-semibold text-slate-400 uppercase mb-1">Sales</div>
<div className="flex items-start">
<div className="text-3xl font-bold text-slate-800 mr-2">$24,780</div>
<div className="text-sm font-semibold text-white px-1.5 bg-green-500 rounded-full">+49%</div>
</div>
</div>
{/* Chart built with Chart.js 3 */}
<div className="grow">
{/* Change the height attribute to adjust the chart height */}
<LineChart data={chartData} width={389} height={128} />
</div>
</div>
);
}
export default DashboardCard01;
So im currently trying to figure out how I can change the state of a button depending on wether I'm on the page or not.
I have this navbar:
import { Fragment } from 'react'
import { Disclosure, Menu, Transition } from '#headlessui/react'
import { BellIcon, MenuIcon, XIcon } from '#heroicons/react/outline'
import { PlusSmIcon } from '#heroicons/react/solid'
const user = {
name: 'Tom Cook',
email: 'tom#example.com',
imageUrl:
'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
}
const navigation = [
{ name: 'Home', href: '/', current: true },
{ name: 'Dashboard', href: '/dashboard', current: false },
{ name: 'Price', href: '/price', current: false },
]
const userNavigation = [
{ name: 'Your Profile', href: '/profile' },
{ name: 'Settings', href: '#' },
{ name: 'Sign out', href: '#' },
]
function classNames(...classes) {
return classes.filter(Boolean).join(' ')
}
export default function Navbar() {
return (
<Disclosure as="nav" className="bg-gray-800">
{({ open }) => (
<>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between h-16">
<div className="flex">
<div className="-ml-2 mr-2 flex items-center md:hidden">
{/* Mobile menu button */}
<Disclosure.Button className="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white">
<span className="sr-only">Open main menu</span>
{open ? (
<XIcon className="block h-6 w-6" aria-hidden="true" />
) : (
<MenuIcon className="block h-6 w-6" aria-hidden="true" />
)}
</Disclosure.Button>
</div>
<div className="flex-shrink-0 flex items-center">
<img
className="block lg:hidden h-8 w-auto"
src="Assets/img/logo-light.png"
alt="Nemondo"
/>
<img
className="hidden lg:block h-8 w-auto"
src="Assets/img/logo-light.png"
alt="Nemondo"
/>
</div>
<div className="hidden md:ml-6 md:flex md:items-center md:space-x-4">
{navigation.map((item) => (
<a
key={item.name}
href={item.href}
className={classNames(
item.current ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white',
'px-3 py-2 rounded-md text-sm font-medium'
)}
aria-current={item.current ? 'page' : undefined}
>
{item.name}
</a>
))}
</div>
</div>
<div className="flex items-center">
<div className="flex-shrink-0">
<button
type="button"
className="relative inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-500 hover:bg-indigo-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-indigo-500"
>
<PlusSmIcon className="-ml-1 mr-2 h-5 w-5" aria-hidden="true" />
<span>New Job</span>
</button>
</div>
<div className="hidden md:ml-4 md:flex-shrink-0 md:flex md:items-center">
<button
type="button"
className="bg-gray-800 p-1 rounded-full text-gray-400 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-white"
>
<span className="sr-only">View notifications</span>
<BellIcon className="h-6 w-6" aria-hidden="true" />
</button>
{/* Profile dropdown */}
<Menu as="div" className="ml-3 relative">
<div>
<Menu.Button className="bg-gray-800 flex text-sm rounded-full focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-white">
<span className="sr-only">Open user menu</span>
<img className="h-8 w-8 rounded-full" src={user.imageUrl} alt="" />
</Menu.Button>
</div>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items className="origin-top-right absolute right-0 mt-2 w-48 rounded-md shadow-lg py-1 bg-white ring-1 ring-black ring-opacity-5 focus:outline-none z-10">
{userNavigation.map((item) => (
<Menu.Item key={item.name}>
{({ active }) => (
<a
href={item.href}
className={classNames(
active ? 'bg-gray-100' : '',
'block px-4 py-2 text-sm text-gray-700'
)}
>
{item.name}
</a>
)}
</Menu.Item>
))}
</Menu.Items>
</Transition>
</Menu>
</div>
</div>
</div>
</div>
<Disclosure.Panel className="md:hidden">
<div className="px-2 pt-2 pb-3 space-y-1 sm:px-3">
{navigation.map((item) => (
<Disclosure.Button
key={item.name}
as="a"
href={item.href}
className={classNames(
item.current ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white',
'block px-3 py-2 rounded-md text-base font-medium'
)}
aria-current={item.current ? 'page' : undefined}
>
{item.name}
</Disclosure.Button>
))}
</div>
<div className="pt-4 pb-3 border-t border-gray-700">
<div className="flex items-center px-5 sm:px-6">
<div className="flex-shrink-0">
<img className="h-10 w-10 rounded-full" src={user.imageUrl} alt="" />
</div>
<div className="ml-3">
<div className="text-base font-medium text-white">{user.name}</div>
<div className="text-sm font-medium text-gray-400">{user.email}</div>
</div>
<button
type="button"
className="ml-auto flex-shrink-0 bg-gray-800 p-1 rounded-full text-gray-400 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-white"
>
<span className="sr-only">View notifications</span>
<BellIcon className="h-6 w-6" aria-hidden="true" />
</button>
</div>
<div className="mt-3 px-2 space-y-1 sm:px-3">
{userNavigation.map((item) => (
<Disclosure.Button
key={item.name}
as="a"
href={item.href}
className="block px-3 py-2 rounded-md text-base font-medium text-gray-400 hover:text-white hover:bg-gray-700"
>
{item.name}
</Disclosure.Button>
))}
</div>
</div>
</Disclosure.Panel>
</>
)}
</Disclosure>
)
}
It seems that when I change the current:
const navigation = [
{ name: 'Home', href: '/', current: true },
{ name: 'Dashboard', href: '/dashboard', current: false },
{ name: 'Price', href: '/price', current: false },
From true to false and vice versa it does exactly what I need, but how can I make it so it changes depending on whether I'm on the page or not?
Thanks in advance.
codesandbox: https://codesandbox.io/s/navbar-react-router-dom-v6-p8vy4b
It is not styled very good. The conditional check of current route look like this:
import { useLocation } from "react-router-dom";
const Navbar = () => {
const location = useLocation();
const navigation = [
{
name: "Root",
href: "/"
},
{
name: "Home",
href: "/home"
},
{
name: "About",
href: "/about"
}
];
return (
<navbar
style={{
display: "flex",
height: "50px",
backgroundColor: "red",
width: "100vw"
}}
>
{navigation.map((nav, idx) => {
const isActiveRoute = location.pathname === nav.href;
// const isActiveRoute = location.pathname.startsWith(nav.href) // or if you want a prefix instead
return (
<a
key={idx}
href={nav.href}
style={{ padding: "0 25px", color: isActiveRoute && "black" }}
>
<h3>{nav.name}</h3>
</a>
);
})}
</navbar>
);
};
export default Navbar;
and the routing :
import "./styles.css";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Navbar from "./Navbar";
export default function App() {
const wrapNavbar = (item) => {
return (
<>
<Navbar />
{item}
<p>note: black navbar color is the active item</p>
</>
);
};
return (
<BrowserRouter>
<Routes>
<Route path="/" element={wrapNavbar(<h1>this is root </h1>)} />
<Route path="/home" element={wrapNavbar(<h1>this is home </h1>)} />
<Route path="/about" element={wrapNavbar(<h1>this is about </h1>)} />
</Routes>
</BrowserRouter>
);
}