updates
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Vite + Vue + TS</title>
|
<title>Contexted</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app" class="bg-light"></div>
|
<div id="app" class="bg-light"></div>
|
||||||
|
|||||||
145
package-lock.json
generated
145
package-lock.json
generated
@@ -9,9 +9,11 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@popperjs/core": "^2.11.7",
|
"@popperjs/core": "^2.11.7",
|
||||||
|
"@vueuse/core": "^10.1.0",
|
||||||
"bootstrap": "^5.2.3",
|
"bootstrap": "^5.2.3",
|
||||||
"bootstrap-icons": "^1.10.5",
|
"bootstrap-icons": "^1.10.5",
|
||||||
"firebase": "^9.20.0",
|
"firebase": "^9.20.0",
|
||||||
|
"hamburgers": "^1.2.1",
|
||||||
"vue": "^3.2.47"
|
"vue": "^3.2.47"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -1012,6 +1014,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.1.tgz",
|
||||||
"integrity": "sha512-DZxSZWXxFfOlx7k7Rv4LAyiMroaxa3Ly/7OOzZO8cBNho0YzAi4qlbrx8W27JGqG57IgR/6J7r+nOJWw6kcvZA=="
|
"integrity": "sha512-DZxSZWXxFfOlx7k7Rv4LAyiMroaxa3Ly/7OOzZO8cBNho0YzAi4qlbrx8W27JGqG57IgR/6J7r+nOJWw6kcvZA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/web-bluetooth": {
|
||||||
|
"version": "0.0.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
|
||||||
|
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
|
||||||
|
},
|
||||||
"node_modules/@vitejs/plugin-vue": {
|
"node_modules/@vitejs/plugin-vue": {
|
||||||
"version": "4.2.1",
|
"version": "4.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.2.1.tgz",
|
||||||
@@ -1187,6 +1194,89 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.47.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.47.tgz",
|
||||||
"integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ=="
|
"integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@vueuse/core": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-3Znoa5m5RO+z4/C9w6DRaKTR3wCVJvD5rav8HTDGsr+7rOZRHtcgFJ8NcCs0ZvIpmev2kExTa311ns5j2RbzDQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/web-bluetooth": "^0.0.16",
|
||||||
|
"@vueuse/metadata": "10.1.0",
|
||||||
|
"@vueuse/shared": "10.1.0",
|
||||||
|
"vue-demi": ">=0.14.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@vueuse/core/node_modules/vue-demi": {
|
||||||
|
"version": "0.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz",
|
||||||
|
"integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"bin": {
|
||||||
|
"vue-demi-fix": "bin/vue-demi-fix.js",
|
||||||
|
"vue-demi-switch": "bin/vue-demi-switch.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@vue/composition-api": "^1.0.0-rc.1",
|
||||||
|
"vue": "^3.0.0-0 || ^2.6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@vue/composition-api": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@vueuse/metadata": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-cM28HjDEw5FIrPE9rgSPFZvQ0ZYnOLAOr8hl1XM6tFl80U3WAR5ROdnAqiYybniwP5gt9MKKAJAqd/ab2aHkqg==",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@vueuse/shared": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-2X52ogu12i9DkKOQ01yeb/BKg9UO87RNnpm5sXkQvyORlbq8ONS5l39MYkjkeVWWjdT0teJru7a2S41dmHmqjQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"vue-demi": ">=0.14.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@vueuse/shared/node_modules/vue-demi": {
|
||||||
|
"version": "0.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz",
|
||||||
|
"integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"bin": {
|
||||||
|
"vue-demi-fix": "bin/vue-demi-fix.js",
|
||||||
|
"vue-demi-switch": "bin/vue-demi-switch.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@vue/composition-api": "^1.0.0-rc.1",
|
||||||
|
"vue": "^3.0.0-0 || ^2.6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@vue/composition-api": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ansi-regex": {
|
"node_modules/ansi-regex": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||||
@@ -1500,6 +1590,11 @@
|
|||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/hamburgers": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/hamburgers/-/hamburgers-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-uFuVVF7/MeUtRWrA+S1FGGo4iVi7RgPzZAmljBnSeDh4snOZzaQ+oB6CI1m4vKD5RGz9s70ufgiJLxgivqA26Q=="
|
||||||
|
},
|
||||||
"node_modules/he": {
|
"node_modules/he": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
|
||||||
@@ -2780,6 +2875,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.1.tgz",
|
||||||
"integrity": "sha512-DZxSZWXxFfOlx7k7Rv4LAyiMroaxa3Ly/7OOzZO8cBNho0YzAi4qlbrx8W27JGqG57IgR/6J7r+nOJWw6kcvZA=="
|
"integrity": "sha512-DZxSZWXxFfOlx7k7Rv4LAyiMroaxa3Ly/7OOzZO8cBNho0YzAi4qlbrx8W27JGqG57IgR/6J7r+nOJWw6kcvZA=="
|
||||||
},
|
},
|
||||||
|
"@types/web-bluetooth": {
|
||||||
|
"version": "0.0.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
|
||||||
|
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
|
||||||
|
},
|
||||||
"@vitejs/plugin-vue": {
|
"@vitejs/plugin-vue": {
|
||||||
"version": "4.2.1",
|
"version": "4.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.2.1.tgz",
|
||||||
@@ -2940,6 +3040,46 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.47.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.47.tgz",
|
||||||
"integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ=="
|
"integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ=="
|
||||||
},
|
},
|
||||||
|
"@vueuse/core": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-3Znoa5m5RO+z4/C9w6DRaKTR3wCVJvD5rav8HTDGsr+7rOZRHtcgFJ8NcCs0ZvIpmev2kExTa311ns5j2RbzDQ==",
|
||||||
|
"requires": {
|
||||||
|
"@types/web-bluetooth": "^0.0.16",
|
||||||
|
"@vueuse/metadata": "10.1.0",
|
||||||
|
"@vueuse/shared": "10.1.0",
|
||||||
|
"vue-demi": ">=0.14.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"vue-demi": {
|
||||||
|
"version": "0.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz",
|
||||||
|
"integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==",
|
||||||
|
"requires": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@vueuse/metadata": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-cM28HjDEw5FIrPE9rgSPFZvQ0ZYnOLAOr8hl1XM6tFl80U3WAR5ROdnAqiYybniwP5gt9MKKAJAqd/ab2aHkqg=="
|
||||||
|
},
|
||||||
|
"@vueuse/shared": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-2X52ogu12i9DkKOQ01yeb/BKg9UO87RNnpm5sXkQvyORlbq8ONS5l39MYkjkeVWWjdT0teJru7a2S41dmHmqjQ==",
|
||||||
|
"requires": {
|
||||||
|
"vue-demi": ">=0.14.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"vue-demi": {
|
||||||
|
"version": "0.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz",
|
||||||
|
"integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==",
|
||||||
|
"requires": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"ansi-regex": {
|
"ansi-regex": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||||
@@ -3170,6 +3310,11 @@
|
|||||||
"is-glob": "^4.0.1"
|
"is-glob": "^4.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"hamburgers": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/hamburgers/-/hamburgers-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-uFuVVF7/MeUtRWrA+S1FGGo4iVi7RgPzZAmljBnSeDh4snOZzaQ+oB6CI1m4vKD5RGz9s70ufgiJLxgivqA26Q=="
|
||||||
|
},
|
||||||
"he": {
|
"he": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
|
||||||
|
|||||||
@@ -10,9 +10,11 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@popperjs/core": "^2.11.7",
|
"@popperjs/core": "^2.11.7",
|
||||||
|
"@vueuse/core": "^10.1.0",
|
||||||
"bootstrap": "^5.2.3",
|
"bootstrap": "^5.2.3",
|
||||||
"bootstrap-icons": "^1.10.5",
|
"bootstrap-icons": "^1.10.5",
|
||||||
"firebase": "^9.20.0",
|
"firebase": "^9.20.0",
|
||||||
|
"hamburgers": "^1.2.1",
|
||||||
"vue": "^3.2.47"
|
"vue": "^3.2.47"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
52
src/App.vue
52
src/App.vue
@@ -1,23 +1,55 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
import TopBar from './components/TopBar.vue'
|
import TopBar from './components/TopBar.vue'
|
||||||
import SideBar from './components/SideBar.vue'
|
import SideBar from './components/SideBar.vue'
|
||||||
import useNotes from './composables/useNotes'
|
import Note from './components/Note.vue'
|
||||||
|
import { activeNote } from './composables/useNotes'
|
||||||
|
|
||||||
const { notes } = useNotes()
|
const sideBarCollapsed = ref(false)
|
||||||
|
|
||||||
|
const viewModes: ViewMode[] = [
|
||||||
|
{ name: 'Note', icon: 'card-text' },
|
||||||
|
{ name: 'List', icon: 'list-task' },
|
||||||
|
{ name: 'Mindmap', icon: 'diagram-3' },
|
||||||
|
]
|
||||||
|
const activeViewMode = ref(viewModes[0])
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<TopBar />
|
<TopBar
|
||||||
<div class="container g-3 d-flex h-100" style="padding-top: 50px">
|
:side-bar-collapsed="sideBarCollapsed"
|
||||||
<SideBar class="py-3" />
|
@toggle-side-bar="sideBarCollapsed = !sideBarCollapsed"
|
||||||
<div id="main" class="bg-white border-start border-end px-4 py-3">
|
/>
|
||||||
main
|
<div class="container g-3 position-relative d-flex h-100">
|
||||||
<pre>{{ notes }}</pre>
|
<SideBar
|
||||||
|
:view-modes="viewModes"
|
||||||
|
:active-view-mode="activeViewMode"
|
||||||
|
@set-view-mode="(viewMode) => (activeViewMode = viewMode)"
|
||||||
|
class="py-3"
|
||||||
|
style="margin-top: 50px"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
id="main"
|
||||||
|
class="bg-white border-start border-end px-4 py-3"
|
||||||
|
:class="{ 'side-bar-collapsed': sideBarCollapsed }"
|
||||||
|
>
|
||||||
|
<Note v-if="activeNote" :note="activeNote" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<style>
|
<style lang="scss">
|
||||||
#main {
|
#main {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
}</style>
|
position: absolute;
|
||||||
|
top: 50px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
margin-left: $sidebar-width;
|
||||||
|
transition: margin $transition-duration ease-out;
|
||||||
|
&.side-bar-collapsed {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
4
src/assets/_variables.scss
Normal file
4
src/assets/_variables.scss
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
$primary: #1e4bc4;
|
||||||
|
$white: #fff !default;
|
||||||
|
$transition-duration: 0.2s;
|
||||||
|
$sidebar-width: 220px;
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
$primary: #1e4bc4;
|
@import './_variables';
|
||||||
|
|
||||||
@import 'bootstrap/scss/bootstrap';
|
@import 'bootstrap/scss/bootstrap';
|
||||||
|
|
||||||
body,
|
body,
|
||||||
@@ -7,3 +6,7 @@ body > div,
|
|||||||
html {
|
html {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|||||||
98
src/components/Hamburger.vue
Normal file
98
src/components/Hamburger.vue
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const props = defineProps<{
|
||||||
|
sideBarCollapsed: boolean
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'toggleSideBar'): void
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<button
|
||||||
|
class="hamburger hamburger--spin-r"
|
||||||
|
:class="{ 'is-active': !props.sideBarCollapsed }"
|
||||||
|
type="button"
|
||||||
|
@click="emit('toggleSideBar')"
|
||||||
|
>
|
||||||
|
<span class="hamburger-box">
|
||||||
|
<span class="hamburger-inner"></span>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
$hamburger-layer-color: $white;
|
||||||
|
$hamburger-layer-width: 25px;
|
||||||
|
$hamburger-layer-height: 3px;
|
||||||
|
$hamburger-layer-spacing: 3px;
|
||||||
|
$hamburger-padding-x: 0px;
|
||||||
|
$hamburger-padding-y: 0px;
|
||||||
|
$hamburger-scale-speed: calc($transition-duration/.22s);
|
||||||
|
|
||||||
|
@import 'hamburgers/_sass/hamburgers/hamburgers.scss';
|
||||||
|
@if index($hamburger-types, spin-r) {
|
||||||
|
/*
|
||||||
|
* Spin Reverse
|
||||||
|
*/
|
||||||
|
.hamburger--spin-r {
|
||||||
|
.hamburger-inner {
|
||||||
|
transition-duration: ($hamburger-scale-speed * 0.22s);
|
||||||
|
transition-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
transition: top
|
||||||
|
($hamburger-scale-speed * 0.1s)
|
||||||
|
($hamburger-scale-speed * 0.25s)
|
||||||
|
ease-in,
|
||||||
|
opacity ($hamburger-scale-speed * 0.1s) ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
transition: bottom
|
||||||
|
($hamburger-scale-speed * 0.1s)
|
||||||
|
($hamburger-scale-speed * 0.25s)
|
||||||
|
ease-in,
|
||||||
|
transform
|
||||||
|
($hamburger-scale-speed * 0.22s)
|
||||||
|
cubic-bezier(0.55, 0.055, 0.675, 0.19);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
.hamburger-inner {
|
||||||
|
transform: rotate(-225deg);
|
||||||
|
transition-delay: ($hamburger-scale-speed * 0.12s);
|
||||||
|
transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
top: 0;
|
||||||
|
opacity: 0;
|
||||||
|
transition: top ($hamburger-scale-speed * 0.1s) ease-out,
|
||||||
|
opacity
|
||||||
|
($hamburger-scale-speed * 0.1s)
|
||||||
|
($hamburger-scale-speed * 0.12s)
|
||||||
|
ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
bottom: 0;
|
||||||
|
transform: rotate(90deg);
|
||||||
|
transition: bottom ($hamburger-scale-speed * 0.1s) ease-out,
|
||||||
|
transform
|
||||||
|
($hamburger-scale-speed * 0.22s)
|
||||||
|
($hamburger-scale-speed * 0.12s)
|
||||||
|
cubic-bezier(0.215, 0.61, 0.355, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
button.hamburger {
|
||||||
|
outline: none !important;
|
||||||
|
line-height: 1;
|
||||||
|
opacity: 0.9;
|
||||||
|
border-radius: 2rem;
|
||||||
|
}
|
||||||
|
.hamburger-box {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
9
src/components/Note.vue
Normal file
9
src/components/Note.vue
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
defineProps<{
|
||||||
|
note: Note
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<h1>{{ note.title }}</h1>
|
||||||
|
<div>{{ note.content }}</div>
|
||||||
|
</template>
|
||||||
@@ -1,35 +1,35 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import useNotes from '../composables/useNotes'
|
import { rootNote } from '../composables/useNotes'
|
||||||
import SideBarMenu from './SideBar/SideBarMenu.vue'
|
import SideBarMenu from './SideBar/SideBarMenu.vue'
|
||||||
import SideBarMenuItem from './SideBar/SideBarMenuItem.vue'
|
import SideBarMenuItem from './SideBar/SideBarMenuItem.vue'
|
||||||
const { rootNote } = useNotes()
|
|
||||||
|
|
||||||
interface ViewMode {
|
const props = defineProps<{
|
||||||
name: string
|
viewModes: ViewMode[]
|
||||||
icon: string
|
activeViewMode: ViewMode
|
||||||
}
|
}>()
|
||||||
const viewModes: ViewMode[] = [
|
|
||||||
{ name: 'Note', icon: 'card-text' },
|
const emit = defineEmits<{
|
||||||
{ name: 'List', icon: 'list-task' },
|
(e: 'setViewMode', viewMode: ViewMode): void
|
||||||
{ name: 'Mindmap', icon: 'diagram-3' },
|
}>()
|
||||||
]
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div id="sidebar" class="position-relative pe-3 d-flex flex-column" style="width: 200px">
|
<div id="sidebar" class="position-relative pe-3 d-flex flex-column">
|
||||||
<SideBarMenu>
|
<SideBarMenu>
|
||||||
<template #header>Root note</template>
|
<template #header>Root note</template>
|
||||||
<template #items>
|
<template #items>
|
||||||
<SideBarMenuItem icon="house">{{
|
<SideBarMenuItem icon="house">{{ rootNote?.title }}</SideBarMenuItem>
|
||||||
rootNote?.title
|
|
||||||
}}</SideBarMenuItem>
|
|
||||||
</template>
|
</template>
|
||||||
</SideBarMenu>
|
</SideBarMenu>
|
||||||
<SideBarMenu>
|
<SideBarMenu>
|
||||||
<template #header>View mode</template>
|
<template #header>View mode</template>
|
||||||
<template #items>
|
<template #items>
|
||||||
<SideBarMenuItem v-for="viewMode in viewModes" :icon="viewMode.icon">{{
|
<SideBarMenuItem
|
||||||
viewMode.name
|
v-for="viewMode in props.viewModes"
|
||||||
}}</SideBarMenuItem>
|
:icon="viewMode.icon"
|
||||||
|
:active="viewMode.name === activeViewMode.name"
|
||||||
|
@click="emit('setViewMode', viewMode)"
|
||||||
|
>{{ viewMode.name }}</SideBarMenuItem
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
</SideBarMenu>
|
</SideBarMenu>
|
||||||
<SideBarMenu>
|
<SideBarMenu>
|
||||||
@@ -44,5 +44,6 @@ const viewModes: ViewMode[] = [
|
|||||||
#sidebar {
|
#sidebar {
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
width: $sidebar-width;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
icon?: string
|
icon?: string
|
||||||
|
active?: boolean
|
||||||
}>()
|
}>()
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<a class="text-opacity-50 text-decoration-none w-100 d-block link-secondary">
|
<a
|
||||||
|
class="text-opacity-50 text-decoration-none w-100 d-block"
|
||||||
|
:class="props.active ? 'link-primary fw-bolder' : 'link-secondary'"
|
||||||
|
>
|
||||||
<i :class="`bi bi-${props.icon}`" class="me-2" v-if="props.icon"></i
|
<i :class="`bi bi-${props.icon}`" class="me-2" v-if="props.icon"></i
|
||||||
><slot></slot>
|
><slot></slot>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -1,10 +1,30 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import Hamburger from './Hamburger.vue'
|
||||||
|
const props = defineProps<{
|
||||||
|
sideBarCollapsed: boolean
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'toggleSideBar'): void
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
|
id="topbar"
|
||||||
class="bg-primary position-absolute top-0 start-0 end-0"
|
class="bg-primary position-absolute top-0 start-0 end-0"
|
||||||
style="height: 50px"
|
style="height: 50px"
|
||||||
>
|
>
|
||||||
<div class="container g-3 h-100 d-flex align-items-center text-white">
|
<div class="container g-3 h-100 d-flex align-items-center text-white">
|
||||||
top bar
|
<Hamburger
|
||||||
|
class="me-3"
|
||||||
|
:side-bar-collapsed="props.sideBarCollapsed"
|
||||||
|
@toggle-side-bar="emit('toggleSideBar')"
|
||||||
|
/><span>Contexted</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<style scoped>
|
||||||
|
#topbar {
|
||||||
|
z-index: 500;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,15 +1,30 @@
|
|||||||
import { ref } from 'vue'
|
import { ref, computed, watch } from 'vue'
|
||||||
const notes = ref<Note[]>([])
|
import { useTitle } from '@vueuse/core'
|
||||||
|
|
||||||
export default function useNotes() {
|
export const notes = ref<Note[]>([])
|
||||||
const setDefaultNotes = (defaultNotes: Note[]) => {
|
|
||||||
notes.value = defaultNotes.map((note) => ({
|
export const activeNote = ref<Note>()
|
||||||
|
watch(activeNote, () => {
|
||||||
|
if (activeNote.value) useTitle(`${activeNote.value.title} | Contexted`)
|
||||||
|
})
|
||||||
|
|
||||||
|
export const rootNote = computed<Note | undefined>(() =>
|
||||||
|
notes.value.find((note: Note) => note.isRoot)
|
||||||
|
)
|
||||||
|
watch(
|
||||||
|
rootNote,
|
||||||
|
() => {
|
||||||
|
if (rootNote.value) activeNote.value = rootNote.value
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
export const setDefaultNotes = (defaultNotes: Note[]) => {
|
||||||
|
notes.value = defaultNotes.map(
|
||||||
|
(note): Note => ({
|
||||||
...note,
|
...note,
|
||||||
created: new Date().getTime(),
|
created: new Date().getTime(),
|
||||||
modified: new Date().getTime(),
|
modified: new Date().getTime(),
|
||||||
}))
|
})
|
||||||
}
|
)
|
||||||
const rootNote = notes.value.find((note) => note.isRoot)
|
|
||||||
|
|
||||||
return { notes, setDefaultNotes, rootNote }
|
|
||||||
}
|
}
|
||||||
|
|||||||
6
src/global.d.ts
vendored
6
src/global.d.ts
vendored
@@ -11,7 +11,11 @@ declare global {
|
|||||||
to: string[]
|
to: string[]
|
||||||
from: string[]
|
from: string[]
|
||||||
}
|
}
|
||||||
isRoot?: boolean
|
}
|
||||||
|
|
||||||
|
interface ViewMode {
|
||||||
|
name: string
|
||||||
|
icon: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export {}
|
export {}
|
||||||
|
|||||||
@@ -2,9 +2,8 @@ import { createApp } from 'vue'
|
|||||||
import './assets/style.scss'
|
import './assets/style.scss'
|
||||||
import 'bootstrap-icons/font/bootstrap-icons.css'
|
import 'bootstrap-icons/font/bootstrap-icons.css'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import useNotes from './composables/useNotes'
|
import { setDefaultNotes } from './composables/useNotes'
|
||||||
import { defaultNotes } from './utils/defaultNotes'
|
import { defaultNotes } from './utils/defaultNotes'
|
||||||
const { setDefaultNotes } = useNotes()
|
|
||||||
setDefaultNotes(defaultNotes)
|
setDefaultNotes(defaultNotes)
|
||||||
|
|
||||||
createApp(App).mount('#app')
|
createApp(App).mount('#app')
|
||||||
|
|||||||
@@ -4,4 +4,13 @@ import vue from '@vitejs/plugin-vue'
|
|||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [vue()],
|
plugins: [vue()],
|
||||||
|
css: {
|
||||||
|
preprocessorOptions: {
|
||||||
|
scss: {
|
||||||
|
additionalData: `
|
||||||
|
@import "./src/assets/_variables.scss";
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user