File tree 8 files changed +165
-0
lines changed
functions/useScrollbarWidth
8 files changed +165
-0
lines changed Original file line number Diff line number Diff line change @@ -92,6 +92,8 @@ Vue.use(VueCompositionAPI)
92
92
[ ![ Demo] ( https://img.shields.io/badge/demo-🚀-yellow.svg )] ( https://microcipcip.github.io/vue-use-kit/?path=/story/sensors-usesize--demo )
93
93
- [ ` useScroll ` ] ( ./src/functions/useScroll/stories/useScroll.md ) &mdash ; tracks an HTML element's scroll position.
94
94
[ ![ Demo] ( https://img.shields.io/badge/demo-🚀-yellow.svg )] ( https://microcipcip.github.io/vue-use-kit/?path=/story/sensors-usescroll--demo )
95
+ - [ ` useScrollbarWidth ` ] ( ./src/functions/useScrollbarWidth/stories/useScrollbarWidth.md ) &mdash ; gets current browser's scrollbar width.
96
+ [ ![ Demo] ( https://img.shields.io/badge/demo-🚀-yellow.svg )] ( https://microcipcip.github.io/vue-use-kit/?path=/story/sensors-usescrollbarwidth--demo )
95
97
- [ ` useSearchParams ` ] ( ./src/functions/useSearchParams/stories/useSearchParams.md ) &mdash ; tracks browser's location search params.
96
98
[ ![ Demo] ( https://img.shields.io/badge/demo-🚀-yellow.svg )] ( https://microcipcip.github.io/vue-use-kit/?path=/story/sensors-usesearchparams--demo )
97
99
- [ ` useWindowSize ` ] ( ./src/functions/useWindowSize/stories/useWindowSize.md ) &mdash ; tracks ` Window ` scroll position.
Original file line number Diff line number Diff line change
1
+ export * from './useScrollbarWidth'
Original file line number Diff line number Diff line change
1
+ <template >
2
+ <table class =" table is-fullwidth" >
3
+ <thead >
4
+ <tr >
5
+ <th >Prop</th >
6
+ <th >Value</th >
7
+ </tr >
8
+ </thead >
9
+ <tbody >
10
+ <tr >
11
+ <td >scrollbarWidth</td >
12
+ <td >{{ scrollbarWidth }}px</td >
13
+ </tr >
14
+ </tbody >
15
+ </table >
16
+ </template >
17
+
18
+ <script lang="ts">
19
+ import Vue from ' vue'
20
+ import { useScrollbarWidth } from ' @src/vue-use-kit'
21
+
22
+ export default Vue .extend ({
23
+ name: ' UseScrollbarWidthDemo' ,
24
+ setup() {
25
+ const { scrollbarWidth } = useScrollbarWidth ()
26
+ return { scrollbarWidth }
27
+ }
28
+ })
29
+ </script >
Original file line number Diff line number Diff line change
1
+ # useScrollbarWidth
2
+
3
+ Vue function that gets current browser's scrollbar width.
4
+
5
+ ## Reference
6
+
7
+ ``` typescript
8
+ function useScrollbarWidth(
9
+ runOnMount ? : boolean
10
+ ): {
11
+ scrollbarWidth: Ref <number >
12
+ getScrollbarWidth: () => void
13
+ }
14
+ ```
15
+
16
+ ### Parameters
17
+
18
+ - ` runOnMount: boolean ` whether to get scrollbar width on mount, ` true ` by default
19
+
20
+ ### Returns
21
+
22
+ - ` scrollbarWidth: Ref<number> ` the scrollbar width
23
+ - ` getScrollbarWidth: Function ` the function to call to get the scrollbar width
24
+
25
+ ## Usage
26
+
27
+ ``` html
28
+ <template >
29
+ <div >
30
+ scrollbarWidth: {{ scrollbarWidth }}px
31
+ </div >
32
+ </template >
33
+
34
+ <script lang =" ts" >
35
+ import Vue from ' vue'
36
+ import { useScrollbarWidth } from ' vue-use-kit'
37
+
38
+ export default Vue .extend ({
39
+ name: ' UseScrollbarWidthDemo' ,
40
+ setup () {
41
+ const { scrollbarWidth } = useScrollbarWidth ()
42
+ return { scrollbarWidth }
43
+ }
44
+ })
45
+ </script >
46
+ ```
Original file line number Diff line number Diff line change
1
+ import { storiesOf } from '@storybook/vue'
2
+ import path from 'path'
3
+ import StoryTitle from '@src/helpers/StoryTitle.vue'
4
+ import UseScrollbarWidthDemo from './UseScrollbarWidthDemo.vue'
5
+
6
+ const functionName = 'useScrollbarWidth'
7
+ const functionPath = path . resolve ( __dirname , '..' )
8
+ const notes = require ( `./${ functionName } .md` ) . default
9
+
10
+ const basicDemo = ( ) => ( {
11
+ components : { StoryTitle, demo : UseScrollbarWidthDemo } ,
12
+ template : `
13
+ <div class="container">
14
+ <story-title
15
+ function-path="${ functionPath } "
16
+ source-name="${ functionName } "
17
+ demo-name="UseScrollbarWidthDemo.vue"
18
+ >
19
+ <template v-slot:title></template>
20
+ <template v-slot:intro></template>
21
+ </story-title>
22
+ <demo />
23
+ </div>`
24
+ } )
25
+
26
+ storiesOf ( 'sensors|useScrollbarWidth' , module )
27
+ . addParameters ( { notes } )
28
+ . add ( 'Demo' , basicDemo )
Original file line number Diff line number Diff line change
1
+ import { mount } from '@src/helpers/test'
2
+ import { useScrollbarWidth } from '@src/vue-use-kit'
3
+
4
+ afterEach ( ( ) => {
5
+ jest . clearAllMocks ( )
6
+ } )
7
+
8
+ const testComponent = ( onMount = true ) => ( {
9
+ template : `
10
+ <div>
11
+ <div id="scrollbarWidth">{{ scrollbarWidth }}</div>
12
+ <button id="getScrollbarWidth" @click="getScrollbarWidth"></button>
13
+ </div>
14
+ ` ,
15
+ setup ( ) {
16
+ const { scrollbarWidth, getScrollbarWidth } = useScrollbarWidth ( onMount )
17
+ return { scrollbarWidth, getScrollbarWidth }
18
+ }
19
+ } )
20
+
21
+ describe ( 'useScrollbarWidth' , ( ) => {
22
+ it ( 'should return a scrollbarWidth as a numeric value' , async ( ) => {
23
+ const wrapper = mount ( testComponent ( ) )
24
+ await wrapper . vm . $nextTick ( )
25
+ expect ( wrapper . find ( '#scrollbarWidth' ) . text ( ) ) . toBe ( '0' )
26
+ } )
27
+ } )
Original file line number Diff line number Diff line change
1
+ import { ref , onMounted , Ref } from '@src/api'
2
+
3
+ export function useScrollbarWidth ( runOnMount = true ) {
4
+ const scrollbarWidth = ref ( 0 )
5
+
6
+ const getScrollbarWidth = ( ) => {
7
+ // https://stackoverflow.com/a/13382873/974107
8
+ // Creating invisible container
9
+ const outer = document . createElement ( 'div' )
10
+ outer . style . visibility = 'hidden'
11
+ outer . style . overflow = 'scroll' // forcing scrollbar to appear
12
+ outer . style . msOverflowStyle = 'scrollbar' // needed for WinJS apps
13
+ document . body . appendChild ( outer )
14
+
15
+ // Creating inner element and placing it in the container
16
+ const inner = document . createElement ( 'div' )
17
+ outer . appendChild ( inner )
18
+
19
+ // Calculating difference between container's full width and the child width
20
+ const scrollbarWidthValue = outer . offsetWidth - inner . offsetWidth
21
+
22
+ // Removing temporary elements from the DOM
23
+ if ( outer . parentNode ) outer . parentNode . removeChild ( outer )
24
+
25
+ scrollbarWidth . value = scrollbarWidthValue
26
+ }
27
+
28
+ onMounted ( ( ) => runOnMount && getScrollbarWidth ( ) )
29
+
30
+ return { scrollbarWidth, getScrollbarWidth }
31
+ }
Original file line number Diff line number Diff line change @@ -18,6 +18,7 @@ export * from './functions/useOrientation'
18
18
export * from './functions/useSize'
19
19
export * from './functions/useSearchParams'
20
20
export * from './functions/useScroll'
21
+ export * from './functions/useScrollbarWidth'
21
22
export * from './functions/useWindowSize'
22
23
// Animations
23
24
export * from './functions/useIntervalFn'
You can’t perform that action at this time.
0 commit comments