Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ node_modules
.idea/
*.log
public/assets/fonts
/.vscode/
13 changes: 13 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"recommendations": [
"antfu.iconify",
"antfu.unocss",
"antfu.vite",
"antfu.goto-alias",
"csstools.postcss",
"dbaeumer.vscode-eslint",
"vue.volar",
"lokalise.i18n-ally",
"streetsidesoftware.code-spell-checker"
]
}
47 changes: 47 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"cSpell.words": ["Vite", "unocss", "vueuse", "vitejs"],
"i18n-ally.sourceLanguage": "en",
"i18n-ally.keystyle": "nested",
"i18n-ally.localesPaths": "locales",
"i18n-ally.sortKeys": true,

// Disable the default formatter
"prettier.enable": false,
"editor.formatOnSave": false,

// Auto fix
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.organizeImports": "never"
},

// Silent the stylistic rules in you IDE, but still auto fix them
"eslint.rules.customizations": [
{ "rule": "style/*", "severity": "off" },
{ "rule": "format/*", "severity": "off" },
{ "rule": "*-indent", "severity": "off" },
{ "rule": "*-spacing", "severity": "off" },
{ "rule": "*-spaces", "severity": "off" },
{ "rule": "*-order", "severity": "off" },
{ "rule": "*-dangle", "severity": "off" },
{ "rule": "*-newline", "severity": "off" },
{ "rule": "*quotes", "severity": "off" },
{ "rule": "*semi", "severity": "off" }
],

// The following is optional.
// It's better to put under project setting `.vscode/settings.json`
// to avoid conflicts with working with different eslint configs
// that does not support all formats.
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue",
"html",
"json",
"jsonc",
"yaml"
]
}
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
"@unocss/reset": "catalog:frontend",
"@vueuse/core": "catalog:frontend",
"nprogress": "catalog:frontend",
"pinia": "catalog:frontend",
"vue": "catalog:frontend",
"vue-i18n": "catalog:frontend",
"vue-router": "catalog:frontend"
Expand Down
29 changes: 0 additions & 29 deletions pnpm-lock.yaml

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

workflow is using frozen lockfile configuration

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion pnpm-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ catalogs:
'@unocss/reset': ^66.1.0-beta.7
'@vueuse/core': ^13.0.0
nprogress: ^0.2.0
pinia: ^3.0.1
vue: ^3.5.13
vue-i18n: ^11.1.2
vue-router: ^4.5.0
Expand Down
38 changes: 38 additions & 0 deletions src/composables/useScrollbarWidth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// source code: https://github.com/vueuse/vueuse/issues/4262
import type { Ref } from 'vue'
import { onMounted, onUnmounted, ref } from 'vue'

// Calculates scrollbar width for an HTML element reactively.
// This is needed for gutter layout happening on Chrome & Opera.
export default function useScrollbarWidth(
elementRef: Ref<HTMLElement | null>,
): Ref<number> {
const scrollbarWidth = ref<number>(0)
let resizeObserver: ResizeObserver

function calc() {
const scrollEl = elementRef.value!
scrollbarWidth.value = scrollEl.offsetWidth - scrollEl.clientWidth
}

onMounted(() => {
const element = elementRef.value!

// initial calculation
calc()

// recalculate whenever window size or zoom level changes
window.addEventListener('resize', calc, false)

// recalculate whenever element size changes
resizeObserver = new ResizeObserver(calc)
resizeObserver.observe(element)
})

onUnmounted(() => {
window.removeEventListener('resize', calc)
resizeObserver.disconnect()
})

return scrollbarWidth
}
7 changes: 7 additions & 0 deletions src/keys/scroll.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import type { UseScrollReturn } from '@vueuse/core'

interface ScrollbarWidthCtx {
// uses MaybeRef for injector default value
scrollbarWidth: MaybeRef<number>
setScrollbarWidth: (value: number) => void
}

export const scrollKey: InjectionKey<UseScrollReturn> = Symbol('kei-chan is injecting scrolling')
export const scrollbarWidthKey: InjectionKey<ScrollbarWidthCtx> = Symbol('kei-chan is injecting scrollbar width')
17 changes: 14 additions & 3 deletions src/layouts/default.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
<script setup lang="ts">
import type { UseScrollReturn } from '@vueuse/core'
import { scrollKey } from '~/keys/scroll'
import { scrollbarWidthKey, scrollKey } from '~/keys/scroll'
import { isSidebarOpenKey } from '~/keys/sidebar'

const route = useRoute()

const isInRoot = computed(() => route.path === '/')
const scrollbarWidth = ref(0)
const isSidebarOpen = ref(false)

// composable init
const el = useTemplateRef<HTMLElement>('scrollRef')
const scrollReturn: UseScrollReturn = useScroll(el)
provide(scrollKey, scrollReturn)

// composable won't work on the same level as initialization
const { arrivedState, measure } = scrollReturn
Expand All @@ -33,8 +34,18 @@ router.afterEach(() => {
})
*/

const isSidebarOpen = ref(false)
function setScrollbarWidth(value: number) {
scrollbarWidth.value = value
}

provide(scrollbarWidthKey, {
scrollbarWidth,
setScrollbarWidth,
})
provide(scrollKey, scrollReturn)
provide(isSidebarOpenKey, isSidebarOpen)

// TODO: match layout decor with browser scrollbar width, fix layout shifts, reset default scrollbar style
</script>

<template>
Expand Down
17 changes: 0 additions & 17 deletions src/modules/pinia.ts

This file was deleted.

15 changes: 14 additions & 1 deletion src/pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
<script setup lang="ts">
import useScrollbarWidth from '~/composables/useScrollbarWidth'
import { scrollbarWidthKey } from '~/keys/scroll'

const { t } = useI18n()

useHead({
title: () => t('button.home'),
})

const el = useTemplateRef('scrollRef')
const scrollbarWidth = useScrollbarWidth(el)
// great article https://gusiol.medium.com/typing-vue-inject-with-object-destructuring-f5a2b6067319
const { setScrollbarWidth } = inject(scrollbarWidthKey, {
scrollbarWidth: 0,
setScrollbarWidth: () => undefined,
})

onMounted(() => setScrollbarWidth(scrollbarWidth.value))
</script>

<template>
<div class="relative" overflow="x-hidden y-auto" h="full" snap="y mandatory">
<div ref="scrollRef" class="relative" overflow="x-hidden y-auto" h="full" snap="y mandatory">
<ScrollIndicator />
<IndexFirstSection />
<IndexSecondSection />
Expand Down
Loading