Skip to content

Commit e9c4eaf

Browse files
committed
Merge branch 'feature/constructor-options'
2 parents 8692e8c + 04eec48 commit e9c4eaf

38 files changed

+11618
-11007
lines changed

.eslintrc.json

+74-3
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,79 @@
1313
"ecmaVersion": 13,
1414
"sourceType": "module"
1515
},
16-
"rules": {},
17-
"overrides": [
16+
"rules": {
17+
"import/no-unused-modules": [
18+
1,
19+
20+
{
21+
"unusedExports": true,
22+
"src": ["./src"]
23+
}
24+
],
25+
26+
"import/no-unresolved": [2, {}],
27+
28+
"jsdoc/check-access": 1, // Recommended
29+
"jsdoc/check-alignment": 1, // Recommended
30+
// "jsdoc/check-examples": 1,
31+
"jsdoc/check-indentation": 1,
32+
"jsdoc/check-line-alignment": 1,
33+
"jsdoc/check-param-names": 1, // Recommended
34+
"jsdoc/check-property-names": 1, // Recommended
35+
"jsdoc/check-syntax": 1,
36+
"jsdoc/check-tag-names": 1, // Recommended
37+
"jsdoc/check-types": 1, // Recommended
38+
"jsdoc/check-values": 1, // Recommended
39+
"jsdoc/empty-tags": 1, // Recommended
40+
"jsdoc/implements-on-classes": 1, // Recommended
41+
"jsdoc/match-description": 1,
42+
"jsdoc/multiline-blocks": 1, // Recommended
43+
"jsdoc/newline-after-description": 1, // Recommended
44+
"jsdoc/no-bad-blocks": 1,
45+
"jsdoc/no-defaults": 1,
46+
// "jsdoc/no-missing-syntax": 1,
47+
"jsdoc/no-multi-asterisks": 1, // Recommended
48+
// "jsdoc/no-restricted-syntax": 1,
49+
// "jsdoc/no-types": 1,
50+
"jsdoc/no-undefined-types": 1, // Recommended
51+
"jsdoc/require-asterisk-prefix": 1,
52+
// "jsdoc/require-description": 1,
53+
"jsdoc/require-description-complete-sentence": 1,
54+
// "jsdoc/require-example": 1,
55+
// "jsdoc/require-file-overview": 1,
56+
"jsdoc/require-hyphen-before-param-description": 1,
57+
"jsdoc/require-jsdoc": 1, // Recommended
58+
"jsdoc/require-param": 1, // Recommended
59+
"jsdoc/require-param-description": 1, // Recommended
60+
"jsdoc/require-param-name": 1, // Recommended
61+
"jsdoc/require-param-type": 1, // Recommended
62+
"jsdoc/require-property": 1, // Recommended
63+
"jsdoc/require-property-description": 1, // Recommended
64+
"jsdoc/require-property-name": 1, // Recommended
65+
"jsdoc/require-property-type": 1, // Recommended
66+
"jsdoc/require-returns": 1, // Recommended
67+
"jsdoc/require-returns-check": 1, // Recommended
68+
"jsdoc/require-returns-description": 1, // Recommended
69+
"jsdoc/require-returns-type": 1, // Recommended
70+
"jsdoc/require-throws": 1,
71+
"jsdoc/require-yields": 1, // Recommended
72+
"jsdoc/require-yields-check": 1, // Recommended
73+
"jsdoc/tag-lines": 1, // Recommended
74+
"jsdoc/valid-types": 1 // Recommended
75+
},
76+
"overrides": [{
77+
"files": [
78+
"./*.js"
79+
],
80+
"env": {
81+
"node": true
82+
},
83+
"settings": {
84+
"import/resolver": {
85+
"node": {}
86+
}
87+
}
88+
},
1889
{
1990
"files": [
2091
"*.spec.js"
@@ -25,6 +96,6 @@
2596
"rules": {
2697
"no-unused-expressions": "off"
2798
}
28-
}
99+
}
29100
]
30101
}

.vscode/launch.json

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"type": "node",
6+
"request": "launch",
7+
"name": "unit tests",
8+
"program": "${workspaceFolder}/node_modules/.bin/mocha",
9+
"args": [
10+
"--colors",
11+
"--experimental-specifier-resolution=node",
12+
"${workspaceFolder}/test/unit/*.spec.*",
13+
],
14+
"internalConsoleOptions": "openOnSessionStart",
15+
"skipFiles": [
16+
"<node_internals>/**"
17+
]
18+
},
19+
{
20+
"type": "node",
21+
"request": "launch",
22+
"name": "e2e tests",
23+
"program": "${workspaceFolder}/node_modules/.bin/mocha",
24+
"args": [
25+
"--colors",
26+
"--experimental-specifier-resolution=node",
27+
"${workspaceFolder}/test/e2e/*.spec.*",
28+
],
29+
"internalConsoleOptions": "openOnSessionStart",
30+
"skipFiles": [
31+
"<node_internals>/**"
32+
]
33+
},
34+
]
35+
}

.vscode/settings.json

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
{
2-
"eslint.validate": [
3-
"javascript"
4-
],
2+
"eslint.validate": ["javascript"],
3+
"editor.formatOnSave": true,
54
"editor.codeActionsOnSave": {
65
"source.fixAll.eslint": true
76
},
8-
}
7+
"eslint.format.enable": true,
8+
"eslint.alwaysShowStatus": true,
9+
}

LICENSE.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2021 Daniele Fioroni
3+
Copyright (c) 2022 Daniele Fioroni
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

+66-57
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@ A small (~4K gzipped) unobtrusive script aimed to encourage a **CSS-first** appr
1515
![with scrollbar gap compensation](https://github.com/memob0x/scroll-padlock/blob/master/docs/with-gap-compensation.gif?raw=true)
1616

1717
## Try it out
18+
1819
Here's some example projects for the most common setups:
1920

20-
* React ([Preview](https://vouoz.csb.app/) - [Browse](https://codesandbox.io/s/scroll-padlock-react-vouoz))
21-
* Angular ([Preview](https://xuudg.csb.app/) - [Browse](https://codesandbox.io/s/scroll-padlock-angular-xuudg))
22-
* Vue ([Preview](https://6ewti.csb.app/) - [Browse](https://codesandbox.io/s/scroll-padlock-vue-6ewti))
23-
* Vanilla ([Preview](https://rgzrb.csb.app/) - [Browse](https://codesandbox.io/s/scroll-padlock-vanilla-rgzrb))
21+
- React ([Preview](https://vouoz.csb.app/) - [Browse](https://codesandbox.io/s/scroll-padlock-react-vouoz))
22+
- Angular ([Preview](https://xuudg.csb.app/) - [Browse](https://codesandbox.io/s/scroll-padlock-angular-xuudg))
23+
- Vue ([Preview](https://6ewti.csb.app/) - [Browse](https://codesandbox.io/s/scroll-padlock-vue-6ewti))
24+
- Vanilla ([Preview](https://rgzrb.csb.app/) - [Browse](https://codesandbox.io/s/scroll-padlock-vanilla-rgzrb))
2425

2526
## Inclusion
2627

@@ -34,27 +35,30 @@ The source code is entirely written in [standard ECMAScript](https://tc39.es/) w
3435
All major budle formats are supported, including [umd](https://github.com/umdjs/umd), [iife](https://developer.mozilla.org/en-US/docs/Glossary/IIFE), [amd](https://en.wikipedia.org/wiki/Asynchronous_module_definition), [cjs](https://en.wikipedia.org/wiki/CommonJS), [esm](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) and [SystemJS](https://github.com/systemjs/systemjs); also, a minified version and a transpiled version through babel are available for each of those.
3536

3637
### Node:
38+
3739
```javascript
38-
import ScrollPadlock from 'scroll-padlock/dist/es/scroll-padlock.js';
40+
import ScrollPadlock from "scroll-padlock/dist/es/scroll-padlock.js";
3941

4042
const scrollPadlock = new ScrollPadlock();
4143
```
4244

4345
### Browser (modules):
46+
4447
```html
4548
<script type="module">
46-
import ScrollPadlock from 'path/to/scroll-padlock/dist/es/scroll-padlock.min.js';
49+
import ScrollPadlock from "path/to/scroll-padlock/dist/es/scroll-padlock.min.js";
4750
48-
const scrollPadlock = new ScrollPadlock();
51+
const scrollPadlock = new ScrollPadlock();
4952
</script>
5053
```
5154

5255
### Browser (globals):
56+
5357
```html
5458
<script src="path/to/scroll-padlock/dist/iife/scroll-padlock.min.js"></script>
5559

5660
<script>
57-
var scrollPadlock = new ScrollPadlock();
61+
var scrollPadlock = new ScrollPadlock();
5862
</script>
5963
```
6064

@@ -68,13 +72,16 @@ An instance requires the **html element** which scroll needs to be controlled an
6872

6973
```javascript
7074
// The css class with the rules that would lock the page scroll
71-
const SCROLL_LOCKED_CSS_CLASS_NAME = 'your-locked-class';
75+
const SCROLL_LOCKED_CSS_CLASS_NAME = "your-locked-class";
7276

7377
// The element which scroll state needs to be controlled
7478
const { documentElement } = document;
7579

7680
// Creates the instance
77-
const instance = new ScrollPadlock(documentElement, SCROLL_LOCKED_CSS_CLASS_NAME);
81+
const instance = new ScrollPadlock(
82+
documentElement,
83+
SCROLL_LOCKED_CSS_CLASS_NAME
84+
);
7885
```
7986

8087
At this point, the lock state can be changed simply **toggling that CSS class**; since the CSS class change is internally observed, the class change itself can be done through native DOM API, a virtual DOM library, another DOM manipulation script, etc...
@@ -88,21 +95,22 @@ classList.add(SCROLL_LOCKED_CSS_CLASS_NAME);
8895
// Unlocks the body scroll
8996
classList.remove(SCROLL_LOCKED_CSS_CLASS_NAME);
9097
```
98+
9199
## CSS Rules Examples
92100

93101
The following ruleset alone is enough to ensure a cross-browser body scroll lock for a standard vertical-scroll page:
94102

95103
```css
96104
html.your-locked-class {
97-
/* Position-fixed hack, locks iOS too */
98-
position: fixed;
99-
width: 100%;
105+
/* Position-fixed hack, locks iOS too */
106+
position: fixed;
107+
width: 100%;
100108

101-
/* Avoids scroll to top */
102-
top: calc(var(--scroll-padlock-scroll-top) * -1);
109+
/* Avoids scroll to top */
110+
top: calc(var(--scroll-padlock-scroll-top) * -1);
103111

104-
/* Reserves space for scrollbar */
105-
padding-right: var(--scroll-padlock-scrollbar-width);
112+
/* Reserves space for scrollbar */
113+
padding-right: var(--scroll-padlock-scrollbar-width);
106114
}
107115
```
108116

@@ -111,42 +119,42 @@ Some [browser recognition logic](https://gist.github.com/memob0x/0869e759887441b
111119
```css
112120
/* iOS only */
113121
html.your-locked-class.ios {
114-
/* iOS fixed position hack */
115-
position: fixed;
116-
width: 100%;
122+
/* iOS fixed position hack */
123+
position: fixed;
124+
width: 100%;
117125

118-
/* Avoids scroll to top */
119-
top: calc(var(--scroll-padlock-scroll-top) * -1);
126+
/* Avoids scroll to top */
127+
top: calc(var(--scroll-padlock-scroll-top) * -1);
120128
}
121129

122130
/* Standard browsers only */
123131
html.your-locked-class.not-ios,
124132
html.your-locked-class.not-ios body {
125-
/* Standard way to lock scroll */
126-
overflow: hidden;
133+
/* Standard way to lock scroll */
134+
overflow: hidden;
127135
}
128136

129137
html.your-locked-class.not-ios body {
130-
/* Reserves space for scrollbar */
131-
/* (iOS has overlay scrollbars, this rule would have no effect there anyway) */
132-
padding-right: var(--scroll-padlock-scrollbar-width);
138+
/* Reserves space for scrollbar */
139+
/* (iOS has overlay scrollbars, this rule would have no effect there anyway) */
140+
padding-right: var(--scroll-padlock-scrollbar-width);
133141
}
134142
```
135143

136144
## CSS Variables
137145

138146
This is the complete list of CSS variables set by this library on the given elements.
139147

140-
* `--scroll-padlock-scroll-top`: the number of pixels that the target is scrolled vertically.
141-
* `--scroll-padlock-scroll-left`: the number of pixels that the target is scrolled horizontally.
142-
* `--scroll-padlock-scrollbar-width`: the target's vertical scrollbar size.
143-
* `--scroll-padlock-scrollbar-height`: the target's horizontal scrollbar size.
144-
* `--scroll-padlock-outer-width`: the target's width including the scrollbar size.
145-
* `--scroll-padlock-outer-height`: the target's height including the scrollbar size.
146-
* `--scroll-padlock-inner-width`: the target's width without the scrollbar size.
147-
* `--scroll-padlock-inner-height`: the target's height without the scrollbar size.
148-
* `--scroll-padlock-scroll-width`: the target's content width.
149-
* `--scroll-padlock-scroll-height`: the target's content height.
148+
- `--scroll-padlock-scroll-top`: the number of pixels that the target is scrolled vertically.
149+
- `--scroll-padlock-scroll-left`: the number of pixels that the target is scrolled horizontally.
150+
- `--scroll-padlock-scrollbar-width`: the target's vertical scrollbar size.
151+
- `--scroll-padlock-scrollbar-height`: the target's horizontal scrollbar size.
152+
- `--scroll-padlock-outer-width`: the target's width including the scrollbar size.
153+
- `--scroll-padlock-outer-height`: the target's height including the scrollbar size.
154+
- `--scroll-padlock-inner-width`: the target's width without the scrollbar size.
155+
- `--scroll-padlock-inner-height`: the target's height without the scrollbar size.
156+
- `--scroll-padlock-scroll-width`: the target's content width.
157+
- `--scroll-padlock-scroll-height`: the target's content height.
150158

151159
## API
152160

@@ -174,21 +182,21 @@ instance.scroll = { top, left };
174182

175183
// Gets the current instance element layout sizes
176184
const {
177-
// The target's width and height including the scrollbar size
178-
outerWidth,
179-
outerHeight,
185+
// The target's width and height including the scrollbar size
186+
outerWidth,
187+
outerHeight,
180188

181-
// The target's width and height without the scrollbar size
182-
innerWidth,
183-
innerHeight,
189+
// The target's width and height without the scrollbar size
190+
innerWidth,
191+
innerHeight,
184192

185-
// The target's content width and height
186-
scrollWidth,
187-
scrollHeight,
193+
// The target's content width and height
194+
scrollWidth,
195+
scrollHeight,
188196

189-
// The target's vertical and horizontal scrollbar size
190-
scrollbarWidth,
191-
scrollbarHeight
197+
// The target's vertical and horizontal scrollbar size
198+
scrollbarWidth,
199+
scrollbarHeight,
192200
} = instanse.layout;
193201
```
194202

@@ -212,20 +220,20 @@ If positioned elements "jumps" on a parent lock state change, the same CSS varia
212220
```css
213221
/* A right-positioned child */
214222
.positioned-element {
215-
position: fixed;
216-
right: 0;
223+
position: fixed;
224+
right: 0;
217225
}
218226

219227
/* The same right-positioned element, */
220228
/* not affected by its own container scrollbars disappearance */
221229
.your-locked-class .positioned-element {
222-
right: var(--scroll-padlock-scrollbar-width);
230+
right: var(--scroll-padlock-scrollbar-width);
223231
}
224232
```
225233

226234
## iOS Bars and Keyboard Tray
227235

228-
There might still be an iOS edge case when locking body scroll with _position: fixed_ technique.
236+
There might still be an iOS edge case when locking body scroll with _position: fixed_ technique.
229237

230238
When the page is scrolled the **system bars** become smaller; at that point, when focusing an input element programmatically, the keyboard tray is triggered and the bars become larger again; that, probably when some animations are taking place, can cause the following visual artifacts.
231239

@@ -243,12 +251,13 @@ const isIOS = someWayToDetectAppleIOS();
243251
// on an a form field make the keyboard tray to show
244252
// and that triggers, along with the visual artifact itself, a "resize" event
245253
window.addEventListener("resize", () => {
246-
if (isIOS && classList.contains(SCROLL_LOCKED_CSS_CLASS_NAME)) {
247-
// "Re-aligns" the iOS keyboard sub-window
248-
window.scrollTo(0, 0);
249-
}
254+
if (isIOS && classList.contains(SCROLL_LOCKED_CSS_CLASS_NAME)) {
255+
// "Re-aligns" the iOS keyboard sub-window
256+
window.scrollTo(0, 0);
257+
}
250258
});
251259
```
260+
252261
The problem should be solved at this point.
253262

254263
![ios bug](https://github.com/memob0x/scroll-padlock/blob/master/docs/ios-fix.gif?raw=true)

0 commit comments

Comments
 (0)