Skip to content

Commit 787ad0c

Browse files
author
lgersen
committed
noUiSlider 15.8.0
1 parent 077c436 commit 787ad0c

File tree

9 files changed

+139
-16
lines changed

9 files changed

+139
-16
lines changed

CHANGELOG.MD

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
### 15.8.0 (*2024-06-10*)
4+
- Added: Allow `connect` option to get updated (#1272);
5+
- Added: `invert-connects` behaviour (#1262, #1272);
6+
37
### 15.7.2 (*2024-05-14*)
48
- Added: `getPositions` to Typescript definitions (#1270);
59
- Added: Allow `null` in `set` Typescript definitions (#1271);

RELEASE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
- Run `npm audit fix`
44
- Update `changelog.md`
55
- Run `npm publish -otp=<2FA VALUE FROM AUTHENTICATOR>`
6+
- Commit changes to changelog and build files
67
- Create a new release on https://github.com/leongersen/noUiSlider/releases

dist/nouislider.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,10 @@ interface UpdatableOptions {
108108
format?: Formatter;
109109
tooltips?: boolean | PartialFormatter | (boolean | PartialFormatter)[];
110110
animate?: boolean;
111+
connect?: "lower" | "upper" | boolean | boolean[];
111112
}
112113
export interface Options extends UpdatableOptions {
113114
range: Range;
114-
connect?: "lower" | "upper" | boolean | boolean[];
115115
orientation?: "vertical" | "horizontal";
116116
direction?: "ltr" | "rtl";
117117
behaviour?: string;

dist/nouislider.js

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,7 @@
713713
var snap = entry.indexOf("snap") >= 0;
714714
var hover = entry.indexOf("hover") >= 0;
715715
var unconstrained = entry.indexOf("unconstrained") >= 0;
716+
var invertConnects = entry.indexOf("invert-connects") >= 0;
716717
var dragAll = entry.indexOf("drag-all") >= 0;
717718
var smoothSteps = entry.indexOf("smooth-steps") >= 0;
718719
if (fixed) {
@@ -722,6 +723,9 @@
722723
// Use margin to enforce fixed state
723724
testMargin(parsed, parsed.start[1] - parsed.start[0]);
724725
}
726+
if (invertConnects && parsed.handles !== 2) {
727+
throw new Error("noUiSlider: 'invert-connects' behaviour must be used with 2 handles");
728+
}
725729
if (unconstrained && (parsed.margin || parsed.limit)) {
726730
throw new Error("noUiSlider: 'unconstrained' behaviour cannot be used with margin or limit");
727731
}
@@ -734,6 +738,7 @@
734738
snap: snap,
735739
hover: hover,
736740
unconstrained: unconstrained,
741+
invertConnects: invertConnects,
737742
};
738743
}
739744
function testTooltips(parsed, entry) {
@@ -904,6 +909,7 @@
904909
// Slider DOM Nodes
905910
var scope_Target = target;
906911
var scope_Base;
912+
var scope_ConnectBase;
907913
var scope_Handles;
908914
var scope_Connects;
909915
var scope_Pips;
@@ -915,6 +921,7 @@
915921
var scope_HandleNumbers = [];
916922
var scope_ActiveHandlesCount = 0;
917923
var scope_Events = {};
924+
var scope_ConnectsInverted = false;
918925
// Document Nodes
919926
var scope_Document = target.ownerDocument;
920927
var scope_DocumentElement = options.documentElement || scope_Document.documentElement;
@@ -971,17 +978,17 @@
971978
}
972979
// Add handles to the slider base.
973980
function addElements(connectOptions, base) {
974-
var connectBase = addNodeTo(base, options.cssClasses.connects);
981+
scope_ConnectBase = addNodeTo(base, options.cssClasses.connects);
975982
scope_Handles = [];
976983
scope_Connects = [];
977-
scope_Connects.push(addConnect(connectBase, connectOptions[0]));
984+
scope_Connects.push(addConnect(scope_ConnectBase, connectOptions[0]));
978985
// [::::O====O====O====]
979986
// connectOptions = [0, 1, 1, 1]
980987
for (var i = 0; i < options.handles; i++) {
981988
// Keep a list of all added handles.
982989
scope_Handles.push(addOrigin(base, i));
983990
scope_HandleNumbers[i] = i;
984-
scope_Connects.push(addConnect(connectBase, connectOptions[i + 1]));
991+
scope_Connects.push(addConnect(scope_ConnectBase, connectOptions[i + 1]));
985992
}
986993
}
987994
// Initialize a single slider.
@@ -1930,8 +1937,26 @@
19301937
var translation = transformDirection(to, 0) - scope_DirOffset;
19311938
var translateRule = "translate(" + inRuleOrder(translation + "%", "0") + ")";
19321939
scope_Handles[handleNumber].style[options.transformRule] = translateRule;
1940+
// sanity check for at least 2 handles (e.g. during setup)
1941+
if (options.events.invertConnects && scope_Locations.length > 1) {
1942+
// check if handles passed each other, but don't match the ConnectsInverted state
1943+
var handlesAreInOrder = scope_Locations.every(function (position, index, locations) {
1944+
return index === 0 || position >= locations[index - 1];
1945+
});
1946+
if (scope_ConnectsInverted !== !handlesAreInOrder) {
1947+
// invert connects when handles pass each other
1948+
invertConnects();
1949+
// invertConnects already updates all connect elements
1950+
return;
1951+
}
1952+
}
19331953
updateConnect(handleNumber);
19341954
updateConnect(handleNumber + 1);
1955+
if (scope_ConnectsInverted) {
1956+
// When connects are inverted, we also have to update adjacent connects
1957+
updateConnect(handleNumber - 1);
1958+
updateConnect(handleNumber + 2);
1959+
}
19351960
}
19361961
// Handles before the slider middle are stacked later = higher,
19371962
// Handles after the middle later is lower
@@ -1961,13 +1986,20 @@
19611986
if (!scope_Connects[index]) {
19621987
return;
19631988
}
1989+
// Create a copy of locations, so we can sort them for the local scope logic
1990+
var locations = scope_Locations.slice();
1991+
if (scope_ConnectsInverted) {
1992+
locations.sort(function (a, b) {
1993+
return a - b;
1994+
});
1995+
}
19641996
var l = 0;
19651997
var h = 100;
19661998
if (index !== 0) {
1967-
l = scope_Locations[index - 1];
1999+
l = locations[index - 1];
19682000
}
19692001
if (index !== scope_Connects.length - 1) {
1970-
h = scope_Locations[index];
2002+
h = locations[index];
19712003
}
19722004
// We use two rules:
19732005
// 'translate' to change the left/top offset;
@@ -2159,6 +2191,7 @@
21592191
"format",
21602192
"pips",
21612193
"tooltips",
2194+
"connect",
21622195
];
21632196
// Only change options that we're actually passed to update.
21642197
updateAble.forEach(function (name) {
@@ -2196,6 +2229,32 @@
21962229
// Invalidate the current positioning so valueSet forces an update.
21972230
scope_Locations = [];
21982231
valueSet(isSet(optionsToUpdate.start) ? optionsToUpdate.start : v, fireSetEvent);
2232+
// Update connects only if it was set
2233+
if (optionsToUpdate.connect) {
2234+
updateConnectOption();
2235+
}
2236+
}
2237+
function updateConnectOption() {
2238+
// IE supported way of removing children including event handlers
2239+
while (scope_ConnectBase.firstChild) {
2240+
scope_ConnectBase.removeChild(scope_ConnectBase.firstChild);
2241+
}
2242+
// Adding new connects according to the new connect options
2243+
for (var i = 0; i <= options.handles; i++) {
2244+
scope_Connects[i] = addConnect(scope_ConnectBase, options.connect[i]);
2245+
updateConnect(i);
2246+
}
2247+
// re-adding drag events for the new connect elements
2248+
// to ignore the other events we have to negate the 'if (!behaviour.fixed)' check
2249+
bindSliderEvents({ drag: options.events.drag, fixed: true });
2250+
}
2251+
// Invert options for connect handles
2252+
function invertConnects() {
2253+
scope_ConnectsInverted = !scope_ConnectsInverted;
2254+
testConnect(options,
2255+
// inverse the connect boolean array
2256+
options.connect.map(function (b) { return !b; }));
2257+
updateConnectOption();
21992258
}
22002259
// Initialization steps
22012260
function setupSlider() {

dist/nouislider.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/nouislider.min.mjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

dist/nouislider.mjs

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,7 @@ function testBehaviour(parsed, entry) {
708708
var snap = entry.indexOf("snap") >= 0;
709709
var hover = entry.indexOf("hover") >= 0;
710710
var unconstrained = entry.indexOf("unconstrained") >= 0;
711+
var invertConnects = entry.indexOf("invert-connects") >= 0;
711712
var dragAll = entry.indexOf("drag-all") >= 0;
712713
var smoothSteps = entry.indexOf("smooth-steps") >= 0;
713714
if (fixed) {
@@ -717,6 +718,9 @@ function testBehaviour(parsed, entry) {
717718
// Use margin to enforce fixed state
718719
testMargin(parsed, parsed.start[1] - parsed.start[0]);
719720
}
721+
if (invertConnects && parsed.handles !== 2) {
722+
throw new Error("noUiSlider: 'invert-connects' behaviour must be used with 2 handles");
723+
}
720724
if (unconstrained && (parsed.margin || parsed.limit)) {
721725
throw new Error("noUiSlider: 'unconstrained' behaviour cannot be used with margin or limit");
722726
}
@@ -729,6 +733,7 @@ function testBehaviour(parsed, entry) {
729733
snap: snap,
730734
hover: hover,
731735
unconstrained: unconstrained,
736+
invertConnects: invertConnects,
732737
};
733738
}
734739
function testTooltips(parsed, entry) {
@@ -899,6 +904,7 @@ function scope(target, options, originalOptions) {
899904
// Slider DOM Nodes
900905
var scope_Target = target;
901906
var scope_Base;
907+
var scope_ConnectBase;
902908
var scope_Handles;
903909
var scope_Connects;
904910
var scope_Pips;
@@ -910,6 +916,7 @@ function scope(target, options, originalOptions) {
910916
var scope_HandleNumbers = [];
911917
var scope_ActiveHandlesCount = 0;
912918
var scope_Events = {};
919+
var scope_ConnectsInverted = false;
913920
// Document Nodes
914921
var scope_Document = target.ownerDocument;
915922
var scope_DocumentElement = options.documentElement || scope_Document.documentElement;
@@ -966,17 +973,17 @@ function scope(target, options, originalOptions) {
966973
}
967974
// Add handles to the slider base.
968975
function addElements(connectOptions, base) {
969-
var connectBase = addNodeTo(base, options.cssClasses.connects);
976+
scope_ConnectBase = addNodeTo(base, options.cssClasses.connects);
970977
scope_Handles = [];
971978
scope_Connects = [];
972-
scope_Connects.push(addConnect(connectBase, connectOptions[0]));
979+
scope_Connects.push(addConnect(scope_ConnectBase, connectOptions[0]));
973980
// [::::O====O====O====]
974981
// connectOptions = [0, 1, 1, 1]
975982
for (var i = 0; i < options.handles; i++) {
976983
// Keep a list of all added handles.
977984
scope_Handles.push(addOrigin(base, i));
978985
scope_HandleNumbers[i] = i;
979-
scope_Connects.push(addConnect(connectBase, connectOptions[i + 1]));
986+
scope_Connects.push(addConnect(scope_ConnectBase, connectOptions[i + 1]));
980987
}
981988
}
982989
// Initialize a single slider.
@@ -1925,8 +1932,26 @@ function scope(target, options, originalOptions) {
19251932
var translation = transformDirection(to, 0) - scope_DirOffset;
19261933
var translateRule = "translate(" + inRuleOrder(translation + "%", "0") + ")";
19271934
scope_Handles[handleNumber].style[options.transformRule] = translateRule;
1935+
// sanity check for at least 2 handles (e.g. during setup)
1936+
if (options.events.invertConnects && scope_Locations.length > 1) {
1937+
// check if handles passed each other, but don't match the ConnectsInverted state
1938+
var handlesAreInOrder = scope_Locations.every(function (position, index, locations) {
1939+
return index === 0 || position >= locations[index - 1];
1940+
});
1941+
if (scope_ConnectsInverted !== !handlesAreInOrder) {
1942+
// invert connects when handles pass each other
1943+
invertConnects();
1944+
// invertConnects already updates all connect elements
1945+
return;
1946+
}
1947+
}
19281948
updateConnect(handleNumber);
19291949
updateConnect(handleNumber + 1);
1950+
if (scope_ConnectsInverted) {
1951+
// When connects are inverted, we also have to update adjacent connects
1952+
updateConnect(handleNumber - 1);
1953+
updateConnect(handleNumber + 2);
1954+
}
19301955
}
19311956
// Handles before the slider middle are stacked later = higher,
19321957
// Handles after the middle later is lower
@@ -1956,13 +1981,20 @@ function scope(target, options, originalOptions) {
19561981
if (!scope_Connects[index]) {
19571982
return;
19581983
}
1984+
// Create a copy of locations, so we can sort them for the local scope logic
1985+
var locations = scope_Locations.slice();
1986+
if (scope_ConnectsInverted) {
1987+
locations.sort(function (a, b) {
1988+
return a - b;
1989+
});
1990+
}
19591991
var l = 0;
19601992
var h = 100;
19611993
if (index !== 0) {
1962-
l = scope_Locations[index - 1];
1994+
l = locations[index - 1];
19631995
}
19641996
if (index !== scope_Connects.length - 1) {
1965-
h = scope_Locations[index];
1997+
h = locations[index];
19661998
}
19671999
// We use two rules:
19682000
// 'translate' to change the left/top offset;
@@ -2154,6 +2186,7 @@ function scope(target, options, originalOptions) {
21542186
"format",
21552187
"pips",
21562188
"tooltips",
2189+
"connect",
21572190
];
21582191
// Only change options that we're actually passed to update.
21592192
updateAble.forEach(function (name) {
@@ -2191,6 +2224,32 @@ function scope(target, options, originalOptions) {
21912224
// Invalidate the current positioning so valueSet forces an update.
21922225
scope_Locations = [];
21932226
valueSet(isSet(optionsToUpdate.start) ? optionsToUpdate.start : v, fireSetEvent);
2227+
// Update connects only if it was set
2228+
if (optionsToUpdate.connect) {
2229+
updateConnectOption();
2230+
}
2231+
}
2232+
function updateConnectOption() {
2233+
// IE supported way of removing children including event handlers
2234+
while (scope_ConnectBase.firstChild) {
2235+
scope_ConnectBase.removeChild(scope_ConnectBase.firstChild);
2236+
}
2237+
// Adding new connects according to the new connect options
2238+
for (var i = 0; i <= options.handles; i++) {
2239+
scope_Connects[i] = addConnect(scope_ConnectBase, options.connect[i]);
2240+
updateConnect(i);
2241+
}
2242+
// re-adding drag events for the new connect elements
2243+
// to ignore the other events we have to negate the 'if (!behaviour.fixed)' check
2244+
bindSliderEvents({ drag: options.events.drag, fixed: true });
2245+
}
2246+
// Invert options for connect handles
2247+
function invertConnects() {
2248+
scope_ConnectsInverted = !scope_ConnectsInverted;
2249+
testConnect(options,
2250+
// inverse the connect boolean array
2251+
options.connect.map(function (b) { return !b; }));
2252+
updateConnectOption();
21942253
}
21952254
// Initialization steps
21962255
function setupSlider() {

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "nouislider",
3-
"version": "15.7.2",
3+
"version": "15.8.0",
44
"main": "dist/nouislider.js",
55
"module": "dist/nouislider.mjs",
66
"style": "dist/nouislider.min.css",

0 commit comments

Comments
 (0)