Skip to content

Commit f59893f

Browse files
committed
add the feature to click labels for selecting that value
- allow clicking on labels - document the "hoverable" property - document the "id" property - add some improvements to readme resolves #38
1 parent cf72150 commit f59893f

File tree

6 files changed

+155
-65
lines changed

6 files changed

+155
-65
lines changed

README.md

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ A reactive, accessible, multi-thumb, range slider with the ability to display "p
99

1010
---
1111

12-
📔 | External | [_Full Documentation & Examples_](https://simeydotme.github.io/svelte-range-slider-pips/)
12+
📔 | External | [Full Documentation & Examples](https://simeydotme.github.io/svelte-range-slider-pips/)
1313
:--: | -----: | :------
14-
💲 | **REPL** |[_Svelte component demo_](https://svelte.dev/repl/030797781fd64ad88302d1343f5b2c43?version=3.32.1)
15-
❤ | **Codepen** |[_Plain JS component demo_](https://codepen.io/simeydotme/pen/KKNJdbK)
14+
📝 | **REPL** |[Svelte component demo](https://svelte.dev/repl/030797781fd64ad88302d1343f5b2c43?version=3.32.1)
15+
❤ | **Codepen** |[Plain JS component demo](https://codepen.io/simeydotme/pen/KKNJdbK)
1616

1717
---
1818

@@ -41,11 +41,23 @@ npm install svelte-range-slider-pips --save-dev # if you prefer npm
4141

4242
## usage
4343

44+
### in a svelte project
45+
46+
Assuming you have a Svelte app up and running;
47+
48+
```html
49+
<script>
50+
import RangeSlider from "svelte-range-slider-pips";
51+
</script>
52+
53+
<RangeSlider values={[50]} pips />
54+
```
55+
4456
### as a regular JS file
4557

4658
If you're not building a svelte-app, you can use the [`/dist/`
4759
version of the script `/dist/svelte-range-slider-pips.js`](dist/svelte-range-slider-pips.js) and include it
48-
either with a regular `<script>` tag. This should even work with jQuery.
60+
with a regular `<script>` tag. This should even work with jQuery.
4961

5062
```html
5163
<script src="./js/vendor/svelte-range-slider-pips.js" />
@@ -54,35 +66,23 @@ either with a regular `<script>` tag. This should even work with jQuery.
5466
5567
<script>
5668
var mySlider = new RangeSliderPips({
57-
target: document.getElementById("my-slider"),
58-
props: { /* props as js object */ }
69+
target: document.querySelector(".mySlider"),
70+
props: { values: [50], pips: true }
5971
});
6072
</script>
6173
```
6274

63-
### in a svelte project
64-
65-
Assuming you have a Svelte app up and running;
66-
67-
```html
68-
<script>
69-
import RangeSlider from "svelte-range-slider-pips";
70-
</script>
71-
72-
<RangeSlider />
73-
```
74-
7575
### as a JS module
7676

77-
If you're building a bleeding-edge JS application (not svelte), you might
77+
If you're building a bleeding-edge JS application (maybe Vue or React), you might
7878
want to use js imports (`import`)
7979

8080
```js
8181
import RangeSlider from "./node_modules/svelte-range-slider-pips/dist/svelte-range-slider-pips.mjs";
8282

8383
var mySlider = new RangeSlider({
8484
target: node, // js reference to a DOM element
85-
props: { /* props as js object */ }
85+
props: { values: [50], pips: true }
8686
});
8787
```
8888

@@ -110,7 +110,9 @@ prop | type | default | description
110110
**all** | `Boolean`/`String` | `false` | Whether to show a pip or label for all values. Same as combining `first`, `last` and `rest`. Use `all='label'` to show a label value
111111
**prefix** | `String` | `""` | A string to prefix to all displayed values
112112
**suffix** | `String` | `""` | A string to suffix to all displayed values
113+
**hoverable** | `Boolean` | `true` | Whether hover styles are enabled for both handles and pips/values
113114
**disabled** | `Boolean` | `false` | Determine if the slider is disabled, or enabled _(only disables interactions, and events)_
115+
**id** | `String` | `""` | Give the slider a unique ID for use in styling
114116
**formatter** | `Function` | `(v,i) => v` | A function to re-format values before they are displayed (`v = value, i = pip index`)
115117
**handleFormatter** | `Function` | `formatter` | A function to re-format values on the handle/float before they are displayed. Defaults to the same function given to the `formatter` property (`v = value, i = handle index`)
116118
**springValues** | `Object` | `{ stiffness: 0.15, damping: 0.4 }` | Svelte spring physics object to change the behaviour of the handle when moving
@@ -125,6 +127,19 @@ event | example | `event.detail` | description
125127

126128
**[📔📘📖 _Full Documentation & Examples_](https://simeydotme.github.io/svelte-range-slider-pips/)**
127129

130+
## styling
131+
132+
**Styling should mostly be done with CSS.**
133+
There's a [bunch of css variables for controlling the colors](https://simeydotme.github.io/svelte-range-slider-pips/#styling) of the elements.
134+
And the slider is fluid horizontally, with the size of things controlled by font-size. So you may change he `font-size` on the `.rangeSlider` base
135+
element to change the scale of everything.
136+
137+
If you require more fine control of the widths, heights, etc, then you may override the default css. This can be easier by using the `id` prop
138+
to give your slider a unique id.
139+
140+
Values of labels can be styled with CSS, and the format can be modified with the `formatter()` function prop. And animation of the handles is
141+
controlled by the `springValues` object prop.
142+
128143
## contribute
129144

130145
I am very happy to accept;

src/RangePips.svelte

Lines changed: 62 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
export let step = 1;
88
export let values = [(max + min) / 2];
99
export let vertical = false;
10+
export let hoverable = true;
11+
export let disabled = false;
1012
1113
// range pips / values props
1214
export let pipstep = undefined;
@@ -22,7 +24,10 @@
2224
2325
// stylistic props
2426
export let focus = undefined;
27+
28+
// methods
2529
export let percentOf = undefined;
30+
export let moveHandle = undefined;
2631
2732
$: pipStep = pipstep || ((max - min) / step >= ( vertical ? 50 : 100 ) ? (max - min) / ( vertical ? 10 : 20 ) : 1);
2833
@@ -45,6 +50,10 @@
4550
return values[0] < val && values[1] > val;
4651
}
4752
};
53+
54+
function labelClick(val) {
55+
moveHandle( undefined, val );
56+
}
4857
</script>
4958

5059
<style>
@@ -53,6 +62,8 @@
5362
--pip-text: var(--range-pip-text, var(--pip));
5463
--pip-active: var(--range-pip-active, darkslategrey);
5564
--pip-active-text: var(--range-pip-active-text, var(--pip-active));
65+
--pip-hover: var(--range-pip-hover, darkslategrey);
66+
--pip-hover-text: var(--range-pip-hover-text, var(--pip-hover));
5667
--pip-in-range: var(--range-pip-in-range, var(--pip-active));
5768
--pip-in-range-text: var(--range-pip-in-range-text, var(--pip-active-text));
5869
}
@@ -84,13 +95,6 @@
8495
top: 0;
8596
left: 0.25em;
8697
}
87-
:global(.rangePips .pip.selected) {
88-
height: 0.75em;
89-
}
90-
:global(.rangePips.vertical .pip.selected) {
91-
height: 1px;
92-
width: 0.75em;
93-
}
9498
:global(.rangePips .pipVal) {
9599
position: absolute;
96100
top: 0.4em;
@@ -102,19 +106,11 @@
102106
left: 0.4em;
103107
transform: translate(25%, -50%);
104108
}
105-
:global(.rangePips .pip.selected .pipVal) {
106-
font-weight: bold;
107-
top: 0.75em;
108-
}
109-
:global(.rangePips.vertical .pip.selected .pipVal) {
110-
top: 0;
111-
left: 0.75em;
112-
}
113109
:global(.rangePips .pip) {
114110
transition: all 0.15s ease;
115111
}
116112
:global(.rangePips .pipVal) {
117-
transition: all 0.15s ease;
113+
transition: all 0.15s ease, font-weight 0s linear;
118114
}
119115
:global(.rangePips .pip) {
120116
color: lightslategray;
@@ -128,36 +124,77 @@
128124
background-color: darkslategrey;
129125
background-color: var(--pip-active);
130126
}
127+
:global(.rangePips.hoverable:not(.disabled) .pip:hover) {
128+
color: darkslategrey;
129+
color: var(--pip-hover-text);
130+
background-color: darkslategrey;
131+
background-color: var(--pip-hover);
132+
}
131133
:global(.rangePips .pip.in-range) {
132134
color: darkslategrey;
133135
color: var(--pip-in-range-text);
134136
background-color: darkslategrey;
135137
background-color: var(--pip-in-range);
136138
}
139+
:global(.rangePips .pip.selected) {
140+
height: 0.75em;
141+
}
142+
:global(.rangePips.vertical .pip.selected) {
143+
height: 1px;
144+
width: 0.75em;
145+
}
146+
:global(.rangePips .pip.selected .pipVal) {
147+
font-weight: bold;
148+
top: 0.75em;
149+
}
150+
:global(.rangePips.vertical .pip.selected .pipVal) {
151+
top: 0;
152+
left: 0.75em;
153+
}
154+
:global(.rangePips.hoverable:not(.disabled) .pip:not(.selected):hover) {
155+
transition: none;
156+
}
157+
:global(.rangePips.hoverable:not(.disabled) .pip:not(.selected):hover .pipVal) {
158+
transition: none;
159+
font-weight: bold;
160+
}
137161
</style>
138162

139-
<div class="rangePips" class:focus class:vertical>
163+
<div
164+
class="rangePips"
165+
class:disabled
166+
class:hoverable
167+
class:vertical
168+
class:focus
169+
>
140170
{#if ( all && first !== false ) || first }
141171
<span
142172
class="pip first"
143173
class:selected={isSelected(min)}
144174
class:in-range={inRange(min)}
145-
style="{vertical ? 'top' : 'left'}: 0%;">
175+
style="{vertical ? 'top' : 'left'}: 0%;"
176+
on:click={labelClick(min)}
177+
on:touchend|preventDefault={labelClick(min)}
178+
>
146179
{#if all === 'label' || first === 'label'}
147180
<span class="pipVal">
148181
{#if prefix}<span class="pipVal-prefix">{prefix}</span>{/if}{formatter(min,0)}{#if suffix}<span class="pipVal-suffix">{suffix}</span>{/if}
149182
</span>
150183
{/if}
151184
</span>
152185
{/if}
186+
153187
{#if ( all && rest !== false ) || rest}
154188
{#each Array(pipCount + 1) as _, i}
155189
{#if pipVal(i) !== min && pipVal(i) !== max}
156190
<span
157191
class="pip"
158192
class:selected={isSelected(pipVal(i))}
159193
class:in-range={inRange(pipVal(i))}
160-
style="{vertical ? 'top' : 'left'}: {percentOf(pipVal(i))}%;">
194+
style="{vertical ? 'top' : 'left'}: {percentOf(pipVal(i))}%;"
195+
on:click={labelClick(pipVal(i))}
196+
on:touchend|preventDefault={labelClick(pipVal(i))}
197+
>
161198
{#if all === 'label' || rest === 'label'}
162199
<span class="pipVal">
163200
{#if prefix}<span class="pipVal-prefix">{prefix}</span>{/if}{formatter(pipVal(i),i)}{#if suffix}<span class="pipVal-suffix">{suffix}</span>{/if}
@@ -167,17 +204,22 @@
167204
{/if}
168205
{/each}
169206
{/if}
207+
170208
{#if ( all && last !== false ) || last}
171209
<span
172210
class="pip last"
173211
class:selected={isSelected(max)}
174212
class:in-range={inRange(max)}
175-
style="{vertical ? 'top' : 'left'}: 100%;">
213+
style="{vertical ? 'top' : 'left'}: 100%;"
214+
on:click={labelClick(max)}
215+
on:touchend|preventDefault={labelClick(max)}
216+
>
176217
{#if all === 'label' || last === 'label'}
177218
<span class="pipVal">
178219
{#if prefix}<span class="pipVal-prefix">{prefix}</span>{/if}{formatter(max,pipCount)}{#if suffix}<span class="pipVal-suffix">{suffix}</span>{/if}
179220
</span>
180221
{/if}
181222
</span>
182223
{/if}
224+
183225
</div>

0 commit comments

Comments
 (0)