1
0
Fork 0

Use eslint-config-awzzm-vue, refactor some code and improve NavigationBar.vue

This commit is contained in:
Moritz Ruth 2020-08-04 20:39:22 +02:00
parent eb9ad07a86
commit 37e43d4098
No known key found for this signature in database
GPG key ID: AFD57E23E753841B
23 changed files with 2141 additions and 1842 deletions

View file

@ -1,13 +0,0 @@
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

View file

@ -1,27 +1,12 @@
module.exports = {
"root": true,
"env": {
browser: true,
node: true,
es6: true
},
"parserOptions": {
"parser": "babel-eslint"
},
"extends": [
root: true,
extends: [
"plugin:nuxt/recommended",
"@moritzruth",
"@moritzruth/eslint-config/vue"
"awzzm-vue/nuxt"
],
rules: {
"no-unused-vars": "warn",
"vue/no-unused-components": "warn"
},
"settings": {
"import/resolver": {
webpack: {
config: "webpack.resolve.js"
parserOptions: {
parser: "babel-eslint",
ecmaVersion: 11,
sourceType: "module"
}
}
}
};

View file

@ -1,14 +1,15 @@
/* eslint-disable no-undef */
/* global workbox */
// Cache the Google Fonts stylesheets with a stale-while-revalidate strategy.
workbox.routing.registerRoute(
/^https:\/\/fonts\.googleapis\.com/,
/^https:\/\/fonts\.googleapis\.com/u,
new workbox.strategies.StaleWhileRevalidate({ cacheName: "google-fonts-stylesheets" })
);
)
// Cache the underlying font files with a cache-first strategy for 1 year.
workbox.routing.registerRoute(
/^https:\/\/fonts\.gstatic\.com/,
/^https:\/\/fonts\.gstatic\.com/u,
new workbox.strategies.CacheFirst({
cacheName: "google-fonts-webfonts",
plugins: [
@ -19,4 +20,4 @@ workbox.routing.registerRoute(
})
]
})
);
)

View file

@ -4,7 +4,7 @@ export const footerItems = [
to: "/legal-notice"
},
{
label: "Privacy Policy",
to: "/privacy-policy"
label: "Privacy",
to: "/privacy"
}
];
]

View file

@ -1,7 +1,7 @@
import _kebabCase from "lodash.kebabcase";
import _kebabCase from "lodash.kebabcase"
export function toModifierClasses(base, classes) {
return Object.entries(classes)
.filter(([, value]) => Boolean(value))
.map(([key]) => `${base}--${_kebabCase(key)}`);
.map(([key]) => `${base}--${_kebabCase(key)}`)
}

View file

@ -125,5 +125,5 @@
<script>
export default {
name: "AnimatedLogo"
};
}
</script>

View file

@ -31,44 +31,32 @@
</style>
<script>
import ExternalIcon from "@/assets/icons/external.svg";
import ExternalIcon from "@/assets/icons/external.svg"
export default {
name: "ExternalLink",
components: { ExternalIcon },
props: {
href: {
type: String,
required: true
},
showProtocol: {
type: Boolean,
default: false
},
showQuery: {
type: Boolean,
default: false
}
href: { type: String, required: true },
showProtocol: { type: Boolean },
showQuery: { type: Boolean }
},
computed: {
label() {
// eslint-disable-next-line import/no-extraneous-dependencies
const url = new (process.server ? require("url").URL : window.URL)(this.href);
let label = "";
const url = new (process.server ? require("url").URL : window.URL)(this.href)
let label = ""
if (this.showProtocol) {
label += url.protocol;
label += "//";
label += url.protocol
label += "//"
}
label += url.host + url.pathname;
label += url.host + url.pathname
if (this.showQuery) {
label += url.search;
}
return label;
if (this.showQuery) label += url.search
return label
}
}
}
};
</script>

View file

@ -126,30 +126,12 @@
export default {
name: "MyButton",
props: {
to: {
type: String,
default: ""
},
href: {
type: String,
default: ""
},
loading: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
isSubmit: {
type: Boolean,
default: false
},
center: {
type: Boolean,
default: false
}
to: { type: String, default: "" },
href: { type: String, default: "" },
loading: { type: Boolean },
disabled: { type: Boolean },
isSubmit: { type: Boolean },
center: { type: Boolean }
},
computed: {
isExternalLink: vm => Boolean(vm.href),
@ -157,28 +139,27 @@
},
methods: {
onClick(event) {
if (!this.disabled && !this.loading) {
this.$emit("click", event);
}
if (!this.disabled && !this.loading)
this.$emit("click", event)
}
},
render(h) {
const children = [];
const children = []
if (this.$slots.prefix) {
children.push(h("div", {
class: "my-button__prefix"
}, this.$slots.prefix));
}, this.$slots.prefix))
}
children.push(h("div", {
class: "my-button__text"
}, this.$slots.default));
}, this.$slots.default))
if (this.$slots.suffix) {
h("div", {
class: "my-button__suffix"
}, this.$slots.suffix);
}, this.$slots.suffix)
}
const baseOptions = {
@ -203,7 +184,7 @@
attrs: {
tabindex: this.disabled || this.loading ? "-1" : "0"
}
};
}
if (this.isInternalLink) {
return h("nuxt-link", {
@ -211,7 +192,7 @@
props: {
to: this.to
}
}, children);
}, children)
} else if (this.isExternalLink) {
return h("a", {
...baseOptions,
@ -220,7 +201,7 @@
href: this.href,
rel: "noopener"
}
}, children);
}, children)
}
return h("button", {
@ -230,7 +211,7 @@
disabled: this.disabled,
type: this.isSubmit ? "submit" : "button"
}
}, children);
}, children)
}
}
};
</script>

View file

@ -2,8 +2,8 @@
<footer class="my-footer">
<nuxt-link
v-for="item in $options.items"
class="my-footer__link"
:key="item.label"
class="my-footer__link"
:to="item.to"
@click.native.passive="open = false"
>
@ -55,10 +55,10 @@
</style>
<script>
import { footerItems } from "@/assets/js/footerItems";
import { footerItems } from "assets/js/footer-items"
export default {
name: "MyFooter",
items: footerItems
};
}
</script>

View file

@ -16,29 +16,22 @@
<span></span>
</div>
<div class="navigation-bar__links">
<div
v-for="item in $options.items"
class="navigation-bar__link-container"
:key="item.label"
>
<nuxt-link
v-if="item.to"
v-for="item in $options.items"
:key="item.label"
class="navigation-bar__link"
:exact="item.to === '/'"
:to="item.to"
@click.native.passive="open = false"
@click.native="open = false"
@mouseenter.native="e => handleLinkEvent(e, true)"
@focus.native="e => handleLinkEvent(e, true)"
@mouseleave.native="e => handleLinkEvent(e, false)"
@blur.native="e => handleLinkEvent(e, false)"
>
<span class="navigation-bar__link-text">
{{ item.label }}
</span>
</nuxt-link>
<a
v-else
class="navigation-bar__link"
rel="noopener"
:href="item.href"
@click.passive="open = false"
>
{{ item.label }}
</a>
</div>
</div>
</nav>
</div>
@ -147,9 +140,10 @@
border: none;
}
.navigation-bar__link-container {
.navigation-bar__link {
position: relative;
background: white;
text-decoration: none;
&:not(:last-child) {
margin-bottom: 10px;
@ -175,24 +169,33 @@
transition: 200ms opacity ease;
}
&:hover, &:focus-within {
&:hover, &:focus, &.nuxt-link-active {
&::before {
opacity: 1;
}
.navigation-bar__link {
.navigation-bar__link-text {
$offset: -3px;
outline: none;
transform: translate($offset, $offset);
}
}
}
.navigation-bar__link {
.navigation-bar--hide-active-state {
.navigation-bar__link.nuxt-link-active {
&::before {
opacity: 0;
}
.navigation-bar__link-text {
transform: translate(0, 0);
}
}
}
.navigation-bar__link-text {
display: block;
color: colors.$background-c;
text-decoration: none;
font-size: 2rem;
background: colors.$background;
@ -261,19 +264,19 @@
background: transparent;
}
.navigation-bar__link-container:not(:last-child) {
.navigation-bar__link:not(:last-child) {
margin-bottom: 0;
margin-right: 40px;
}
.navigation-bar__link {
.navigation-bar__link-text {
font-size: 1.3rem;
}
}
</style>
<script>
import { toModifierClasses } from "@/assets/js/toModifierClasses";
import { toModifierClasses } from "assets/js/to-modifier-classes"
const ITEMS = [
{
@ -284,49 +287,50 @@
label: "Projects",
to: "/projects"
}
];
]
export default {
name: "NavigationBar",
props: {
backgroundAfterScroll: {
type: Boolean,
default: false
},
title: {
type: String,
default: ""
}
backgroundAfterScroll: { type: Boolean },
title: { type: String, default: "" }
},
data: () => ({
open: false,
scrollPosition: 0
scrollPosition: 0,
hideActiveState: false
}),
computed: {
showTitle: vm => vm.scrollPosition > 60,
showBackground: vm => vm.backgroundAfterScroll ? vm.scrollPosition > 0 : true,
classes() {
const { open, showBackground } = this;
const { open, showBackground, hideActiveState } = this
return toModifierClasses("navigation-bar", {
open,
showBackground
});
showBackground,
hideActiveState
})
}
},
mounted() {
const scrollListener = () => {
this.scrollPosition = window.scrollY;
};
this.scrollPosition = window.scrollY
}
window.addEventListener("scroll", scrollListener, { passive: true });
window.addEventListener("scroll", scrollListener, { passive: true })
this.$on("hook:beforeDestroy", () => {
window.removeEventListener("scroll", scrollListener);
});
window.removeEventListener("scroll", scrollListener)
})
scrollListener();
scrollListener()
},
methods: {
handleLinkEvent(event, hideActiveStateNow) {
if (!event.target.classList.contains("nuxt-link-active")) this.hideActiveState = hideActiveStateNow
}
},
items: ITEMS
};
}
</script>

View file

@ -8,7 +8,7 @@
<div class="my-project__description">
<slot/>
</div>
<div class="my-project__links" v-if="github || npm || url">
<div v-if="github || npm || url" class="my-project__links">
<MyButton
v-if="url !== ''"
class="my-project__link"
@ -108,10 +108,10 @@
</style>
<script>
import MyButton from "@/components/MyButton";
import GitHubIcon from "@/assets/icons/github.svg";
import NPMIcon from "@/assets/icons/npm.svg";
import PointerRightIcon from "@/assets/icons/pointer-right.svg";
import MyButton from "@/components/MyButton"
import GitHubIcon from "@/assets/icons/github.svg"
import NPMIcon from "@/assets/icons/npm.svg"
import PointerRightIcon from "@/assets/icons/pointer-right.svg"
export default {
name: "MyProject",
@ -138,5 +138,5 @@
default: ""
}
}
};
}
</script>

View file

@ -14,10 +14,10 @@
</style>
<script>
import MyFooter from "@/components/MyFooter";
import MyFooter from "@/components/MyFooter"
export default {
name: "DefaultLayout",
components: { MyFooter }
};
}
</script>

View file

@ -9,5 +9,5 @@
<script>
export default {
name: "EmptyLayout"
};
}
</script>

7
manifest.json Normal file
View file

@ -0,0 +1,7 @@
{
"name": "Moritz Ruth",
"short_name": "Moritz Ruth",
"background_color": "#000000",
"display": "browser",
"description": "Moritz Ruth creates things."
}

View file

@ -1,4 +1,5 @@
/* eslint-disable camelcase */
import manifest from "./manifest.json"
// eslint-disable-next-line import/no-default-export
export default {
mode: "spa",
@ -6,7 +7,7 @@ export default {
** Headers of the page
*/
head: {
titleTemplate: "%s | Moritz Ruth",
titleTemplate: `%s | ${manifest.name}`,
link: [
{ rel: "icon", type: "image/x-icon", href: "/favicon.ico" },
{ rel: "stylesheet", href: "https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@400;600&display=swap" }
@ -49,31 +50,13 @@ export default {
meta: {
viewport: "width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0",
mobileApp: false,
name: "Moritz Ruth",
name: manifest.name,
author: "Moritz Ruth",
description: "Moritz Ruth is a web developer, photograph and digital creator.",
description: manifest.description,
lang: "en",
themeColor: "#000000"
},
// https://developer.mozilla.org/en-US/docs/Web/Manifest
manifest: {
name: "Moritz Ruth",
short_name: "Moritz Ruth",
background_color: "#000000",
display: "browser",
description: "Moritz Ruth is a web developer, photograph and digital creator."
}
},
/*
** Build configuration
*/
build: {
/*
** You can extend webpack config here
*/
// eslint-disable-next-line no-unused-vars
extend(config, context) {
manifest
}
}
};

View file

@ -1,7 +1,7 @@
{
"name": "moritzruth.de",
"description": "Moritz Ruth is a web developer, photograph and digital creator.",
"author": "Moritz Ruth",
"description": "Ny personal website",
"author": "Moritz Ruth <dev@moritzruth.de>",
"private": true,
"scripts": {
"dev": "HOST=0.0.0.0 nuxt",
@ -12,22 +12,21 @@
"dependencies": {
"@nuxtjs/pwa": "^3.0.0-beta.20",
"lodash.kebabcase": "^4.1.1",
"nuxt": "^2.12.2",
"shaped.js": "^1.0.3",
"nuxt": "^2.14.0",
"shaped.js": "^2.0.0",
"vue": "^2.6.11",
"vue-ripple-directive": "^2.0.1"
},
"devDependencies": {
"@moritzruth/eslint-config": "^2.0.5",
"@nuxt/types": "^2.14.1",
"@nuxtjs/eslint-module": "^2.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^7.0.0",
"eslint-import-resolver-webpack": "^0.12.1",
"eslint": "^7.6.0",
"eslint-config-awzzm-vue": "^1.0.2",
"eslint-plugin-nuxt": "^1.0.0",
"fibers": "^5.0.0",
"sass": "^1.26.3",
"sass-loader": "^8.0.2",
"serve": "^11.3.0",
"sass": "^1.26.10",
"sass-loader": "^9.0.2",
"svg-to-vue-component": "^0.3.8"
}
}

View file

@ -1,7 +1,7 @@
<template>
<div class="index-page">
<NavigationBar background-after-scroll title="Start"/>
<canvas class="index-page__background" ref="canvas"/>
<canvas ref="canvas" class="index-page__background"/>
<main class="index-page__content">
<AnimatedLogo/>
<div class="index-page__socials">
@ -12,7 +12,8 @@
><InstagramIcon class="index-page__social-icon"/></a>
<a
class="index-page__social"
href="https://twitter.com/moritz_ruth"
href="httpsU
://twitter.com/moritz_ruth"
title="Twitter"
><TwitterIcon class="index-page__social-icon"/></a>
<a
@ -34,10 +35,10 @@
<footer class="index-page__footer">
<nuxt-link
v-for="item in $options.footerItems"
class="index-page__footer-link"
:key="item.label"
class="index-page__footer-link"
:to="item.to"
@click.native.passive="open = false"
@click.native.passive="() => { open = null }"
>
{{ item.label }}
</nuxt-link>
@ -154,68 +155,34 @@
</style>
<script>
import { Canvas } from "shaped.js";
import AnimatedLogo from "@/components/AnimatedLogo";
import NavigationBar from "@/components/NavigationBar";
import { footerItems } from "@/assets/js/footerItems";
import InstagramIcon from "@/assets/icons/instagram.svg";
import TwitterIcon from "@/assets/icons/twitter.svg";
import NPMIcon from "@/assets/icons/npm.svg";
import GitHubIcon from "@/assets/icons/github.svg";
import EmailIcon from "@/assets/icons/email.svg";
const LINES = [
{
minCount: 8,
probability: 1 / 30000,
height: 1,
length: [80, 150],
speed: [0.2, 0.5],
colors: [
"#BB2081",
"#14AAD8"
]
}
];
import { ShapedCanvas } from "shaped.js"
import AnimatedLogo from "@/components/AnimatedLogo"
import NavigationBar from "@/components/NavigationBar"
import { footerItems } from "assets/js/footer-items"
import InstagramIcon from "@/assets/icons/instagram.svg"
import TwitterIcon from "@/assets/icons/twitter.svg"
import NPMIcon from "@/assets/icons/npm.svg"
import GitHubIcon from "@/assets/icons/github.svg"
import EmailIcon from "@/assets/icons/email.svg"
export default {
name: "IndexPage",
layout: "empty",
head: () => ({ title: "Moritz Ruth", titleTemplate: "%s" }),
components: { NavigationBar, AnimatedLogo, InstagramIcon, TwitterIcon, NPMIcon, GitHubIcon, EmailIcon },
mounted() {
let configIndex = 0;
const shaped = new ShapedCanvas(this.$refs.canvas, {
useWindowSize: true,
colors: ["#BB2081", "#14AAD8"],
minCount: 8,
probability: 1 / 30000,
height: 1,
length: [80, 150],
speed: [0.2, 0.5]
})
if (localStorage !== undefined) {
const rawValue = localStorage.getItem("nextBackground");
if (rawValue) {
try {
configIndex = JSON.parse(rawValue);
} catch {
// ignored
}
}
}
if (configIndex > LINES.length - 1) {
configIndex = 0;
}
if (localStorage !== undefined) {
localStorage.setItem("nextBackground", JSON.stringify(configIndex + 1));
}
const config = LINES[configIndex];
const backgroundCanvas = new Canvas(this.$refs.canvas, {
lines: config,
fillWindowSize: true
});
this.$once("hook:beforeDestroy", () => {
backgroundCanvas.destroy();
});
this.$once("hook:beforeDestroy", () => shaped.stop())
},
head: () => ({ title: "Moritz Ruth creates things", titleTemplate: "%s" }),
footerItems
};
}
</script>

View file

@ -66,7 +66,7 @@
</template>
<script>
import NavigationBar from "../components/NavigationBar";
import NavigationBar from "../components/NavigationBar"
export default {
name: "LegalNoticePage",
@ -75,5 +75,5 @@
htmlAttrs: { lang: "de" },
title: "Legal notice"
})
};
}
</script>

View file

@ -284,8 +284,8 @@
</style>
<script>
import ExternalLink from "@/components/ExternalLink";
import NavigationBar from "@/components/NavigationBar";
import ExternalLink from "@/components/ExternalLink"
import NavigationBar from "@/components/NavigationBar"
export default {
name: "PrivacyPolicyPage",
@ -294,5 +294,5 @@
htmlAttrs: { lang: "de" },
title: "Privacy Policy"
})
};
}
</script>

View file

@ -67,12 +67,12 @@
</style>
<script>
import NavigationBar from "@/components/NavigationBar";
import MyProject from "@/components/pages/projects/MyProject";
import NavigationBar from "@/components/NavigationBar"
import MyProject from "@/components/pages/projects/MyProject"
export default {
name: "ProjectsPage",
components: { MyProject, NavigationBar },
head: () => ({ title: "Projects" })
};
}
</script>

View file

@ -1,4 +1,4 @@
import Vue from "vue";
import Ripple from "vue-ripple-directive";
import Vue from "vue"
import Ripple from "vue-ripple-directive"
Vue.directive("ripple", Ripple);
Vue.directive("ripple", Ripple)

View file

@ -1,14 +0,0 @@
// eslint-disable-next-line import/no-extraneous-dependencies
const path = require("path");
// Used by ESLint and WebStorm
module.exports = {
resolve: {
alias: {
"@": path.resolve(__dirname),
"~": path.resolve(__dirname)
},
extensions: [".vue", ".js"]
}
};

3513
yarn.lock

File diff suppressed because it is too large Load diff