create a draft navigation
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="app\" />
|
||||
<Folder Include="src\utils\" />
|
||||
<Folder Include="src\views\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
+38
-2
@@ -1,11 +1,47 @@
|
||||
<template>
|
||||
<aside class="sidebar">
|
||||
<aside class="menu">
|
||||
<img class="logo" src="/just.svg" :alt="$t('app.name')" />
|
||||
<nav class="navigation">
|
||||
<navigation-item name="Shopping" symbol="ListTodo" :active="true" :count="7" />
|
||||
<navigation-item name="Work" symbol="ListTodo" :count="702" />
|
||||
<navigation-item name="Apartment" symbol="ListTodo" />
|
||||
<navigation-item name="Add a list" symbol="ListPlus" :minor="true" />
|
||||
</nav>
|
||||
<div class="menu-bottom">
|
||||
<navigation-item name="Settings" symbol="Bolt" :minor="true" />
|
||||
</div>
|
||||
</aside>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import NavigationItem from '@/components/navigation-item.vue';
|
||||
import { posts } from '@/db';
|
||||
|
||||
let items = posts.find().fetch();
|
||||
console.info(items);
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.menu
|
||||
{
|
||||
width: 260px;
|
||||
margin: 10px;
|
||||
border-radius: 8px;
|
||||
background: var(--color-menu-bg);
|
||||
height: calc(100vh - 20px);
|
||||
overflow-y: auto;
|
||||
padding: 16px;
|
||||
display: grid;
|
||||
grid-template-rows: auto minmax(0, 1fr) auto;
|
||||
}
|
||||
|
||||
.logo
|
||||
{
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.navigation
|
||||
{
|
||||
margin-top: 12px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,7 @@
|
||||
import { type App } from 'vue';
|
||||
import uiIcon from './ui-icon.vue';
|
||||
|
||||
export function createComponents (app: App)
|
||||
{
|
||||
app.component('ui-icon', uiIcon);
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<template>
|
||||
<button type="button" class="navigation-item" :class="classes">
|
||||
<ui-icon :symbol="symbol" class="navigation-item-icon" />
|
||||
<span class="navigation-item-text" v-text="name"></span>
|
||||
<span class="navigation-item-count" v-if="count > 0" v-text="count"></span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive } from 'vue'
|
||||
|
||||
interface Props {
|
||||
symbol: string,
|
||||
name: string,
|
||||
count?: number,
|
||||
active?: boolean,
|
||||
minor?: boolean
|
||||
}
|
||||
|
||||
const { symbol, name, count = 0, active, minor } = defineProps<Props>();
|
||||
|
||||
const classes = reactive({
|
||||
'is-active': active,
|
||||
'is-list': !minor
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.navigation-item
|
||||
{
|
||||
appearance: none;
|
||||
height: 38px;
|
||||
border-radius: 6px;
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, auto) 1fr;
|
||||
text-decoration: none;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
background: transparent;
|
||||
padding: 0 12px;
|
||||
width: 100%;
|
||||
border: 1px solid transparent;
|
||||
cursor: pointer;
|
||||
//transition: background-color 0.2s ease;
|
||||
|
||||
&.is-active, &:hover
|
||||
{
|
||||
background: var(--color-menu-item-hover-bg);
|
||||
|
||||
.navigation-item-count
|
||||
{
|
||||
background: var(--color-menu-item-hover-count-bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.navigation:has(.navigation-item:not(.is-active):hover)
|
||||
{
|
||||
.navigation-item.is-active
|
||||
{
|
||||
background: transparent;
|
||||
}
|
||||
.navigation-item.is-active .navigation-item-count
|
||||
{
|
||||
background: var(--color-menu-item-count-bg);
|
||||
}
|
||||
}
|
||||
|
||||
.navigation-item-icon
|
||||
{
|
||||
height: 20px;
|
||||
stroke-width: 1.5px;
|
||||
color: var(--color-text-dim);
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.navigation-item-text
|
||||
{
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
color: var(--color-text-dim);
|
||||
|
||||
.navigation-item.is-list &
|
||||
{
|
||||
font-weight: 500;
|
||||
color: var(--color-text);
|
||||
}
|
||||
}
|
||||
|
||||
.navigation-item-count
|
||||
{
|
||||
height: 16px;
|
||||
justify-self: start;
|
||||
min-width: 16px;
|
||||
padding: 0 6px;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 8px;
|
||||
font-size: 0.6em;
|
||||
background: var(--color-menu-item-count-bg);
|
||||
color: var(--color-text-dim);
|
||||
//transition: background-color 0.2s ease;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<component
|
||||
:is="icon"
|
||||
:size="size"
|
||||
:color="color"
|
||||
:stroke-width="strokeWidth" :default-class="defaultClass"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import * as icons from "lucide-vue-next";
|
||||
|
||||
const props = defineProps({
|
||||
symbol: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
size: Number,
|
||||
color: String,
|
||||
strokeWidth: Number,
|
||||
defaultClass: String
|
||||
})
|
||||
|
||||
const icon = computed(() => icons[props.symbol]);
|
||||
</script>
|
||||
@@ -1,6 +1,7 @@
|
||||
import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import { createComponents } from '@/components'
|
||||
|
||||
import './styles/styles.scss'
|
||||
import App from './App.vue'
|
||||
@@ -8,6 +9,7 @@ import App from './App.vue'
|
||||
import en_translations from './locales/en.json'
|
||||
const app = createApp(App)
|
||||
|
||||
createComponents(app)
|
||||
app.use(createPinia())
|
||||
app.use(createI18n<[typeof en_translations], 'en'>({
|
||||
locale: 'en',
|
||||
|
||||
@@ -11,7 +11,7 @@ body
|
||||
{
|
||||
color: var(--color-text);
|
||||
font-family: 'inter', sans-serif;
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
background: var(--color-layout-bg);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,14 @@
|
||||
--color-layout-icons-fg: var(--color-fg-shade-3);
|
||||
--color-layout-icons-hover-fg: var(--color-fg-shade-2);
|
||||
|
||||
// menu shades
|
||||
--color-menu-bg: var(--color-bg-shade-3);
|
||||
--color-menu-item-hover-bg: var(--color-bg-shade-4);
|
||||
--color-menu-item-count-bg: var(--color-bg-shade-4);
|
||||
--color-menu-item-hover-count-bg: var(--color-bg-shade-5);
|
||||
|
||||
// general text shades
|
||||
--color-text: var(--color-fg-shade-1);
|
||||
--color-text-dim: var(--color-fg-shade-2);
|
||||
--color-text-dim-one: var(--color-fg-shade-3);
|
||||
}
|
||||
+2
-2
@@ -7,8 +7,8 @@ import vueDevTools from 'vite-plugin-vue-devtools'
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
vue()
|
||||
//vueDevTools(),
|
||||
vue(),
|
||||
//vueDevTools()
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
|
||||
Reference in New Issue
Block a user