How to mobile collapse navbar from Materialize CSS in Svelte? - mobile

I am trying to use the javascript functions in Materialize CSS in my Svelte Project. I have a navbar which is called in app.svelte. I have called M.AutoInit(); in the script tags of app.svelte as so:
<script>
import "../node_modules/materialize-css/dist/css/materialize.min.css";
import "../node_modules/materialize-css/dist/js/materialize.min.js";
import { Router, Route } from "svelte-routing";
import { setupI18n, isLocaleLoaded, locale } from "./services/i18n";
import { derived } from "svelte/store";
import Home from "./pages/Home.svelte";
import About from "./pages/About.svelte";
import Navbar from "./layout/Navbar.svelte";
$: if (!$isLocaleLoaded) {
setupI18n({ withLocale: "jp" });
}
M.AutoInit();
</script>
{#if $isLocaleLoaded}
<Router>
<Navbar />
<Route path="/" component={Home} />
<Route path="/about" component={About} />
</Router>
{:else}
<p>Loading...</p>
{/if}
I add the required javascript in my Navbar.svelte file as in the materialize css documentation here.
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.sidenav');
var instances = M.Sidenav.init(elems, options);
});
However click the mobile hamburger button does not bring out the side menu.
In addition, browser console says that "options" is not defined.

Hello stackoverflow and svelte community. I have fixed the above issue, and will document my steps here:
In my Navbar.svelte file, I re-wrote the javascript into a function:
function mobileNav() {
var elems = document.querySelectorAll(".sidenav");
var instances = M.Sidenav.init(elems);
}
Then, I bound the function to the mobile hamburger button by adding "on:click={mobileNav}" to the hamburger button, as is possible in svelte! Here it is using the Navbar as in documentation:
<nav>
<div class="nav-wrapper">
Logo
menu</i>
<ul class="right hide-on-med-and-down">
<li>Sass</li>
<li>Components</li>
<li>Javascript</li>
<li>Mobile</li>
</ul>
</div>
</nav>
<ul class="sidenav" id="mobile-demo">
<li>Sass</li>
<li>Components</li>
<li>Javascript</li>
<li>Mobile</li>
</ul>
In the navbar documentation, the function takes the arguments (elems, options) however removing options fixed the problem entirely.

Related

NextJs 13 Experimental App Dir Hash in routes not directing to the hash id

I am using Nextjs 13 with the experimental App Dir but am not sure if this problem I am facing has anything to do with the issue I am facing. I have an id in my home page of "faqs" and when I click on the link, I can see it successfully goes to that link but does nothing in the browser. If I am on another page, I click the link and it takes me to the home page with the correct url but still stays on the top of the page and does not scroll to the indicated id. I did implement scroll={false} as suggested in the documentation but it makes no difference.
Here is a snippet of the relevant code parts:
"use client"
import React, { useState } from "react"
import { useRouter } from "next/navigation"
import Link from "next/link"
const Navigation = () => {
const router = useRouter()
...
In the return:
<Link scroll={false} href="/#faqs">FAQS</Link>
I Even tried:
<button type="button" onClick={() => router.push("/#faqs")}>FAQS</button>
In React the hash works fairly well but in next js, even only in client rendering it seems convoluted. If anyone knows what I am doing wrong or if there is a viable work around, I would sure appreciate it.
Thank you in advance.
If I am missing anything, please let me know.
I use hashtags a lot and I plan to start using the app directory in future projects, so I dug into this and it's not pretty. Apparently, NextJS uses a different package for app directory components client-side called "next/navigation". It's very different from "next/router". Also, when using "next/link" elements, NextJS does not trigger the onRouteChangeComplete event when location.hash changes but location.pathname does not.
So, in order to detect a hash change and scroll to the associated element, I finally had to implement this hack:
"use client"
import { Inter } from '#next/font/google'
import paragraph from './paragraph'
import Link from 'next/link'
import { useEffect, useState } from 'react'
const inter = Inter({ subsets: ['latin'] })
export default function Home() {
const [navClick, setNavClick] = useState(false);
useEffect(() => {
setTimeout(() => {
const hash = window.location.hash;
if (hash) document.querySelector(hash).scrollIntoView();
}, 0);
}, [navClick])
const toggleNavClick = () => setNavClick((oldVal) => !oldVal);
return (
<main>
<nav>
<ul>
<li>
<Link href="/#one" onClick={toggleNavClick}>Section One</Link>
</li>
<li>
<Link href="/#two" onClick={toggleNavClick}>Section Two</Link>
</li>
<li>
<Link href="/#three" onClick={toggleNavClick}>Section Three</Link>
</li>
</ul>
</nav>
<div className="container">
<section id="one">
<h1>Section One</h1>
<div dangerouslySetInnerHTML={{ __html: paragraph }} />
</section>
<section id="two">
<h1>Section Two</h1>
<div dangerouslySetInnerHTML={{ __html: paragraph }} />
</section>
<section id="three">
<h1>Section Three</h1>
<div dangerouslySetInnerHTML={{ __html: paragraph }} />
</section>
</div>
</main>
)
}
Since the hash change cannot be detected because no event is triggered, I basically created an event by toggling navClick each time a link is clicked. The navigation logic is enclosed in setTimeout() function because it triggers after window.location is updated.
Repo: https://github.com/designly1/next-hash-test
Demo: https://next-hash-test.vercel.app/

How to open a component in another window with React?

I am trying to make a component page open in another window when I click a button. I have tried using window.open(<Contact />), however that does not seem to work.
I am trying to make it so that the <button>Contact me!</button> opens that component in a full window. Is there a way to do that?
ContactMe.jsx:
import '../App.css';
import Contact from './Contact';
import { ReactComponent as LinkedInLogo } from '../images/linkedin.svg';
function ContactMe() {
return(
<>
<div className='contact-container' id='contactMe'>
<div className='contact-box'>
<h1>Want to connect?</h1>
<button id='contact-me-btn'>Contact Me!</button>
<a>
<LinkedInLogo title='LinkedIn Profile' id='linkedinprofile-svg'/>
</a>
</div>
<div className='contact-container-footer'>
<h7>Designed and built by <a href='https://github.com/BlazingIsFire' target='_blank' title='Github'>Andrew Schweitzer</a>.</h7>
</div>
</div>
</>
)
}
export default ContactMe;
First create Route for the component tab
<Route path="/Contact" element={<Contact />}> // if you are using router v6
To open the link in a new tab, use the element by passing a target attribute with a value _blank. Like this
<button>Contact Me </button>

Using Fullpagejs with react-router-dom

I am building a website using Fullpage.js, React, and react-router-dom. I create a Link in the second section in the Fullpage component, and I want this Link can take me to another route (/anotherPage):
// Fullpage.js
import React, { useEffect } from "react";
import { Link } from "react-router-dom";
import { initFullpage } from "./initFullpage";
const Fullpage = () => {
useEffect(() => {
initFullpage();
}, []);
return (
<div id="fullpage">
<div class="section">Some section</div>
<div class="section">
<Link to="/anotherPage">
Go to a special page.
</Link>
</div>
<div class="section">Some section</div>
<div class="section">Some section</div>
</div>
);
};
export default Fullpage;
Additionally, I need another Link to go back from /anotherPage route back to the second section in the Fullpage component.
I made a demo here.
As you can try, if you click the link on the second section, react can route you to AnotherPage, but the navigation dots provide by Fullpage package is still there, and you can even scroll up and down, though this will cause errors. Also, if you click Go back, it will also break the App.
How to do it right? Thanks for your help!
Here is my App.js:
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import Fullpage from "./components/Fullpage";
import AnotherPage from "./components/AnotherPage";
export default function App() {
return (
<Router>
<Switch>
<Route exact path="/">
<Fullpage />
</Route>
<Route exact path="/anotherPage">
<AnotherPage />
</Route>
</Switch>
</Router>
);
}
I found I don't need to use Fullpage.js to achieve the "scroll-full-page" effect. It's actually easy to achieve by CSS. Have a look at scroll-snap-type.
// index.html
<div class="container">
<section class="page">
Page one
</section>
<section class="page">
Page two
</section>
</div>
// css
.container{
width: 100%;
height: 100vh;
scroll-snap-type: y mandatory;
overflow: auto;
}
.page{
scroll-snap-align: start;
height: 100vh;
}
Then you can have Fullpage.js type scrolling effect. Then you can use react-router-dom without problem.

Using next js for a static website

error - React.Children.only expected to receive a single React element child.
There were quite a few questions with the same context, I tried those solutions but have not found a solution.
The Navbar of the website is what is giving me the error. There is a section over the Navbar which renders properly, when I try to render the Navbar below it throws the error.
import Link from 'next/link'
import Head from '../components/head'
import Download from '../components/nav'
import NavBar from '../components/header'
import Footer from '../components/footer'
import htmlContent from 'html-loader!../legacy/index.html'
const Homepage = () => (
<div>
<Head />
<Download/>
<NavBar />
<div dangerouslySetInnerHTML={{__html: htmlContent}} />
<Footer />
</div>
);
export default Homepage
The footer shows properly, head tag is for all the meta data etc(also works). Github link to all the code is-https://github.com/yohanelly/website-jsx/tree/master/components
The problem is with the whitespace between the Link and the a tag.
<Link href="#"> <a className="menu-links features">Features</a></Link>
should be either
<Link href="#"><a className="menu-links features">Features</a></Link>
or
<Link href="#">
<a className="menu-links features">Features</a>
</Link>
Read the Children in JSX section of the React docs for more info.

can't route successfully between components in react app

I have a static react app (that means there is not server side rendering) located under example.com/web-class.gr. My problem is that I can't route between components when I use my sidebar menu.
For instance. When I navigate to example.com/web-class.gr/css-intermediate the page loads as expected. From now on if I navigate to different lessonName the page is loading as expected. But I also have exercises, which I can't load when I press the corresponding button in my menu. To get an idea this is my index.js file:
import React from 'react';
import { Link as ReactLink } from 'react-router';
import sidebarStore from './Sidebar/SidebarStore';
import lessonValues from '../../lessonValues';
import LessonStore from '../../LessonStore';
import SidebarLink from './Sidebar/SidebarLink';
export default class Sidebar extends React.Component {
constructor() {
super();
this.state = {
SidebarIsCollapse: sidebarStore.getCurrentState()
}
this.NavMdPlaceholderClass = 'hidden-xs col-sm-4 col-md-3 col-lg-3';
}
componentWillMount() {
sidebarStore.on('change', () => {
this.setState({ SidebarIsCollapse: sidebarStore.getCurrentState() });
this.ChangeSidebarState();
});
this.RenderMainMenu();
}
ChangeSidebarState() {
const NAV_DefaultClasses = "col-sm-4 col-md-3 col-lg-3 ";
if (this.state.SidebarIsCollapse) {
this.NavMdPlaceholderClass = NAV_DefaultClasses + "slideInLeft";
} else {
this.NavMdPlaceholderClass = NAV_DefaultClasses + "slideOffLeft";
}
}
RenderMainMenu() {
this.main_menu = [];
for (let link of lessonValues) {
let { Id, url, isExercise, title } = link;
this.main_menu.push(<SidebarLink key={Id} url={url} isExercise={isExercise} title={title}/>);
}
}
render() {
return (
<div class={this.NavMdPlaceholderClass} id="nav-md-placeholder">
<nav id="sidebar">
<ul id="main-menu">
<li class="ripple-btn">
<ReactLink to="/" onClick={this.SetLessonDetails.bind(this)}>
<span class="item-align-fix">
<i class="glyphicon glyphicon-home" style={{'marginRight': '10px'}}></i>
<strong>
<span>AΡΧΙΚΗ</span>
</strong>
</span>
</ReactLink>
</li>
{this.main_menu}
</ul>
</nav>
</div>
);
}
}
here is the SidebarLink component file:
import React from 'react';
import LessonStore from '../../../LessonStore';
import { Link as ReactLink } from 'react-router';
export default class SidebarLink extends React.Component {
SetPageTitle() {
LessonStore.setLesson(this.props.url);
}
render() {
let glyphoconType = 'glyphicon ';
glyphoconType += this.props.isExercise ? 'glyphicon-pencil' : 'glyphicon-ok-sign';
glyphoconType += ' nav-ico untaken-lesson';
return (
<li class="ripple-btn">
<ReactLink to={this.props.url} onClick={() => this.SetPageTitle()} >
<span class="item-align-fix">
<i class={glyphoconType}></i>
<span>{this.props.title}</span>
</span>
</ReactLink>
</li>
);
}
}
But if I refresh the page manually, I am able to reveal the exercise page. But now I can't navigate to any other element. Only if I click it in sidebar menu and manually refresh the page.
To sum up:
The lessons are loading dynamically. I can navigate between them.
I can't navigate to exercises. Only if I click the corresponding exercise and hit the refresh button.
If I'm viewing an exercise (eg exercise-1), I am not able to navigate to any other component.
I use nginx and below is my rule for the project:
location ^~ /web-class.gr/ {
try_files $uri $uri/ =404;
if (!-e $request_filename){
rewrite ^(.*)$ /web-class.gr/index.html break;
}
}
And lastly here is my sidebar component:
import React from 'react';
import { Link as ReactLink } from 'react-router';
import sidebarStore from './Sidebar/SidebarStore';
import lessonValues from '../../lessonValues';
import LessonStore from '../../LessonStore';
import SidebarLink from './Sidebar/SidebarLink';
// some other helper functions here
render() {
return (
<div class={this.NavMdPlaceholderClass} id="nav-md-placeholder">
<nav id="sidebar">
<ul id="main-menu">
<li class="ripple-btn">
<ReactLink to="/web-class.gr/" onClick={this.SetLessonDetails.bind(this)}>
<span class="item-align-fix">
<i class="glyphicon glyphicon-home" style={{'marginRight': '10px'}}></i>
<strong>
<span>AΡΧΙΚΗ</span>
</strong>
</span>
</ReactLink>
</li>
{this.main_menu}
</ul>
</nav>
</div>
);
Is there any problem with ReactLink to? On my apache machine all works as expected. I can't figure out why my program breaks.
Update
I provide the link of the site to help your job become easier. The site is in greek although I believe you can understand it's structure.
web-class.gr
Code on Github
This One worked For me
NB
for React Router
use <BrowserRouter> tag only once to enclose the whole of your application.
Use this tag at the point of Rendering.
For Example
If you are using Create-React-app .Use this at your Index.js file
ReactDom.Render(<BrowserRouter><App/></BrowserRouter>)
Second Update:
Change your render code in react/index.js to
ReactDom.render(
<Router history={browserHistory} >
<Route path="/" component={Layout} >
<IndexRoute component={Index} ></IndexRoute>
<Route path="/exercise-1" name="exercise-1" component={Exercise1} ></Route>
<Route path="/exercise-2" name="exercise-2" component={Exercise2} ></Route>
<Route path="/exercise-3" name="exercise-3" component={Exercise3} ></Route>
<Route path="/exercise-4" name="exercise-4" component={Exercise4} ></Route>
<Route path="/exercise-5" name="exercise-5" component={Exercise5} ></Route>
<Route path="/exercise-6" name="exercise-6" component={Exercise6} ></Route>
<Route path="/:lessonName" name="lesson" component={Lesson} ></Route>
<Route path=":lessonName" name="lesson" component={Lesson} ></Route>
</Route>
</Router>
,app);
i..e the path starts with /

Resources