-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
342 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"/> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> | ||
<link rel="icon" href="https://alpinejs.dev/favicon.png"/> | ||
<title>Hyper</title> | ||
<meta name="title" content="Hyper"/> | ||
<meta name="description" content="Frontend-template that helps quickly start projects from scratch"/> | ||
<meta name="keywords" content="front-end responsive utility-classes grid-layout responsive-design frontend-template tailwindcss alpinejs animate-css front-end-template"/> | ||
<meta name="author" content="Ray Chang"/> | ||
<!-- Open Graph / Facebook --> | ||
<meta property="og:type" content="website"/> | ||
<meta property="og:url" content="https://create-alpine-app.netlify.app/intro/"/> | ||
<meta property="og:title" content="Hyper"/> | ||
<meta property="og:description" content="Frontend-template that helps quickly start projects from scratch"/> | ||
<meta property="og:image" content="https://opengraph.githubassets.com/2469fa99cf18457e00fdde599b67f77cc3ff11f3195f336bef9e8b6ae314659d/rayc2045/create-alpine-app"/> | ||
<!-- Twitter --> | ||
<meta property="twitter:card" content="summary_large_image"/> | ||
<meta property="twitter:url" content="https://create-alpine-app.netlify.app/intro/"/> | ||
<meta property="twitter:title" content="Hyper"/> | ||
<meta property="twitter:description" content="Frontend-template that helps quickly start projects from scratch"/> | ||
<meta property="twitter:image" content="https://opengraph.githubassets.com/2469fa99cf18457e00fdde599b67f77cc3ff11f3195f336bef9e8b6ae314659d/rayc2045/create-alpine-app"/> | ||
<!-- Noto Sans TC --> | ||
<link rel="preconnect" href="https://fonts.googleapis.com"/> | ||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/> | ||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+Sans+TC:400,700&display=swap"/> | ||
<!-- Libraries --> | ||
<script src="https://cdn.tailwindcss.com"></script><!-- https://tailwindcss.com, https://hyperui.dev --> | ||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/animate.css@4.1.1/animate.min.css"/> | ||
<link rel="stylesheet" href="/src/style.css"/> | ||
<script src="/src/app.js" defer></script> | ||
<script src="https://cdn.jsdelivr.net/npm/alpinejs-component@1.2.6/dist/component.min.js" defer></script> | ||
<script src="https://cdn.jsdelivr.net/npm/@imacrayon/alpine-ajax@0.5.0/dist/cdn.min.js" defer></script> | ||
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js" defer></script> | ||
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.1.0/dist/purify.min.js" defer></script> | ||
</head> | ||
<body | ||
x-data="{ TITLE, ...utils, localStore, router }" | ||
class="min-h-svh flex flex-col" | ||
style="--animate-duration: 1.2s" | ||
@dragstart.prevent | ||
> | ||
<nav class="px-4 bg-base-100 sticky top-0 flex gap-4 border-b border-gray-200 bg-white z-[1]"> | ||
<a href="#/" class="py-4 font-bold text-lg text-gray-900" x-text="TITLE"></a> | ||
<ul class="hidden md:flex items-center gap-4 text-sm"> | ||
<li> | ||
<a class="inline-block py-4 hover:text-gray-500 transition" href="#/shop"> | ||
Shop | ||
</a> | ||
</li> | ||
<li> | ||
<a class="inline-block py-4 hover:text-gray-500 transition" href="#/collections"> | ||
Collections | ||
</a> | ||
</li> | ||
<li> | ||
<a class="inline-block py-4 hover:text-gray-500 transition" href="#/blog"> | ||
Blog | ||
</a> | ||
</li> | ||
<li> | ||
<a class="inline-block py-4 hover:text-gray-500 transition" href="#/about"> | ||
About | ||
</a> | ||
</li> | ||
</ul> | ||
</nav> | ||
|
||
<section class="relative bg-gray-100 border-y border-gray-200"> | ||
<div class="mx-auto max-w-screen-xl px-4 py-2"> | ||
<a | ||
href="https://github.com/rayc2045/Hyper" | ||
rel="noreferrer" | ||
target="_blank" | ||
class="flex items-center justify-center gap-1.5 hover:opacity-75 transition" | ||
> | ||
<span | ||
class="text-sm/none font-medium" | ||
x-text="`Enjoy ${TITLE}? Give it a star on GitHub`" | ||
></span> | ||
<span aria-hidden="true" role="img">🎉</span> | ||
</a> | ||
</div> | ||
<button | ||
aria-label="Close" | ||
class="absolute p-1 top-[.4rem] right-3 text-sm text-gray-500" | ||
@click="$el.parentNode.remove()" | ||
> | ||
✕ | ||
</button> | ||
</section> | ||
|
||
<main | ||
class="py-16 flex-1" | ||
x-init="router.updatePath()" | ||
x-html="router.getPageHTML()" | ||
@hashchange.window="router.updatePath(); scrollToTop();" | ||
></main> | ||
|
||
<footer class="border-t border-gray-200 bg-white"> | ||
<div class="mx-auto max-w-screen-xl px-4 py-8 lg:py-12"> | ||
<a href="#/"> | ||
<span class="font-medium text-lg text-gray-900 hover:text-gray-500 transition" x-text="TITLE"></span> | ||
</a> | ||
<div class="mt-6"> | ||
<p class="max-w-md text-pretty leading-relaxed text-gray-700"> | ||
Starter template for marketing and eCommerce websites. Powered by | ||
<a | ||
class="text-gray-900 hover:text-gray-500 transition underline" | ||
href="https://alpinejs.dev/" | ||
target="_blank" | ||
> | ||
Alpine.js | ||
</a> | ||
and | ||
<a | ||
class="text-gray-900 hover:text-gray-500 transition underline" | ||
href="https://www.hyperui.dev/" | ||
target="_blank" | ||
rel="noreferrer" | ||
> | ||
Hyper UI | ||
</a>. | ||
</p> | ||
<div class="mt-4 lg:flex lg:items-end lg:justify-between"> | ||
<ul class="flex gap-4"> | ||
<li> | ||
<a | ||
class="text-sm text-gray-900 hover:text-gray-500 transition underline" | ||
href="#/about/faqs" | ||
> | ||
FAQs | ||
</a> | ||
</li> | ||
<li> | ||
<a | ||
class="text-sm text-gray-900 hover:text-gray-500 transition underline" | ||
href="#/about/acknowledgements" | ||
> | ||
Acknowledgements | ||
</a> | ||
</li> | ||
</ul> | ||
<p class="mt-4 text-sm text-gray-700 lg:mt-0"> | ||
© <span x-text="new Date().getFullYear()"></span> Created by | ||
<a | ||
href="https://github.com/rayc2045" | ||
target="_blank" | ||
rel="noreferrer" | ||
class="text-gray-900 hover:text-gray-500 transition underline" | ||
> | ||
Ray C | ||
</a> | ||
</p> | ||
</div> | ||
</div> | ||
</div> | ||
</footer> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
'use strict'; | ||
|
||
const TITLE = 'Hyper'; | ||
|
||
const utils = { | ||
scrollToTop() { | ||
scrollTo({ top: 0, behavior: 'smooth' }); | ||
}, | ||
getWindowWidth() { | ||
return window.innerWidth; | ||
}, | ||
isVisible(el) { | ||
return el.getBoundingClientRect().bottom > 0; | ||
}, | ||
toggleClasses(el, cls) { | ||
cls.split(' ').map(cl => el.classList.toggle(cl)); | ||
}, | ||
getScrollProgress() { | ||
const winScroll = | ||
document.body.scrollTop || document.documentElement.scrollTop; | ||
const height = | ||
document.documentElement.scrollHeight - | ||
document.documentElement.clientHeight; | ||
const scrolled = (winScroll / height) * 100; | ||
return Math.round(scrolled) + '%'; | ||
}, | ||
playAudio(audio, volume = 1) { | ||
audio.currentTime = 0; | ||
audio.volume = volume; | ||
audio.play(); | ||
}, | ||
async fetchData(api) { | ||
return await fetch(api).then(res => res.json()); | ||
}, | ||
async delay(delay = 0) { | ||
await new Promise(resolve => { | ||
setTimeout(resolve, delay * 1000); | ||
}); | ||
}, | ||
getParamsByUrl(url = window.location.href) { | ||
const urlSearch = url.split('?')[1]; | ||
const urlSearchParams = new URLSearchParams(urlSearch); | ||
const entries = Object.fromEntries(urlSearchParams.entries()); | ||
Object.keys(entries).forEach(entry => { | ||
const split = entries[entry].split(' '); | ||
if (split.length === 1 && split[0] === '') return (entries[entry] = []); | ||
entries[entry] = split; | ||
}); | ||
return entries; | ||
}, | ||
copyText(text) { | ||
navigator.clipboard.writeText(text.trim()); | ||
}, | ||
getRandomNum(min, max) { | ||
return Math.floor(Math.random() * max) + min; | ||
}, | ||
thousandFormat(num) { | ||
const parts = num.toString().split('.'); | ||
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); | ||
return parts.join('.'); | ||
}, | ||
getRepeatedItem(arr) { | ||
const set = new Set(); | ||
return arr.filter(item => | ||
set.has(JSON.stringify(item)) | ||
? true | ||
: (set.add(JSON.stringify(item)), false) | ||
); | ||
}, | ||
}; | ||
|
||
const STORAGE_KEY = `${TITLE.replaceAll(' ', '-')}-hyper-app`; | ||
const localStore = { | ||
fetch() { | ||
return JSON.parse(localStorage.getItem(STORAGE_KEY)); | ||
}, | ||
save(id) { | ||
localStorage.setItem(STORAGE_KEY, JSON.stringify(id)); | ||
}, | ||
remove() { | ||
localStorage.removeItem(STORAGE_KEY); | ||
}, | ||
}; | ||
|
||
const router = { | ||
routes: [ | ||
{ path: '/', component: '/home.html' }, | ||
{ path: '/docs', component: '/docs.html' }, | ||
{ path: '/about/faq', component: '/about/faq.html' }, | ||
{ | ||
path: '/about/acknowledgements', | ||
component: '/about/acknowledgements.html', | ||
}, | ||
], | ||
currentPath: '', | ||
updatePath() { | ||
const path = location.hash.slice(1).split('?')[0]; | ||
this.currentPath = path.startsWith('/') ? path : '/'; | ||
}, | ||
async getPageHTML(path = this.currentPath) { | ||
const root = '/src/pages'; | ||
const page = | ||
this.routes.find(route => route.path === path)?.component || '/404.html'; | ||
return await fetch(root + page).then(res => res.text()); | ||
}, | ||
}; |
Oops, something went wrong.