Initial commit

This commit is contained in:
Filip Znachor 2024-06-05 21:47:16 +02:00
commit 0edbbb015e
12 changed files with 228 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
node_modules
bun.lockb

20
package.json Normal file
View file

@ -0,0 +1,20 @@
{
"name": "@codespacecz/web",
"version": "0.0.1",
"description": "Astro website components for CodeSpace websites",
"author": "CodeSpace (https://codespace.cz)",
"license": "LGPL-3.0-or-later",
"exports": {
"./components": "./src/components/index.ts",
"./types": "./src/types.ts",
"./style.css": "./src/css/style.css"
},
"dependencies": {
"astro-icon": "^1.1.0",
"@iconify-json/tabler": "^1.1.110"
},
"devDependencies": {
"astro": "^4.9.3",
"typescript": "^5.4.5"
}
}

View file

@ -0,0 +1,30 @@
---
import type { Meta } from '../types';
interface Props {
meta: Meta
}
const { meta } = Astro.props;
const title = meta.title + (meta.use_title_suffix ? meta.title_suffix : "");
const card = meta.image_type == "banner" ? "summary_large_image" : "summary";
---
<meta charset="UTF-8" />
<title>{title}</title>
<meta name="description" content={meta.desc} />
<meta name="theme-color" content={meta.color}>
<meta name="description" content={meta.desc}>
<meta property="og:site_name" content={meta.site_name}>
<meta property="og:title" content={meta.title}>
<meta property="og:description" content={meta.desc}>
<meta property="og:image" content={meta.image}>
<meta property="twitter:site_name" content={meta.site_name}>
<meta property="twitter:title" content={meta.title}>
<meta property="twitter:description" content={meta.desc}>
<meta property="twitter:image" content={meta.image}>
<meta property="twitter:card" content={card}>
<meta name="author" content={meta.author}>
<meta name="viewport" content="width=device-width" />
<link rel="icon" href={meta.favicon} />

32
src/components/Nav.astro Normal file
View file

@ -0,0 +1,32 @@
---
import { Icon } from 'astro-icon/components';
import type { NavProps, RecursivePartial } from '../types';
import "../css/nav.css";
type Props = RecursivePartial<NavProps>;
const logo = {
link: "/",
image: "/assets/logo.webp",
...Astro.props.logo
};
---
<input type="checkbox" id="menu-toggle">
<nav>
<div class="inner">
<div class="title">
<slot name="logo">
<a href={ logo.link } class="logo">
<img src={ logo.image } />
</a>
</slot>
<label for="menu-toggle">
<Icon name="tabler:menu-2" class="icon" />
</label>
</div>
<ul>
<slot />
</ul>
</div>
</nav>

View file

@ -0,0 +1,14 @@
---
import type { HTMLAttributes } from 'astro/types';
type Props = HTMLAttributes<'a'>;
const { href, class: className, ...props } = Astro.props;
const { pathname } = Astro.url;
const isActive = href === pathname;
---
<a href={href} class:list={[className, { active: isActive }]} {...props}>
<slot />
</a>

3
src/components/index.ts Normal file
View file

@ -0,0 +1,3 @@
export { default as MetaTags } from './MetaTags.astro';
export { default as Nav } from './Nav.astro';
export { default as NavLink } from './NavLink.astro';

14
src/css/global.css Normal file
View file

@ -0,0 +1,14 @@
html, body {font-family: Cantarell, sans-serif; background-color: var(--bg-color); color: var(--text-color); margin: 0; line-height: 1.5; font-size: 20px; display: flex; flex-direction: column; justify-content: space-between; min-height: 100vh;}
:is(nav, header, section, footer) > .inner {max-width: var(--site-width); margin: auto; padding: 0 var(--site-padding);}
@media screen and (max-width: 600px) {
:root {
--site-padding: 20px;
}
}
h1, h2, h3, h4, h5 {color: var(--title-color); font-weight: 900;}
a {color: var(--link-color);}
a:hover {color: var(--link-hover-color);}

49
src/css/nav.css Normal file
View file

@ -0,0 +1,49 @@
nav {position: relative; top: 0; left: 0; width: 100%; border-bottom: 1px solid var(--border-color); height: var(--nav-height);}
.style-white-nav nav img {filter: grayscale(1) brightness(10);}
nav .inner {display: flex; gap: 30px; align-items: center;}
nav .title > * {display: none;}
nav .title img {height: 30px;}
nav .title .icon {padding: 20px; margin: -20px; cursor: pointer; font-size: 24px; color: var(--title-color);}
nav .title .logo {display: flex;}
nav :is(a, label) {display: flex; align-items: center;}
nav ul {list-style: none; padding: 0; margin: 0; display: flex; gap: 20px; font-size: 20px; flex: 1;}
nav ul a {gap: 8px; color: var(--text-color); text-decoration: none; font-weight: 700; padding: 22px 0;}
nav a.active {color: var(--nav-link-color); box-shadow: 0 1px 0 0 var(--nav-link-color);}
nav a:hover {color: var(--text-hover-color);}
nav ul li.right {margin-left: auto;}
#menu-toggle {display: none;}
@media screen and (max-width: 900px) {
:root {
--nav-height: 64px !important;
}
nav {overflow: hidden;}
#menu-toggle:checked + nav {height: 100%;}
nav .inner {display: block; flex-direction: column-reverse;}
nav .title {display: grid; gap: 15px; grid-template-columns: 1fr max-content; border-bottom: 1px solid var(--border-color); height: var(--nav-height);}
nav .title > *, .nav .title {display: flex; align-items: center;}
nav .title img {height: 24px;}
nav ul {flex-direction: column; margin: 20px 0; gap: 0px;}
nav ul li {margin: 0 !important;}
nav ul a {padding: 6px 20px; padding-left: 51px; margin: 0 -20px; font-size: 18px; position: relative; text-decoration: none;}
nav ul a.active {font-weight: 900; box-shadow: none;}
nav ul a::before {content: ""; width: 11px; height: 2px; background-color: var(--nav-inactive-color); position: absolute; left: 23px; top: 50%; border-radius: 5px;}
nav ul a.active::before {background-color: var(--brand-color-1);}
}
:not(#menu-toggle:checked) + nav + header.under-nav {margin-top: calc(-1px - var(--nav-height)); padding-top: calc(1px + var(--nav-height));}

13
src/css/sections.css Normal file
View file

@ -0,0 +1,13 @@
/* Sections */
:is(header, section, footer) > .inner {margin: 70px auto; padding: 0 var(--site-padding);}
/* Header */
header > .inner {padding: 0 var(--site-padding);}
header {overflow: hidden;}
header:not(.no-line) + section {border-top: 1px solid var(--border-color);}
.in-header {margin-top: -50px;}

3
src/css/style.css Normal file
View file

@ -0,0 +1,3 @@
@import "./variables.css";
@import "./global.css";
@import "./sections.css";

23
src/css/variables.css Normal file
View file

@ -0,0 +1,23 @@
:root {
--bg-color: #18181b;
--alt-bg-color: #232327;
--border-color: rgba(255, 255, 255, 0.1);
--nav-link-color: #fff;
--nav-inactive-color: #fff5;
--nav-height: 75px;
--title-color: #fff;
--text-color: #fffa;
--text-hover-color: #fffd;
--text-active-color: #fff;
--link-color: #dd4379;
--link-hover-color: #c21f58;
--site-padding: 40px;
--site-width: 1200px;
}

25
src/types.ts Normal file
View file

@ -0,0 +1,25 @@
export type RecursivePartial<T> = {
[P in keyof T]?: RecursivePartial<T[P]>;
};
export interface Meta {
site_name: string,
author: string,
title: string,
desc: string,
title_suffix: string,
use_title_suffix: boolean,
image: string,
image_type: "banner" | "icon",
favicon: string,
color: string
}
export interface NavProps {
logo: NavLogo
}
interface NavLogo {
link: string,
image: string
}