Initial commit
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
# EditorConfig is awesome: https://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
@@ -0,0 +1,47 @@
|
||||
name: CI
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
eslint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: latest
|
||||
- name: Install modules
|
||||
run: bun ci
|
||||
- name: Run ESLint
|
||||
run: bun run lint
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
needs: eslint
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: latest
|
||||
- name: Install modules
|
||||
run: bun ci
|
||||
- name: Build site
|
||||
run: bun run build
|
||||
- name: Upload static files as artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: dist/
|
||||
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
permissions:
|
||||
pages: write
|
||||
id-token: write
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
@@ -0,0 +1,5 @@
|
||||
.idea
|
||||
.vscode
|
||||
node_modules
|
||||
.eslintcache
|
||||
dist
|
||||
@@ -0,0 +1,32 @@
|
||||
# Vue-boilerplate
|
||||
*Minimal static Vue project*
|
||||
|
||||
<!-- TODO: 1. rename app (and tool URL) -->
|
||||
|
||||
### [Tool link](https://klemek.github.io/vue-boilerplate/)
|
||||
|
||||
## Use this template
|
||||
|
||||
<!-- TODO: 3. remove this part -->
|
||||
|
||||
```bash
|
||||
git clone git@github.com/klemek/vue-boilerplate.git {PROJECT}
|
||||
cd {PROJECT}
|
||||
git remote rename origin template
|
||||
git remote add origin {PROJECT REMOTE}
|
||||
# everytime you want to update your fork
|
||||
git fetch --all
|
||||
git merge template/master
|
||||
```
|
||||
|
||||
> Every task is indicated with a TODO
|
||||
|
||||
1. [ ] Rename app in [README.md](./README.md), [index.html](./index.html), [App.vue](./src/App.vue) and [package.json](./package.json)
|
||||
2. [ ] Change app hue and saturation in [style.css](./style.css)
|
||||
3. [ ] Remove this part and all TODO
|
||||
|
||||
|
||||
## Tips
|
||||
|
||||
* [Material design colors](https://materialui.co/colors/) are available, you can use `class="red-500"` on your HTML
|
||||
* [Lucide icons](https://lucide.dev/icons) are available, you can use `<LucideIcon name=house/>` on your Vue template
|
||||
@@ -0,0 +1,24 @@
|
||||
import { globalIgnores } from "eslint/config";
|
||||
import {
|
||||
defineConfigWithVueTs,
|
||||
vueTsConfigs,
|
||||
} from "@vue/eslint-config-typescript";
|
||||
import pluginVue from "eslint-plugin-vue";
|
||||
import skipFormatting from "@vue/eslint-config-prettier/skip-formatting";
|
||||
import { configureVueProject } from "@vue/eslint-config-typescript";
|
||||
|
||||
configureVueProject({ scriptLangs: ["ts", "tsx"] });
|
||||
|
||||
export default defineConfigWithVueTs(
|
||||
{
|
||||
name: "app/files-to-lint",
|
||||
files: ["**/*.{ts,mts,tsx,vue}"],
|
||||
},
|
||||
|
||||
globalIgnores(["**/dist/**"]),
|
||||
|
||||
pluginVue.configs["flat/recommended"],
|
||||
vueTsConfigs.strictTypeChecked,
|
||||
vueTsConfigs.stylisticTypeChecked,
|
||||
skipFormatting,
|
||||
);
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- TODO: 1. rename app -->
|
||||
<title>Change this you moron</title>
|
||||
<link rel="stylesheet" href="/style.css" />
|
||||
<link rel="stylesheet" href="/material-colors.css" />
|
||||
<!-- <link rel="icon" href="/favicon.ico"> -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta charset="UTF-8">
|
||||
<!-- card related -->
|
||||
<!--
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta property="og:title" content="">
|
||||
<meta property="og:description" content="">
|
||||
<meta property="og:image" content="https://.../preview_640x320.jpg">
|
||||
<meta property="org:url" content="https://...">
|
||||
-->
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
Generated
+4860
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "vue-boilerplate",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "run-p type-check \"build-only {@}\" --",
|
||||
"preview": "vite preview",
|
||||
"build-only": "vite build",
|
||||
"type-check": "vue-tsc --build",
|
||||
"lint": "eslint . --cache",
|
||||
"fix": "eslint . --fix --cache",
|
||||
"format": "prettier --write --experimental-cli src/"
|
||||
},
|
||||
"dependencies": {
|
||||
"lucide-vue-next": "^0.562.0",
|
||||
"vue": "^3.5.25"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/node24": "^24.0.3",
|
||||
"@types/node": "^24.10.1",
|
||||
"@vitejs/plugin-vue": "^6.0.2",
|
||||
"@vue/eslint-config-prettier": "^10.2.0",
|
||||
"@vue/eslint-config-typescript": "^14.6.0",
|
||||
"@vue/tsconfig": "^0.8.1",
|
||||
"eslint": "^9.39.1",
|
||||
"eslint-plugin-vue": "~10.5.1",
|
||||
"jiti": "^2.6.1",
|
||||
"npm-run-all2": "^8.0.4",
|
||||
"prettier": "3.6.2",
|
||||
"typescript": "~5.9.0",
|
||||
"vite": "^7.2.4",
|
||||
"vite-plugin-vue-devtools": "^8.0.5",
|
||||
"vue-tsc": "^3.1.5"
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
=================================================
|
||||
https://www.joshwcomeau.com/css/custom-css-reset/
|
||||
=================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
1. Use a more-intuitive box-sizing model.
|
||||
*/
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
/*
|
||||
2. Remove default margin
|
||||
*/
|
||||
* {
|
||||
margin: 0;
|
||||
}
|
||||
/*
|
||||
3. Allow percentage-based heights in the application
|
||||
*/
|
||||
html,
|
||||
body, div#app {
|
||||
height: 100%;
|
||||
}
|
||||
/*
|
||||
Typographic tweaks!
|
||||
4. Add accessible line-height
|
||||
5. Improve text rendering
|
||||
*/
|
||||
body {
|
||||
line-height: 1.5;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
/*
|
||||
6. Improve media defaults
|
||||
*/
|
||||
img,
|
||||
picture,
|
||||
video,
|
||||
canvas,
|
||||
svg {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
}
|
||||
/*
|
||||
7. Remove built-in form typography styles
|
||||
*/
|
||||
input,
|
||||
button,
|
||||
textarea,
|
||||
select {
|
||||
font: inherit;
|
||||
}
|
||||
/*
|
||||
8. Avoid text overflows
|
||||
*/
|
||||
p,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
/*
|
||||
9. Create a root stacking context
|
||||
*/
|
||||
#root,
|
||||
#__next {
|
||||
isolation: isolate;
|
||||
}
|
||||
|
||||
/*
|
||||
=================================================
|
||||
CUSTOM STYLE
|
||||
=================================================
|
||||
*/
|
||||
|
||||
@import url("https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap");
|
||||
@import url("https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap");
|
||||
|
||||
:root {
|
||||
/* https://materialui.co/colors/ */
|
||||
/* TODO: 2. change hue and saturation */
|
||||
--hue-primary: 65.52;
|
||||
--sat-primary: 20%;
|
||||
--background: hsl(var(--hue-primary), var(--sat-primary), 96.08%);
|
||||
--background-primary: hsl(var(--hue-primary), var(--sat-primary), 93.33%);
|
||||
--background-secondary: hsl(var(--hue-primary), var(--sat-primary), 90%);
|
||||
--color-primary: hsl(var(--hue-primary), var(--sat-primary), 50%);
|
||||
--text-primary: hsl(var(--hue-primary), var(--sat-primary), 25%);
|
||||
--text-secondary: hsl(var(--hue-primary), var(--sat-primary), 30%);
|
||||
}
|
||||
|
||||
/*
|
||||
=================================================
|
||||
https://blog.koley.in/2019/339-bytes-of-responsive-css
|
||||
https://www.swyx.io/css-100-bytes
|
||||
https://gist.github.com/JoeyBurzynski/617fb6201335779f8424ad9528b72c41
|
||||
=================================================
|
||||
*/
|
||||
|
||||
html,
|
||||
body {
|
||||
padding: 0;
|
||||
max-width: 100%;
|
||||
color: var(--text-primary);
|
||||
font-family: "Roboto", Verdana, serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--background);
|
||||
}
|
||||
|
||||
main {
|
||||
padding: 1.5rem;
|
||||
margin: auto;
|
||||
background-color: var(--background-primary);
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin: 1em 0 0.5em;
|
||||
}
|
||||
|
||||
p,
|
||||
ul,
|
||||
ol {
|
||||
margin-bottom: 2em;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
hr {
|
||||
opacity: 25%;
|
||||
border-bottom: 0;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
textarea,
|
||||
input,
|
||||
select,
|
||||
.mono {
|
||||
font-family: "Roboto Mono", monospace;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
main {
|
||||
max-width: 42rem;
|
||||
}
|
||||
table {
|
||||
font-size: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* LUCIDE ICONS
|
||||
*/
|
||||
|
||||
.lucide {
|
||||
width: 1.1em;
|
||||
height: 1.1em;
|
||||
}
|
||||
|
||||
svg.lucide {
|
||||
display: inline-block;
|
||||
vertical-align: text-top;
|
||||
}
|
||||
|
||||
b .lucide,
|
||||
h1 .lucide,
|
||||
h2 .lucide,
|
||||
h3 .lucide,
|
||||
h4 .lucide,
|
||||
h5 .lucide,
|
||||
h6 .lucide {
|
||||
stroke-width: 3;
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from "vue";
|
||||
import LucideIcon from "./components/LucideIcon.vue";
|
||||
import CustomButton from "./components/CustomButton.vue"
|
||||
|
||||
const visible = ref<boolean>(false);
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
visible.value = true;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main :style="{ display: visible ? 'inherit' : 'none' }">
|
||||
<!-- TODO: 1. rename app -->
|
||||
<h1>
|
||||
<LucideIcon name="package" />
|
||||
Vue-Boilerplate
|
||||
</h1>
|
||||
<br />
|
||||
<p>
|
||||
Fill this page with <i>whatever</i> you're going to develop.
|
||||
<br>
|
||||
<b>Then enjoy!</b>
|
||||
</p>
|
||||
<CustomButton>
|
||||
<LucideIcon name="square-arrow-right"/> This is a sample button yay
|
||||
</CustomButton>
|
||||
<br />
|
||||
<hr />
|
||||
<small class="footer">
|
||||
<LucideIcon name="at-sign" />
|
||||
|
||||
<a href="https://github.com/klemek" target="_blank">klemek</a>
|
||||
-
|
||||
<!-- TODO: 1. rename app -->
|
||||
<LucideIcon name="github" />
|
||||
|
||||
<a href="https://github.com/klemek/vue-boilerplate" target="_blank">
|
||||
Repository
|
||||
</a>
|
||||
- 2025
|
||||
</small>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.button {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-decoration: none;
|
||||
padding: 1em;
|
||||
margin-bottom: 0.75em;
|
||||
border: 1px solid var(--color-primary);
|
||||
border-radius: 0.5em;
|
||||
background-color: var(--background);
|
||||
cursor: pointer;
|
||||
font-size: 1.333em;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background-color: var(--background-secondary);
|
||||
}
|
||||
|
||||
.footer {
|
||||
opacity: 50%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,36 @@
|
||||
<script setup lang="ts">
|
||||
interface Props {
|
||||
href?: string;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
defineProps<Props>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component
|
||||
:is="href ? 'a' : 'div'"
|
||||
:class="`button ${color ? 'b-' + color + ' ' + color : ''}`"
|
||||
>
|
||||
<slot></slot>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.button {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-decoration: none;
|
||||
padding: 1em;
|
||||
margin-bottom: 0.75em;
|
||||
border: 1px solid var(--color-primary);
|
||||
border-radius: 0.5em;
|
||||
background-color: var(--background);
|
||||
cursor: pointer;
|
||||
font-size: 1.333em;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background-color: var(--background-secondary);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,40 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted } from "vue";
|
||||
import * as icons from "lucide-vue-next";
|
||||
|
||||
interface Props {
|
||||
name: string;
|
||||
color?: string;
|
||||
strokeWidth?: string;
|
||||
defaultClass?: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
color: "currentColor",
|
||||
strokeWidth: "2",
|
||||
defaultClass: "lucide",
|
||||
});
|
||||
|
||||
function kebab2camel(kebab: string): string {
|
||||
return kebab
|
||||
.split("-")
|
||||
.map((item) => item.charAt(0).toUpperCase() + item.slice(1).toLowerCase())
|
||||
.join("");
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
console.log(kebab2camel(props.name));
|
||||
});
|
||||
|
||||
// @ts-expect-error: cannot infer type of all exported data
|
||||
const icon = computed(() => icons[kebab2camel(props.name)]);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component
|
||||
:is="icon"
|
||||
:color="color"
|
||||
:stroke-width="strokeWidth"
|
||||
:default-class="defaultClass"
|
||||
/>
|
||||
</template>
|
||||
@@ -0,0 +1,4 @@
|
||||
import { createApp } from "vue";
|
||||
import App from "./App.vue";
|
||||
|
||||
createApp(App).mount("#app");
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
|
||||
"exclude": ["src/**/__tests__/*"],
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"files": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.node.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.app.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "@tsconfig/node24/tsconfig.json",
|
||||
"include": [
|
||||
"vite.config.*",
|
||||
"vitest.config.*",
|
||||
"cypress.config.*",
|
||||
"nightwatch.conf.*",
|
||||
"playwright.config.*",
|
||||
"eslint.config.*"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"types": ["node"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { fileURLToPath, URL } from 'node:url'
|
||||
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import vueDevTools from 'vite-plugin-vue-devtools'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
base: '',
|
||||
plugins: [
|
||||
vue(),
|
||||
vueDevTools(),
|
||||
],
|
||||
publicDir: "public",
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
},
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user