compare-images-slider 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,20 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - uses: actions/setup-node@v4
14
+ with:
15
+ node-version: 20
16
+ cache: npm
17
+ - run: npm ci --no-audit --no-fund
18
+ - run: npm run lint
19
+ - run: npm test
20
+ - run: npm run build
@@ -0,0 +1,39 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ contents: read
10
+ id-token: write # required for npm trusted publishing (OIDC)
11
+
12
+ jobs:
13
+ publish:
14
+ runs-on: ubuntu-latest
15
+
16
+ steps:
17
+ # Checkout the repository
18
+ - name: Checkout code
19
+ uses: actions/checkout@v6
20
+
21
+ # Set up Node.js
22
+ - name: Set up Node.js
23
+ uses: actions/setup-node@v6
24
+ with:
25
+ node-version: 24
26
+ cache: "npm"
27
+ registry-url: "https://registry.npmjs.org"
28
+
29
+ # Trusted publishing requires npm >= 11.5.1
30
+ - name: Update npm
31
+ run: npm install -g npm@latest
32
+
33
+ # Install dependencies
34
+ - name: Install dependencies
35
+ run: npm ci
36
+
37
+ # Publish to npm (auth via OIDC, provenance generated automatically)
38
+ - name: Publish
39
+ run: npm publish
package/README.md CHANGED
@@ -2,6 +2,25 @@
2
2
 
3
3
  A simple slider for comparing two images visually.
4
4
 
5
+ <img style="max-width: 100%" src="https://i.imgur.com/e9m4QaU.jpeg" alt="Compare Images Slider Screenshot">
6
+
7
+ ## Features
8
+
9
+ - Lightweight
10
+ - Minimal DOM depth
11
+ - No dependencies
12
+ - Mobile friendly
13
+ - Vertical slider
14
+ - Inertia physics with capped, natural-feeling flicks
15
+ - Bounce back
16
+ - Keyboard accessible ([W3C APG Window Splitter](https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/))
17
+ - Custom element, no shadow DOM
18
+ - Customizable via CSS
19
+
20
+ ## Demo
21
+
22
+ [Check out the demo](https://stamat.github.io/compare-images-slider/)
23
+
5
24
  ## Installation
6
25
 
7
26
  ```bash
@@ -12,16 +31,19 @@ or use the CDN:
12
31
 
13
32
  ```html
14
33
  <script src="https://unpkg.com/compare-images-slider/dist/compare-images-slider.min.js"></script>
15
- <link rel="stylesheet" href="https://unpkg.com/compare-images-slider/dist/compare-images-slider.min.css">
34
+ <link
35
+ rel="stylesheet"
36
+ href="https://unpkg.com/compare-images-slider/dist/compare-images-slider.min.css"
37
+ />
16
38
  ```
17
39
 
18
40
  ## Usage
19
41
 
20
42
  ```html
21
43
  <div class="js-compare-images-slider compare-images-slider">
22
- <img src="img.jpg" alt="">
44
+ <img src="img.jpg" alt="" />
23
45
  <div class="frame">
24
- <img src="img-alt.jpg" alt="">
46
+ <img src="img-alt.jpg" alt="" />
25
47
  </div>
26
48
  <span class="handle"></span>
27
49
  </div>
@@ -30,25 +52,50 @@ or use the CDN:
30
52
  **⚠️ Note:** Don't be lazy and please set the intrinsic dimensions of the images. This eliminates layout shifts and will ensure the slider works as expected.
31
53
 
32
54
  ```javascript
33
- import CompareImagesSlider from 'compare-images-slider';
55
+ import CompareImagesSlider from "compare-images-slider";
34
56
 
35
- const slider = document.querySelector('.js-compare-images-slider');
57
+ const slider = document.querySelector(".js-compare-images-slider");
36
58
  const compareImagesSlider = new CompareImagesSlider(slider);
37
59
  ```
38
60
 
39
61
  If you are loading the script asynchronously, you can listen for the `CompareImagesSliderLoaded` event to initialize the slider:
40
62
 
41
63
  ```javascript
42
- document.addEventListener('CompareImagesSliderLoaded', function() {
43
- const slider = document.querySelector('.js-compare-images-slider');
64
+ document.addEventListener("CompareImagesSliderLoaded", function () {
65
+ const slider = document.querySelector(".js-compare-images-slider");
44
66
  const compareImagesSlider = new CompareImagesSlider(slider);
45
67
  });
46
68
  ```
47
69
 
48
70
  ```scss
49
- @import 'node_modules/compare-images-slider/src/styles/index.scss';
71
+ @import "node_modules/compare-images-slider/src/styles/index.scss";
72
+ ```
73
+
74
+ ## Custom element
75
+
76
+ The same markup wrapped in a `<compare-images-slider>` tag upgrades itself — no
77
+ JavaScript call needed. It uses light DOM (no shadow root), so the images, frame
78
+ and handle stay fully stylable. Options are read from attributes (bare, `data-*`
79
+ or kebab-case):
80
+
81
+ ```html
82
+ <compare-images-slider inertia initial-position="35">
83
+ <img src="img.jpg" alt="" />
84
+ <div class="frame">
85
+ <img src="img-alt.jpg" alt="" />
86
+ </div>
87
+ <span class="handle"></span>
88
+ </compare-images-slider>
50
89
  ```
51
90
 
91
+ ## Accessibility
92
+
93
+ The handle is a focusable `role="separator"` implementing the
94
+ [W3C APG Window Splitter pattern](https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/)
95
+ with `aria-valuenow`/`min`/`max`, `aria-orientation` and `aria-controls`. Once
96
+ focused: arrow keys move by `step`, Page Up/Down by `pageStep`, Home/End jump to
97
+ the extremes, and double-click snaps to the nearest extreme.
98
+
52
99
  ## Options
53
100
 
54
101
  ```javascript
@@ -56,23 +103,43 @@ document.addEventListener('CompareImagesSliderLoaded', function() {
56
103
  const options = {
57
104
  inertia: false, // inertia physics, you can flick the handle
58
105
  friction: 0.9, // the friction of the inertia
59
- bounce: false, // will bounce back when intertia is enabled and the boundary is reached
106
+ bounce: false, // will bounce back when inertia is enabled and the boundary is reached
60
107
  bounceFactor: 0.1, // the force of the bounce
61
- vertical: false // vertical slider
62
- onlyHandle: true // only the handle is draggable
63
- }
108
+ maxFlickVelocity: 0.5, // cap on flick velocity (% per ms), tames hard flicks
109
+ vertical: false, // vertical slider
110
+ onlyHandle: true, // only the handle is draggable
111
+ initialPosition: 50, // starting position (0-100)
112
+ step: 5, // arrow-key step (percent)
113
+ pageStep: 25, // Page Up/Down step (percent)
114
+ };
64
115
 
65
116
  new CompareImagesSlider(slider, options);
66
117
  ```
67
118
 
68
- ## TODO:
119
+ Available attribute options (bare, `data-*` or kebab-case):
69
120
 
70
- - [x] Add options
71
- - [x] Scroll block on drag
72
- - [x] Vertical option
73
- - [ ] Add factory class, migrate the general factory class to the book of spells prior to that? Better turn this into custom element!
74
- - [x] Refactor onDrag and move it to the book of spells
75
- - [ ] Add initialized state, don't initialize twice
121
+ - `vertical` - vertical slider
122
+ - `inertia`, `bounce`, `only-handle` - booleans
123
+ - `friction`, `bounce-factor`, `max-flick-velocity`, `initial-position`, `step`, `page-step` - numbers
124
+
125
+ ```html
126
+ <div class="js-compare-images-slider compare-images-slider" vertical>
127
+ <img src="img.jpg" alt="" />
128
+ <div class="frame">
129
+ <img src="img-alt.jpg" alt="" />
130
+ </div>
131
+ <span class="handle"></span>
132
+ </div>
133
+ ```
134
+
135
+ ## Development
136
+
137
+ ```bash
138
+ npm install
139
+ npm test # unit tests (node:test)
140
+ npm run lint
141
+ npm run build
142
+ ```
76
143
 
77
144
  ---
78
145
 
@@ -0,0 +1,2 @@
1
+ /* compare-images-slider v1.0.2 | https://stamat.github.io/compare-images-slider/ | MIT License */
2
+ @charset "UTF-8";:root{--content-max: 46rem;--radius: .5rem;--font-body: "DM Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;--font-mono: "SFMono-Regular", "JetBrains Mono", Menlo, Consolas, monospace}:root,:root[data-theme=light]{--bg: #fff;--bg-alt: #f5f6f8;--bg-code: #f5f6f8;--fg: #1c2024;--fg-muted: #5b6570;--border: #e3e6ea;--accent: #7048e8;--accent-fg: #fff;--link: #6741d9;--shadow: 0 4px 20px rgb(20 24 30 / 8%)}:root[data-theme=dark]{--bg: #16181d;--bg-alt: #1d2026;--bg-code: #1d2026;--fg: #e4e7eb;--fg-muted: #98a1ad;--border: #2b2f36;--accent: #9775fa;--accent-fg: #16181d;--link: #b197fc;--shadow: 0 4px 20px rgb(0 0 0 / 40%)}*{box-sizing:border-box}body{margin:0;font-family:var(--font-body);background:var(--bg);color:var(--fg);line-height:1.65;-webkit-font-smoothing:antialiased}a{color:var(--link)}a:hover{text-decoration:none}:root{--topbar-h: 3.25rem}html{scroll-padding-top:calc(var(--topbar-h) + 1rem)}.topbar{position:sticky;top:0;z-index:40;height:var(--topbar-h);display:flex;align-items:center;gap:.75rem;padding:0 1rem;background:var(--bg);border-top:1px solid var(--border);border-bottom:1px solid var(--border)}.topbar a{text-decoration:none}.brand{font-weight:700;font-size:1.1rem;color:var(--fg);display:flex;align-items:center;gap:.4rem}.brand:hover{text-decoration:none}.brand-mark{font-size:1.3rem}.icon-btn{display:inline-flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;border:0;background:transparent;color:var(--fg-muted);cursor:pointer;border-radius:var(--radius);font-size:1.1rem}.icon-btn:hover{background:var(--bg-alt);color:var(--fg);text-decoration:none}.topbar-actions{display:flex;align-items:center;gap:.75rem;margin-left:auto}.topbar-links{display:flex;align-items:center;gap:1rem}.topbar-links:empty{display:none}.topbar-links a{color:var(--fg-muted);font-size:.9rem;font-weight:500}.topbar-links a:hover{color:var(--fg)}@media(max-width:40rem){.topbar-links{display:none}}.theme-sun{display:none}.theme-moon{display:inline}:root[data-theme=dark] .theme-sun{display:inline}:root[data-theme=dark] .theme-moon{display:none}.content{flex:1 1 auto;min-width:0;padding:2rem clamp(1rem,5vw,3rem) 4rem;display:flex;flex-direction:column;align-items:center}.page-footer{width:100%;max-width:var(--content-max);margin-top:3rem;padding-top:1.5rem;border-top:1px solid var(--border);color:var(--fg-muted);font-size:.85rem}.prose{width:100%;max-width:var(--content-max)}.prose a{text-decoration:underline}.prose a:hover{text-decoration:none}.prose h1,.prose h2,.prose h3,.prose h4{position:relative;line-height:1.25;scroll-margin-top:calc(var(--topbar-h, 0rem) + 1rem)}.prose h1{font-size:2rem;margin:0 0 1rem}.prose h2{font-size:1.5rem;margin:2.5rem 0 1rem;padding-bottom:.3rem;border-bottom:1px solid var(--border)}.prose h3{font-size:1.2rem;margin:2rem 0 .75rem}.heading-anchor{padding-left:.3em;color:var(--fg-muted);opacity:0;text-decoration:none!important}.heading-anchor:before{content:"#"}.prose :is(h1,h2,h3,h4):hover .heading-anchor,.heading-anchor:focus{opacity:1}.heading-anchor:hover{color:var(--link)}.prose p,.prose ul,.prose ol{margin:0 0 1rem}.prose li{margin:.25rem 0}.prose :is(img,video,embed,object){max-width:100%;height:auto;border-radius:var(--radius)}.prose svg{max-width:100%}.prose iframe{width:100%;aspect-ratio:16/9;height:auto;border:0;border-radius:var(--radius)}.prose hr{border:0;border-top:1px solid var(--border);margin:2rem 0}.prose :is(figure,.code-wrap){margin:1.75rem 0}.prose p:has(>:is(img,video,iframe,embed,object):only-child){margin:1.75rem 0}.prose figure{padding:0}.prose figure>:is(img,video,iframe,embed,object){display:block;margin-inline:auto}.prose figcaption{margin-top:.6rem;color:var(--fg-muted);font-size:.85rem;line-height:1.5;text-align:center}.prose :not(pre)>code{background:var(--bg-code);padding:.12em .4em;border-radius:.3rem;font-family:var(--font-mono);font-size:.875em;border:1px solid var(--border)}.prose table{width:100%;border-collapse:collapse;margin:0 0 1.25rem;font-size:.9rem;display:block;overflow-x:auto}.prose th,.prose td{border:1px solid var(--border);padding:.5rem .75rem;text-align:left}.prose thead th{background:var(--bg-alt)}.prose tbody tr:nth-child(2n){background:color-mix(in srgb,var(--fg) 4%,transparent)}.prose blockquote{margin:0 0 1rem;padding:.5rem 1rem;border-left:3px solid var(--border);color:var(--fg-muted)}.code-wrap{position:relative}.prose pre{margin:1.75rem 0;background:var(--bg-code);border:1px solid var(--border);border-radius:var(--radius);padding:1rem 3.7rem 1rem 1.1rem;overflow-x:auto;font-size:.85rem;line-height:1.6}.prose .code-wrap>pre{margin:0}.prose pre code{font-family:var(--font-mono);background:none;border:0;padding:0}.copy-btn{position:absolute;top:.7rem;right:.7rem;display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;border:1px solid var(--border);border-radius:.35rem;background:var(--bg);color:var(--fg-muted);cursor:pointer;transition:color .12s,border-color .12s,background .12s}.copy-btn:hover{background:var(--bg-alt);color:var(--fg)}.copy-btn .icon-check{display:none}.copy-btn.copied{color:#2f9e44;border-color:#2f9e44}.copy-btn.copied .icon-copy{display:none}.copy-btn.copied .icon-check{display:inline}.copy-btn.copied:after{content:attr(data-tip);position:absolute;top:50%;right:calc(100% + .4rem);transform:translateY(-50%);padding:.15rem .45rem;border-radius:.3rem;background:var(--fg);color:var(--bg);font-size:.7rem;font-family:var(--font-body);white-space:nowrap;pointer-events:none}.admonition,.marked-github-alert{--adm: var(--accent);margin:0 0 1.25rem;border:1px solid var(--adm);border-left:1px solid var(--adm)!important;border-radius:var(--radius);padding:0!important}.admonition p,.marked-github-alert p{padding:0 1rem}.admonition p:last-child,.marked-github-alert p:last-child{margin-bottom:.75rem}.admonition-title,.marked-github-alert-title{background:color-mix(in srgb,var(--adm) 7%,var(--bg));border-top-left-radius:var(--radius);border-top-right-radius:var(--radius);border-bottom:1px solid var(--adm);padding:.5rem 1rem!important;margin-bottom:.75rem!important;font-weight:700;font-size:.9rem;color:var(--adm);display:flex;align-items:center;gap:.4rem}.admonition-title:before{content:attr(data-icon)}.marked-github-alert-title svg{width:1rem;height:1rem;fill:currentColor}.admonition.info,.marked-github-alert-info,.marked-github-alert-important{--adm: #1c7ed6}.admonition.tip,.marked-github-alert-tip{--adm: #2f9e44}.admonition.warning,.marked-github-alert-warning{--adm: #f08c00}.admonition.caution,.marked-github-alert-caution{--adm: #e03131}.admonition.note,.marked-github-alert-note{--adm: #7048e8}.hljs-comment,.hljs-quote{color:var(--fg-muted);font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-literal,.hljs-section,.hljs-name{color:#cc5de8}.hljs-string,.hljs-attr,.hljs-template-tag,.hljs-addition{color:#2b8a3e}.hljs-number,.hljs-symbol,.hljs-bullet{color:#f76707}.hljs-title,.hljs-title.function_,.hljs-selector-id,.hljs-selector-class{color:#1c7ed6}.hljs-type,.hljs-class .hljs-title,.hljs-built_in{color:#a67500}.hljs-attribute,.hljs-variable,.hljs-tag{color:#e8590c}.hljs-meta,.hljs-deletion{color:var(--fg-muted)}:root[data-theme=dark] .hljs-keyword,:root[data-theme=dark] .hljs-selector-tag,:root[data-theme=dark] .hljs-literal,:root[data-theme=dark] .hljs-section,:root[data-theme=dark] .hljs-name{color:#e599f7}:root[data-theme=dark] .hljs-string,:root[data-theme=dark] .hljs-attr,:root[data-theme=dark] .hljs-template-tag,:root[data-theme=dark] .hljs-addition{color:#69db7c}:root[data-theme=dark] .hljs-number,:root[data-theme=dark] .hljs-symbol,:root[data-theme=dark] .hljs-bullet{color:#ffa94d}:root[data-theme=dark] .hljs-title,:root[data-theme=dark] .hljs-title.function_,:root[data-theme=dark] .hljs-selector-id,:root[data-theme=dark] .hljs-selector-class{color:#74c0fc}:root[data-theme=dark] .hljs-type,:root[data-theme=dark] .hljs-built_in{color:#ffd43b}:root[data-theme=dark] .hljs-attribute,:root[data-theme=dark] .hljs-variable,:root[data-theme=dark] .hljs-tag{color:#ffa94d}:root{--compare-images-slider-initial-position: 50%;--compare-images-slider-handle-bg: #fff;--compare-images-slider-handle-fg: #000;--compare-images-slider-handle-size: 42px;--compare-images-slider-handle-font-size: 28px}.compare-images-slider,compare-images-slider{display:block;position:relative;user-select:none;-webkit-user-select:none;-moz-user-select:none}.compare-images-slider img,compare-images-slider img{pointer-events:none}.compare-images-slider>img,compare-images-slider>img{max-width:100%;height:auto;display:block}.compare-images-slider .frame,compare-images-slider .frame{position:absolute;top:0;left:0;height:100%;width:var(--compare-images-slider-initial-position);overflow:hidden;z-index:2}.compare-images-slider .frame>img,compare-images-slider .frame>img{height:auto;display:block;max-width:none}.compare-images-slider .handle,compare-images-slider .handle{position:absolute;left:var(--compare-images-slider-initial-position);top:0;bottom:0;width:2px;margin-left:-1px;height:100%;cursor:ew-resize;z-index:3;touch-action:none}.compare-images-slider .handle:after,compare-images-slider .handle:after{position:absolute;top:50%;left:50%;width:var(--compare-images-slider-handle-size);height:var(--compare-images-slider-handle-size);transform:translate3d(-50%,-50%,0);content:"\2194";font-size:var(--compare-images-slider-handle-font-size);background:var(--compare-images-slider-handle-bg);color:var(--compare-images-slider-handle-fg);display:flex;align-items:center;justify-content:center;text-align:center;border-radius:21px}.compare-images-slider .handle:focus-visible,compare-images-slider .handle:focus-visible{outline:none}.compare-images-slider .handle:focus-visible:after,compare-images-slider .handle:focus-visible:after{outline:3px solid Highlight;outline:3px solid -webkit-focus-ring-color;outline-offset:2px}.compare-images-slider[data-vertical] .frame,.compare-images-slider[vertical] .frame,compare-images-slider[data-vertical] .frame,compare-images-slider[vertical] .frame{width:100%;height:var(--compare-images-slider-initial-position)}.compare-images-slider[data-vertical] .handle,.compare-images-slider[vertical] .handle,compare-images-slider[data-vertical] .handle,compare-images-slider[vertical] .handle{left:0;top:var(--compare-images-slider-initial-position);width:100%;height:2px;margin-top:-1px;margin-left:0;cursor:ns-resize}.compare-images-slider[data-vertical] .handle:after,.compare-images-slider[vertical] .handle:after,compare-images-slider[data-vertical] .handle:after,compare-images-slider[vertical] .handle:after{content:"\2195"}.compare-images-slider img,compare-images-slider img{border-radius:var(--radius)}.compare-images-slider,compare-images-slider{--compare-images-slider-handle-bg: var(--bg);--compare-images-slider-handle-fg: var(--fg)}.compare-images-slider .handle:after,compare-images-slider .handle:after{display:none}.compare-images-slider .handle-knob,compare-images-slider .handle-knob{position:absolute;top:50%;left:50%;width:var(--compare-images-slider-handle-size);height:var(--compare-images-slider-handle-size);transform:translate3d(-50%,-50%,0);background:var(--compare-images-slider-handle-bg);color:var(--compare-images-slider-handle-fg);display:flex;align-items:center;justify-content:center;border-radius:21px}.compare-images-slider .handle-knob svg,compare-images-slider .handle-knob svg{width:24px;height:24px;fill:currentColor}.compare-images-slider[data-vertical] .handle-knob,.compare-images-slider[vertical] .handle-knob,compare-images-slider[data-vertical] .handle-knob,compare-images-slider[vertical] .handle-knob{transform:translate3d(-50%,-50%,0) rotate(90deg)}
@@ -1,25 +1,33 @@
1
- /* compare-images-slider v1.0.1 | https://stamat.github.io/compare-images-slider/ | MIT License */
1
+ /* compare-images-slider v1.0.2 | https://stamat.github.io/compare-images-slider/ | MIT License */
2
2
  @charset "UTF-8";
3
3
  :root {
4
4
  --compare-images-slider-initial-position: 50%;
5
+ --compare-images-slider-handle-bg: #fff;
6
+ --compare-images-slider-handle-fg: #000;
7
+ --compare-images-slider-handle-size: 42px;
8
+ --compare-images-slider-handle-font-size: 28px;
5
9
  }
6
10
 
7
- .compare-images-slider {
11
+ .compare-images-slider,
12
+ compare-images-slider {
8
13
  display: block;
9
14
  position: relative;
10
15
  user-select: none;
11
16
  -webkit-user-select: none;
12
17
  -moz-user-select: none;
13
18
  }
14
- .compare-images-slider img {
19
+ .compare-images-slider img,
20
+ compare-images-slider img {
15
21
  pointer-events: none;
16
22
  }
17
- .compare-images-slider > img {
23
+ .compare-images-slider > img,
24
+ compare-images-slider > img {
18
25
  max-width: 100%;
19
26
  height: auto;
20
27
  display: block;
21
28
  }
22
- .compare-images-slider .frame {
29
+ .compare-images-slider .frame,
30
+ compare-images-slider .frame {
23
31
  position: absolute;
24
32
  top: 0;
25
33
  left: 0;
@@ -28,11 +36,16 @@
28
36
  overflow: hidden;
29
37
  z-index: 2;
30
38
  }
31
- .compare-images-slider .frame > img {
39
+ .compare-images-slider .frame > img,
40
+ compare-images-slider .frame > img {
32
41
  height: auto;
33
42
  display: block;
43
+ /* The script sets this image's width to the slider's full width; a page-level
44
+ `img { max-width: 100% }` would clamp it to the frame and break the reveal. */
45
+ max-width: none;
34
46
  }
35
- .compare-images-slider .handle {
47
+ .compare-images-slider .handle,
48
+ compare-images-slider .handle {
36
49
  position: absolute;
37
50
  left: var(--compare-images-slider-initial-position);
38
51
  top: 0;
@@ -42,26 +55,45 @@
42
55
  height: 100%;
43
56
  cursor: ew-resize;
44
57
  z-index: 3;
58
+ touch-action: none;
45
59
  }
46
- .compare-images-slider .handle:after {
60
+ .compare-images-slider .handle:after,
61
+ compare-images-slider .handle:after {
47
62
  position: absolute;
48
63
  top: 50%;
49
64
  left: 50%;
50
- width: 42px;
51
- height: 42px;
65
+ width: var(--compare-images-slider-handle-size);
66
+ height: var(--compare-images-slider-handle-size);
52
67
  transform: translate3d(-50%, -50%, 0);
53
68
  content: "↔";
54
- line-height: 38px;
55
- font-size: 28px;
56
- background: #fff;
69
+ font-size: var(--compare-images-slider-handle-font-size);
70
+ background: var(--compare-images-slider-handle-bg);
71
+ color: var(--compare-images-slider-handle-fg);
72
+ display: flex;
73
+ align-items: center;
74
+ justify-content: center;
57
75
  text-align: center;
58
76
  border-radius: 21px;
59
77
  }
60
- .compare-images-slider[data-vertical] .frame, .compare-images-slider[vertical] .frame {
78
+ .compare-images-slider .handle:focus-visible,
79
+ compare-images-slider .handle:focus-visible {
80
+ outline: none;
81
+ }
82
+ .compare-images-slider .handle:focus-visible:after,
83
+ compare-images-slider .handle:focus-visible:after {
84
+ outline: 3px solid Highlight;
85
+ outline: 3px solid -webkit-focus-ring-color;
86
+ outline-offset: 2px;
87
+ }
88
+ .compare-images-slider[data-vertical] .frame, .compare-images-slider[vertical] .frame,
89
+ compare-images-slider[data-vertical] .frame,
90
+ compare-images-slider[vertical] .frame {
61
91
  width: 100%;
62
92
  height: var(--compare-images-slider-initial-position);
63
93
  }
64
- .compare-images-slider[data-vertical] .handle, .compare-images-slider[vertical] .handle {
94
+ .compare-images-slider[data-vertical] .handle, .compare-images-slider[vertical] .handle,
95
+ compare-images-slider[data-vertical] .handle,
96
+ compare-images-slider[vertical] .handle {
65
97
  left: 0;
66
98
  top: var(--compare-images-slider-initial-position);
67
99
  width: 100%;
@@ -70,7 +102,9 @@
70
102
  margin-left: 0;
71
103
  cursor: ns-resize;
72
104
  }
73
- .compare-images-slider[data-vertical] .handle:after, .compare-images-slider[vertical] .handle:after {
105
+ .compare-images-slider[data-vertical] .handle:after, .compare-images-slider[vertical] .handle:after,
106
+ compare-images-slider[data-vertical] .handle:after,
107
+ compare-images-slider[vertical] .handle:after {
74
108
  content: "↕";
75
109
  }
76
110
  /*# sourceMappingURL=compare-images-slider.css.map */
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["file:///Users/stamat/Sites/localhost/compare-images-slider/src/styles/index.scss"],"names":[],"mappings":";;AAAA;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAKA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE","sourcesContent":[":root {\n --compare-images-slider-initial-position: 50%;\n}\n\n.compare-images-slider {\n display: block;\n position: relative;\n user-select: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n\n img {\n pointer-events: none;\n }\n\n & > img {\n max-width: 100%;\n height: auto;\n display: block;\n }\n\n .frame {\n position: absolute;\n top:0;\n left: 0;\n height: 100%;\n width: var(--compare-images-slider-initial-position);\n overflow: hidden;\n z-index: 2;\n\n & > img {\n height: auto;\n display: block;\n }\n }\n\n .handle {\n position:absolute;\n left: var(--compare-images-slider-initial-position);\n top:0;\n bottom:0;\n width: 2px;\n margin-left: -1px;\n height: 100%;\n cursor: ew-resize;\n z-index: 3;\n }\n\n .handle:after {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 42px;\n height: 42px;\n transform: translate3d(-50%, -50%, 0);\n\n content:'↔';\n line-height: 38px;\n font-size: 28px;\n background: #fff;\n text-align: center;\n border-radius: 21px;\n }\n\n &[data-vertical],\n &[vertical] {\n .frame {\n width: 100%;\n height: var(--compare-images-slider-initial-position);\n }\n\n .handle {\n left: 0;\n top: var(--compare-images-slider-initial-position);\n width: 100%;\n height: 2px;\n margin-top: -1px;\n margin-left: 0;\n cursor: ns-resize;\n }\n\n .handle:after {\n content:'↕';\n }\n }\n}\n"]}
1
+ {"version":3,"sourceRoot":"","sources":["file:///Users/stamat/Sites/localhost/compare-images-slider/src/styles/index.scss"],"names":[],"mappings":";;AAAA;EACE;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EACE;;AAGF;AAAA;EACE;EACA;EACA;;AAGF;AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;AAAA;EACE;EACA;AACA;AAAA;EAEA;;AAIJ;AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;AAAA;EACE;;AAGF;AAAA;EACE;EACA;EACA;;AAKA;AAAA;AAAA;EACE;EACA;;AAGF;AAAA;AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;AAAA;AAAA;EACE","sourcesContent":[":root {\n --compare-images-slider-initial-position: 50%;\n --compare-images-slider-handle-bg: #fff;\n --compare-images-slider-handle-fg: #000;\n --compare-images-slider-handle-size: 42px;\n --compare-images-slider-handle-font-size: 28px;\n}\n\n.compare-images-slider,\ncompare-images-slider {\n display: block;\n position: relative;\n user-select: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n\n img {\n pointer-events: none;\n }\n\n & > img {\n max-width: 100%;\n height: auto;\n display: block;\n }\n\n .frame {\n position: absolute;\n top:0;\n left: 0;\n height: 100%;\n width: var(--compare-images-slider-initial-position);\n overflow: hidden;\n z-index: 2;\n\n & > img {\n height: auto;\n display: block;\n /* The script sets this image's width to the slider's full width; a page-level\n `img { max-width: 100% }` would clamp it to the frame and break the reveal. */\n max-width: none;\n }\n }\n\n .handle {\n position:absolute;\n left: var(--compare-images-slider-initial-position);\n top:0;\n bottom:0;\n width: 2px;\n margin-left: -1px;\n height: 100%;\n cursor: ew-resize;\n z-index: 3;\n touch-action: none;\n }\n\n .handle:after {\n position: absolute;\n top: 50%;\n left: 50%;\n width: var(--compare-images-slider-handle-size);\n height: var(--compare-images-slider-handle-size);\n transform: translate3d(-50%, -50%, 0);\n\n content:'↔';\n font-size: var(--compare-images-slider-handle-font-size);\n background: var(--compare-images-slider-handle-bg);\n color: var(--compare-images-slider-handle-fg);\n display: flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n border-radius: 21px;\n }\n\n .handle:focus-visible {\n outline: none;\n }\n\n .handle:focus-visible:after {\n outline: 3px solid Highlight;\n outline: 3px solid -webkit-focus-ring-color;\n outline-offset: 2px;\n }\n\n &[data-vertical],\n &[vertical] {\n .frame {\n width: 100%;\n height: var(--compare-images-slider-initial-position);\n }\n\n .handle {\n left: 0;\n top: var(--compare-images-slider-initial-position);\n width: 100%;\n height: 2px;\n margin-top: -1px;\n margin-left: 0;\n cursor: ns-resize;\n }\n\n .handle:after {\n content:'↕';\n }\n }\n}\n"]}