React-router pages with arrows - javascript

I want to change menu-pages (in react-router) with to icons ("back", "forward")...
export const ArrowNav = () => {
const menu = useContext(menuContext);
return <div className="lmpixels-arrows-nav">
<NavLink to={"/about"}>
<div className="lmpixels-arrow-right">
<i className="lnr lnr-chevron-right"/>
</div>
</NavLink>
<NavLink to="/resume">
<div className="lmpixels-arrow-left">
<i className="lnr lnr-chevron-left"/>
</div>
</NavLink>
</div>
}

Instead of using html css styles to show the icons you might like to try the package React Icons:
https://react-icons.github.io/
I, particularly, avoid using old CSS style names for icons like you are trying to do. In fact, I prefer to do all I can do to avoid the use of CSS files with React. Because React uses a lot js objects I believe it is better practice the use of some kind of CSS objects:
https://www.w3schools.com/react/react_css.asp
The error you are getting might depend on how are you importing the needed css information.
More info you might find useful:
https://medium.com/swlh/using-react-router-navlink-to-specify-the-active-element-in-a-navigation-bar-38700ffd4900
Hope this will help you

Related

What's the best way to pass markdown to an Astro component as a prop

What I'm trying to do
A simple way to render the content of a markdown file when it's passed as a string to another component using .compiledContent (or even using .rawContnent)? Or even a better way than this as obviously usually in Astro we can use the <Content /> Component, but from my knowledge, I can't pass a component or this functionality to another component without using a <slot /> in the parent component.
I have some JS for the parent component and using a <slot/> instead of passing the props to the component would change things, so hopefully looking for a solution with using this.
My setup
Data stored in /src/data/experience as markdown files with a year and a description formatted as markdown in the content section of each file
A component called Tabs.astro which takes props of headings and contents which are both lists of strings
A page /src/pages/experience.astro with the Tabs component in it which is displaying this data
I take the below code to get the data from the markdown files and pass the years and descriptions to the Tab component.
experience.astro
---
import Tabs from "../components/Tabs.astro";
const jobs = await Astro.glob("../data/experience/*.md");
const years = jobs.map((job) => job.frontmatter.year);
const descriptions = jobs.map((job) => job.compiledContent);
---
<!-- My component taking the data to be rendered -->
<Tabs headings={years} contents={descriptions} />
Tabs.astro
And the component renders the info like so
<!-- Tabs -->
<div class="tabs">
<ul class="tabs-header">
{
headings.map((heading) => (
<li>{heading}</li>
))
}
</ul>
<ul class="tabs-content">
{contents.map((content) => <li class="tab">{content}</li>)}
</ul>
</div>
My current solution
At the moment using .compiledContent gets me the correct HTML, however it is all in a string so the HTML doesn't actually render.
What I'm looking for
Is there a native way in Astro to pass markdown as a prop to a component?
If not is there a manual and recommended way in Astro to convert a markdown string and sanitise it to protect against XSS attacks? (if this is a risk in Astro when rendered statically?)
If not what are your most recommended ways to render markdown and sanitise it in JS?
Thanks so much for your time and help! I'm loving using Astro
p.s Also happy to concede and just use a <slot/> in my component if needed... ;)
Astro has a set:html directive you can use in combination with a Fragment like this
<Fragment set:html={post.compiledContent()}/>
After a bit of struggling with this myself, the current solution from the Astro docs for a single file without looping is the following.
Import your file with {Content as YourAliasName} from '../yourPath/yourFileName.md'
Then just use it as a tag <YourAliasName />
Example from the docs for reference:
---
import {Content as PromoBanner} from '../components/promoBanner.md';
---
<PromoBanner />
https://docs.astro.build/en/guides/markdown-content/#the-content-component

Tailwind.css — How to implement the last-child using Tailwind?

I have tried without success to implement the prefix last: as shown in the Tailwind.css documentation. Can anyone point out what I am doing wrong? I cannot make this work.
Thank you in advance.
React Component
{items.map((item, i) => {
return (
<li
key={i.toString()}
v-for="(item, i) in items"
className="pb-sm xl:pb-md last:pb-0" // This is the problematic fellow!
>
<div className="grid grid-cols-12">
<div className="col-start-2 col-span-10 md:col-start-2 md:col-span-8 pb-2 sm:pb-xs md:pb-xs lg:pb-xs xl:pb-0">
<div className="serif text-h5 xl:text-h4 lg:text-h4 md:text-h4 leading-snug xl:leading-tight lg:leading-tight md:leading-snug">
{item}
</div>
</div>
<div className="col-start-2 col-span-10 sm:col-start-5 sm:col-span-6 md:col-start-5 md:col-span-6 lg:col-start-5 lg:col-span-6 xl:col-start-5 xl:col-span-3 pb-xs sm:pb-xs">
<div className="text-p sm:text-p">{description[i]}</div>
</div>
</div>
</li>
)
})}
As of April 2022 (v 3.0.24)
According to Tailwind's doc:
Style an element when it is the first-child or last-child using the first and last modifiers
Just use last:${yourClassName} to target the last child in your case.
Source: https://tailwindcss.com/docs/hover-focus-and-other-states#last
Not sure if you're using Tailwind v2.X or v1.X but you need to activate the variant for last. Here is a quote from the official v2 docs related page
By default, the last-child variant is not enabled for any core plugins.
I've tried to make an example for you on https://play.tailwindcss.com/ but it doesn't work there. Meanwhile, I spin a Vite VueJS repo with the latest version of TW and it's working perfectly.
So, this in your tailwind.config.js should do the trick
module.exports = {
...
variants: {
extend: {
padding: ['last'],
}
},
...
}
v2's documentation is here and v1's is here.
Beware, the variants >> extend is only available in the v2. If you're using v1, you can still override the whole padding variant manually, not a big deal.
PS: Tailwind's team fixed the issue already, damn !

React: why my links that are inside React components are not working as used to work in pure HTML page?

Basically I'm trying to remake some simple web page that I have initially created with HTML and CSS to be working rather on React. I managed to redo the page to correctly display when it was moved into React, however I don't really understand why the navigation links that I have on top do not take me to the corresponding section on the same page anymore as well as why the external links to the project sites also stopped working.
Here is the project link code:
import React from "react";
export default function ProjectTile(props) {
return (
<div className="project-tile" id={props.id}>
<a href={props.href} target="_blank" id={props.link_id}>
<img
className="project_screenshot"
src={props.img_src}
alt={props.img_alt}
/>
<p className="project_name">
<span className="brackets"><</span> {props.title}{" "}
<span className="brackets">/></span>
</p>
</a>
</div>
);
}
All props are getting mapped and loaded from the array with corresponding data where each object looks like this:
{
id: "tribute_page",
link_id: "https://codepen.io/konstantinkrumin/full/PooYQbG",
img_src: "https://i.imgur.com/ynRuzOQ.png",
img_alt: "tribute_page_screenshot",
title: "Tribute Page"
}
The navigation links used are the following:
import React from "react";
export default function Navbar() {
return (
<nav id="navbar">
<a className="nav-link" href="#welcome-section">
About
</a>
<a className="nav-link" href="#projects">
Projects
</a>
<a className="nav-link" href="#contact">
Contact
</a>
</nav>
);
}
And each section they refer to have an id corresponding to the href indicated above.
Here if the link to this project on codesandbox
P.S. Everything used to work correctly when it was on HTML.
Also the contact links that seem to be set in similar way as project links are working.
Here are two things I think I found out:
In the ProjectTile.js file, replace href = {props.href} by href={props.link_id and now project opens in codepen.
About the jump link you have made in nav-bar, I think it's because of problem of codesandbox.
If you manage to make your url to https://op6gq.csb.app#projects instead of https://op6gq.csb.app/#projects. That's gonna work.
Or directly visiting https://op6gq.csb.app/#welcome-section jump link too works well.
It looks like there's no href prop. Sounds like what you want is something like
href={`#${props.id}`}
which would evaluate to href="#tribute_page" in this example.
You Have to try that your page url become:
https://op6gq.csb.app#welcome-section
Not:
https://op6gq.csb.app/#welcome-section
please attend to that / in address bar!

Font Awesome icons not showing up using Bulma in Gatsby

I am building a website using Gatsby and Bulma. In my Nav.js file, where I create a general format for the buttons at the top of the website, I have a few buttons using Bulma to which I would like to add icons inside. I went off the documentation for adding Bulma buttons with Font Awesome Icons: https://bulma.io/documentation/elements/button/. My code is exactly the same, other that the fact that I have my buttons wrapped in an <a> tag to link to other pages in my website. I have the included <script> file listed in documentation to have Font Awesome Icons available, and my code looks as such:
const Nav = () => {
return (
<div style={{ margin: `3rem auto`, maxWidth: 650, padding: `0 1rem` }}>
<nav>
<script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
<p class="buttons is-outlined is-centered">
<a href="/"><button class="button is-outlined"> <span class="icon">
<i class="fas fa-home"></i>
</span>
<span>Home</span>
</button></a>
<button class="button is-outlined">Projects</button>
<button class="button is-outlined">Experience</button>
</p>
</nav>
</div>
)
}
I'm not sure if I have the script located in the correct part of the file, and I've only tried to put an icon for my Home button which looks like this:
The gap to the left of the "Home" is where I'm guessing the icon should be. I would appreciate any help as to why the icon is not showing up or is showing up blank. Thank you!
I ran into this issue myself so posting here for anyone that is looking for the answer. There are a few ways to make it work, including using the icons as components with a library such as react-fontawesome. However if you're using Bulma then chances are that you specifically don't want to do that, instead you want to use the class names.
So first install the package:
npm i #fortawesome/fontawesome-free
Then in your index.js / app.js / any styling wrapper component you have:
import '#fortawesome/fontawesome-free/css/all.min.css'
Here is a Typescript example I have in front of me. This is a wrapper component that imports all my global styles for nested child components to use:
import React from 'react';
import 'bulma/css/bulma.css';
import '#fortawesome/fontawesome-free/css/all.min.css';
import NavMenu from '../nav-menu';
import Footer from '../footer';
import './layout.css';
const Layout: React.FC<{ light: boolean }> = ({ light, children }) => {
return (
<div className="layout-wrapper">
<NavMenu light={light} />
{children}
<Footer light={light} />
</div>
);
};
export default Layout;
With the help of a friend, what solved the issue was putting the <script> tag in the public/index.html file of the project, and then making an exact copy and naming it index.html and putting it in the static folder in the project. This way, each time a Gatsby server is ran, it will create a copy of the index.html file in the public repository with the Font Awesome Icon script included.

How to create a conditional rendering of Gatsby's Link component and <a> tag for links?

From Gatsby's official docs regarding Gatsby's Link component, it states that the Link component is used only for internal links, whereas for external links, one has to use the tag.
I'm building a Button component that has inbuilt props for links. The problem is right now I have to create 2 separate Button components for internal and external links due to the limitation.
My goal is to use one freeLink component that can be used as both internal and external links
I've tried creating a subcomponent (Button) for the button, but I'm unsure of the parent component (freeLink) which requires conditional rendering. The subcomponent is as of follows:
const Button = props => (
<button className={props.btnType}>
<span>{props.text}</span>
</button>
)
This is the visual logic to what I want to achieve:
For Internal links
<freeLink intLink="/about" btnType="btn-cta" text="Read about us">
</freeLink>
...which will render...
<Link to="/about">
<button className="btn-cta">
<span>Read about us</span>
</button>
</Link>
It is relatively similar for external links
<freeLink extLink="https://google.com" btnType="btn-cta" text="Visit Our Partner">
</freeLink>
...which will render...
<a href="https://google.com">
<button className="btn-cta">
<span>Visit Our Partner</span>
</button>
</a>
I'm quite new to Javascript, Gatsby and React so I'm unsure to how to apply a conditional rendering based on props applied.
Any advice, suggestion, or direction to how to code up the freeLink component is greatly appreciated.
P.S: I've seen Conditionally Use Gatsby Link in React Compoment but the chosen answer is too complicated for me to understand, and I don't have enough points to comment to ask for further elaboration.
You could try something simple like this:
const MyLink = (href, text, ...props) => {
if (href.startsWith("http") {
return <a href={href} {...props}>{text}</a>
} else {
return <Link href={href} {...props}>{text}</Link>
}
}
Your component could return different stuff based on weather you pass it a to or a href prop:
import { Link } from "gatsby"
const freeLink = props => {
if (props.to) return <Link {...props} />
return <a {...props} />
}`

Categories

Resources