Skip to content

Commit

Permalink
Add handleAttributes feature (#1019)
Browse files Browse the repository at this point in the history
  • Loading branch information
leongersen committed Aug 12, 2021
1 parent 7e1cb76 commit cb2a70f
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 17 deletions.
12 changes: 12 additions & 0 deletions documentation/reference.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,18 @@
<td><code>false</code></td>
<td><code>5</code></td>
</tr>
<tr>
<td><a href="/nouislider/slider-options/#section-keyboard-support">keyboardMultiplier</a></td>
<td><code>number</code></td>
<td><code>false</code></td>
<td><code>1</code></td>
</tr>
<tr>
<td><a href="/nouislider/slider-options/#section-handle-attributes">handleAttributes</a></td>
<td>array of <code>{ key: value }</code> for each handle</td>
<td><code>false</code></td>
<td><em>[none]</em></td>
</tr>
<tr>
<td><a href="/nouislider/behaviour-option/">behaviour</a></td>
<td><code>string</code></td>
Expand Down
27 changes: 27 additions & 0 deletions documentation/slider-options.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<li><a href="#section-direction">Direction</a></li>
<li><a href="#section-tooltips">Tooltips</a></li>
<li><a href="#section-animate">Animate</a></li>
<li><a href="#section-handle-attributes">Handle Attributes</a></li>
<li><a href="#section-keyboard-support">Keyboard Support</a></li>
<li><a href="#section-document-element">Document Element <small>(advanced)</small></a></li>
</ul>
Expand Down Expand Up @@ -441,6 +442,32 @@
</section>


<?php sect('handle-attributes'); ?>
<h2>Handle Attributes</h2>

<section>

<div class="view">

<p>Additional attributes can be added to the slider handles using the <code>handleAttributes</code> option.</p>

<div class="options">
<strong>Default</strong>
<div><em>[none]</em></div>

<strong>Accepted values</strong>
<div>array of <code>{ key: value }</code> for each handle</div>
</div>
</div>

<div class="side">

<?php code('handle-attributes'); ?>
</div>

</section>


<?php sect('keyboard-support'); ?>
<h2>Keyboard Support</h2>

Expand Down
11 changes: 11 additions & 0 deletions documentation/slider-options/handle-attributes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
noUiSlider.create(slider, {
start: [10, 120],
handleAttributes: [
{ 'aria-label': 'lower' },
{ 'aria-label': 'upper' },
],
range: {
'min': 0,
'max': 100
}
});
57 changes: 40 additions & 17 deletions src/nouislider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ type Pips = PositionsPips | ValuesPips | CountPips | StepsPips | RangePips;

type StartValues = string | number | (string | number)[];

type HandleAttributes = { [key: string]: string };

interface UpdatableOptions {
range?: Range;
start?: StartValues;
Expand Down Expand Up @@ -143,6 +145,7 @@ export interface Options extends UpdatableOptions {
cssClasses?: CssClasses;
ariaFormat?: PartialFormatter;
animationDuration?: number;
handleAttributes?: HandleAttributes[];
}

interface Behaviour {
Expand Down Expand Up @@ -177,6 +180,7 @@ interface ParsedOptions {
animationDuration: number;
snap?: boolean;
format: Formatter;
handleAttributes?: HandleAttributes[];

range: Range;
singleStep: number;
Expand Down Expand Up @@ -261,7 +265,7 @@ type GetResult = number | string | (string | number)[];

type NextStepsForHandle = [number | false | null, number | false | null];

type OptionKey = (keyof Options) & (keyof ParsedOptions) & (keyof UpdatableOptions);
type OptionKey = keyof Options & keyof ParsedOptions & keyof UpdatableOptions;

type PipsFilter = (value: number, type: PipsType) => PipsType;

Expand Down Expand Up @@ -399,13 +403,13 @@ function getPageOffset(doc: Document): PageOffset {
const x = supportPageOffset
? window.pageXOffset
: isCSS1Compat
? doc.documentElement.scrollLeft
: doc.body.scrollLeft;
? doc.documentElement.scrollLeft
: doc.body.scrollLeft;
const y = supportPageOffset
? window.pageYOffset
: isCSS1Compat
? doc.documentElement.scrollTop
: doc.body.scrollTop;
? doc.documentElement.scrollTop
: doc.body.scrollTop;

return {
x: x,
Expand All @@ -426,16 +430,16 @@ function getActions(): { start: string; move: string; end: string } {
end: "pointerup"
}
: window.navigator.msPointerEnabled
? {
start: "MSPointerDown",
move: "MSPointerMove",
end: "MSPointerUp"
}
: {
start: "mousedown touchstart",
move: "mousemove touchmove",
end: "mouseup touchend"
};
? {
start: "MSPointerDown",
move: "MSPointerMove",
end: "MSPointerUp"
}
: {
start: "mousedown touchstart",
move: "mousemove touchmove",
end: "mouseup touchend"
};
}

// https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
Expand Down Expand Up @@ -1186,6 +1190,14 @@ function testTooltips(parsed: ParsedOptions, entry: boolean | Formatter | (boole
}
}

function testHandleAttributes(parsed: ParsedOptions, entry: HandleAttributes[]): void {
if (entry.length !== parsed.handles) {
throw new Error("noUiSlider: must pass a attributes for all handles.");
}

parsed.handleAttributes = entry;
}

function testAriaFormat(parsed: ParsedOptions, entry: PartialFormatter): void {
if (!isValidPartialFormatter(entry)) {
throw new Error("noUiSlider: 'ariaFormat' requires 'to' method.");
Expand Down Expand Up @@ -1279,7 +1291,8 @@ function testOptions(options: Options): ParsedOptions {
keyboardSupport: { r: true, t: testKeyboardSupport },
documentElement: { r: false, t: testDocumentElement },
cssPrefix: { r: true, t: testCssPrefix },
cssClasses: { r: true, t: testCssClasses }
cssClasses: { r: true, t: testCssClasses },
handleAttributes: { r: false, t: testHandleAttributes }
};

const defaults = {
Expand Down Expand Up @@ -1330,7 +1343,10 @@ function testOptions(options: Options): ParsedOptions {
parsed.transformRule = noPrefix ? "transform" : msPrefix ? "msTransform" : "webkitTransform";

// Pips don't move, so we can place them using left/top.
const styles = [["left", "top"], ["right", "bottom"]];
const styles = [
["left", "top"],
["right", "bottom"]
];

parsed.style = styles[parsed.dir][parsed.ort] as "left" | "top" | "right" | "bottom";

Expand Down Expand Up @@ -1402,6 +1418,13 @@ function scope(target: TargetElement, options: ParsedOptions, originalOptions: O
});
}

if (options.handleAttributes !== undefined) {
const attributes: HandleAttributes = options.handleAttributes[handleNumber];
Object.keys(attributes).forEach(function(attribute: string) {
handle.setAttribute(attribute, attributes[attribute]);
});
}

handle.setAttribute("role", "slider");
handle.setAttribute("aria-orientation", options.ort ? "vertical" : "horizontal");

Expand Down
6 changes: 6 additions & 0 deletions tests/slider_aria.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ QUnit.test("Aria", function (assert) {
return Math.round(x).toString();
}, from: Number
},
handleAttributes: [
{ 'aria-label': 'lower' },
{ 'aria-label': 'upper' },
],
range: {
'min': 50,
'max': 1050
Expand All @@ -24,11 +28,13 @@ QUnit.test("Aria", function (assert) {

assert.equal(handle0.getAttribute('role'), 'slider');

assert.equal(handle0.getAttribute('aria-label'), 'lower');
assert.equal(handle0.getAttribute('aria-valuemin'), '50.0', 'Handle0 min');
assert.equal(handle0.getAttribute('aria-valuemax'), '100.0', 'Handle0 max');
assert.equal(handle0.getAttribute('aria-valuenow'), '50.0', 'Handle0 now');
assert.equal(handle0.getAttribute('aria-valuetext'), '50', 'Handle0 txt');

assert.equal(handle1.getAttribute('aria-label'), 'upper');
assert.equal(handle1.getAttribute('aria-valuemin'), '100.0', 'Handle1 min');
assert.equal(handle1.getAttribute('aria-valuemax'), '1050.0', 'Handle1 max');
assert.equal(handle1.getAttribute('aria-valuenow'), '150.0', 'Handle1 now');
Expand Down

0 comments on commit cb2a70f

Please sign in to comment.