From 26ba717d10b18183f44e334706a61ddbafc6e29a Mon Sep 17 00:00:00 2001 From: Sayiddd Date: Sat, 4 Apr 2026 10:45:44 +0700 Subject: [PATCH 1/4] Added useScrollbarWidth composable Added composable & provider and injector for accessing scrollbar width --- src/composables/useScrollbarWidth.ts | 38 ++++++++++++++++++++++++++++ src/keys/scroll.ts | 7 +++++ src/layouts/default.vue | 17 ++++++++++--- src/pages/index.vue | 15 ++++++++++- 4 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 src/composables/useScrollbarWidth.ts diff --git a/src/composables/useScrollbarWidth.ts b/src/composables/useScrollbarWidth.ts new file mode 100644 index 0000000..18e3073 --- /dev/null +++ b/src/composables/useScrollbarWidth.ts @@ -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, +): Ref { + const scrollbarWidth = ref(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 +} diff --git a/src/keys/scroll.ts b/src/keys/scroll.ts index 14ebb46..c990784 100644 --- a/src/keys/scroll.ts +++ b/src/keys/scroll.ts @@ -1,3 +1,10 @@ import type { UseScrollReturn } from '@vueuse/core' +interface ScrollbarWidthCtx { + // uses MaybeRef for injector default value + scrollbarWidth: MaybeRef + setScrollbarWidth: (value: number) => void +} + export const scrollKey: InjectionKey = Symbol('kei-chan is injecting scrolling') +export const scrollbarWidthKey: InjectionKey = Symbol('kei-chan is injecting scrollbar width') diff --git a/src/layouts/default.vue b/src/layouts/default.vue index 3ffd7cf..4e70718 100644 --- a/src/layouts/default.vue +++ b/src/layouts/default.vue @@ -1,16 +1,17 @@