@sit-onyx/headless 0.4.0-dev-20251112133447 → 0.4.0-dev-20251118092838
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.
- package/dist/composables/slider/TestSlider.d.vue.ts +9 -0
- package/dist/composables/slider/createSlider.d.ts +388 -112
- package/dist/composables/slider/createSlider.testing.d.ts +10 -30
- package/dist/index.js +186 -484
- package/dist/playwright.d.ts +1 -0
- package/dist/playwright.js +138 -0
- package/package.json +1 -1
- package/dist/composables/slider/DiscreteSlider.d.vue.ts +0 -92
- package/dist/composables/slider/RangeSlider.d.vue.ts +0 -92
- package/dist/composables/slider/SimpleSlider.d.vue.ts +0 -92
package/dist/index.js
CHANGED
|
@@ -959,465 +959,204 @@ const createNavigationMenu = createBuilder(({ navigationName }) => {
|
|
|
959
959
|
};
|
|
960
960
|
});
|
|
961
961
|
const areArraysEqual = (arrayA, arrayB, comparer = (a, b) => a === b) => arrayA.length === arrayB.length && arrayA.every((value, index) => comparer(value, arrayB[index]));
|
|
962
|
-
const isFocusVisible = (element) => {
|
|
963
|
-
try {
|
|
964
|
-
return element.matches(":focus-visible");
|
|
965
|
-
} catch {
|
|
966
|
-
return false;
|
|
967
|
-
}
|
|
968
|
-
};
|
|
969
|
-
const isTouchEvent = (event) => "touches" in event || "changedTouches" in event || "targetTouches" in event;
|
|
970
|
-
const DRAG_MOVE_THRESHOLD = 2;
|
|
971
|
-
const KEY = {
|
|
972
|
-
Up: "ArrowUp",
|
|
973
|
-
Down: "ArrowDown",
|
|
974
|
-
Left: "ArrowLeft",
|
|
975
|
-
Right: "ArrowRight",
|
|
976
|
-
PageUp: "PageUp",
|
|
977
|
-
PageDown: "PageDown",
|
|
978
|
-
Home: "Home",
|
|
979
|
-
End: "End"
|
|
980
|
-
};
|
|
981
962
|
const NAVIGATION_KEYS = /* @__PURE__ */ new Set([
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
963
|
+
"ArrowUp",
|
|
964
|
+
"ArrowDown",
|
|
965
|
+
"ArrowLeft",
|
|
966
|
+
"ArrowRight",
|
|
967
|
+
"PageUp",
|
|
968
|
+
"PageDown",
|
|
969
|
+
"Home",
|
|
970
|
+
"End"
|
|
990
971
|
]);
|
|
991
|
-
const INCREMENT_KEYS = /* @__PURE__ */ new Set([
|
|
992
|
-
const DECREMENT_KEYS = /* @__PURE__ */ new Set([
|
|
993
|
-
const readThumbIndex = (event) => Number(event.currentTarget?.dataset.index ?? -1);
|
|
994
|
-
const roundToStep = (value, step, min) => Number((Math.round((value - min) / step) * step + min).toFixed(MathUtils.decimalsCount(step)));
|
|
995
|
-
const findClosestIndex = (values, currentValue) => {
|
|
996
|
-
const result = values.reduce((acc, value, index) => {
|
|
997
|
-
const distance = Math.abs(currentValue - value);
|
|
998
|
-
if (!acc || distance <= acc.closestDistance) {
|
|
999
|
-
return {
|
|
1000
|
-
closestIndex: index,
|
|
1001
|
-
closestDistance: distance
|
|
1002
|
-
};
|
|
1003
|
-
}
|
|
1004
|
-
return acc;
|
|
1005
|
-
}, null);
|
|
1006
|
-
return result?.closestIndex ?? -1;
|
|
1007
|
-
};
|
|
1008
|
-
const adjustValueByIndex = ({
|
|
1009
|
-
values,
|
|
1010
|
-
newValue,
|
|
1011
|
-
index
|
|
1012
|
-
}) => values.map((value, i) => i === index ? newValue : value).sort((a, b) => a - b);
|
|
1013
|
-
const asc = (a, b) => a - b;
|
|
1014
|
-
const valueToArray = (value) => Array.isArray(value) ? value : [value];
|
|
972
|
+
const INCREMENT_KEYS = /* @__PURE__ */ new Set(["ArrowRight", "ArrowUp", "PageUp"]);
|
|
973
|
+
const DECREMENT_KEYS = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowDown", "PageDown"]);
|
|
1015
974
|
const _unstableCreateSlider = createBuilder(
|
|
1016
975
|
(options) => {
|
|
1017
976
|
const sliderRef = createElRef();
|
|
1018
|
-
const min = computed(() =>
|
|
1019
|
-
const max = computed(() =>
|
|
1020
|
-
const step = computed(() =>
|
|
1021
|
-
const
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
return arrayValues.map((value) => {
|
|
1026
|
-
const clamped = MathUtils.clamp(value, min.value, max.value);
|
|
1027
|
-
if (isDiscrete.value) {
|
|
1028
|
-
return roundToStep(clamped, step.value, min.value);
|
|
1029
|
-
}
|
|
1030
|
-
return clamped;
|
|
1031
|
-
});
|
|
977
|
+
const min = computed(() => toValue(options.min) ?? 0);
|
|
978
|
+
const max = computed(() => toValue(options.max) ?? 100);
|
|
979
|
+
const step = computed(() => toValue(options.step) ?? 1);
|
|
980
|
+
const draggingThumbIndex = ref();
|
|
981
|
+
watch(draggingThumbIndex, (newThumbIndex) => {
|
|
982
|
+
if (newThumbIndex == void 0) return;
|
|
983
|
+
Array.from(sliderRef.value.querySelectorAll('[role="slider"]')).at(newThumbIndex)?.focus();
|
|
1032
984
|
});
|
|
1033
985
|
const shiftStep = computed(() => {
|
|
1034
|
-
const shiftStep2 =
|
|
986
|
+
const shiftStep2 = toValue(options.shiftStep);
|
|
1035
987
|
if (shiftStep2 != void 0) return shiftStep2;
|
|
1036
988
|
const stepMultiple = Math.max(1, Math.round((max.value - min.value) * 0.1 / step.value));
|
|
1037
989
|
return stepMultiple * step.value;
|
|
1038
990
|
});
|
|
1039
|
-
const isDisabled = computed(() => unref(options.disabled) ?? false);
|
|
1040
|
-
const isDiscrete = computed(() => unref(options.discrete) ?? false);
|
|
1041
991
|
const marks = computed(() => {
|
|
1042
|
-
const
|
|
1043
|
-
if (
|
|
1044
|
-
|
|
992
|
+
const _marks = toValue(options.marks);
|
|
993
|
+
if (!_marks) return [];
|
|
994
|
+
if (_marks === true) {
|
|
995
|
+
const markCount = Math.floor((max.value - min.value) / step.value) + 1;
|
|
996
|
+
return Array.from({ length: markCount }, (_, index) => {
|
|
997
|
+
return { value: min.value + step.value * index };
|
|
998
|
+
});
|
|
1045
999
|
}
|
|
1046
|
-
return
|
|
1000
|
+
return _marks.map((mark) => {
|
|
1001
|
+
if (typeof mark === "number") return { value: mark };
|
|
1002
|
+
return mark;
|
|
1003
|
+
}).sort((a, b) => a.value - b.value);
|
|
1047
1004
|
});
|
|
1048
|
-
const
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
if (marks.value && Array.isArray(marks.value)) {
|
|
1062
|
-
return marks.value.map((mark) => typeof mark === "number" ? { value: mark } : mark).filter((mark) => mark.value >= min.value && mark.value <= max.value).sort((a, b) => asc(a.value, b.value));
|
|
1063
|
-
}
|
|
1064
|
-
if (step.value && step.value > 0) {
|
|
1065
|
-
return [...Array(Math.floor((max.value - min.value) / step.value + 1))].map((_, index) => ({
|
|
1066
|
-
value: min.value + step.value * index
|
|
1067
|
-
}));
|
|
1068
|
-
}
|
|
1069
|
-
return [];
|
|
1005
|
+
const getNormalizedValue = computed(() => {
|
|
1006
|
+
return (value) => {
|
|
1007
|
+
let values = typeof value === "number" ? [value] : value;
|
|
1008
|
+
values = values.map((value2) => MathUtils.clamp(value2, min.value, max.value)).map((value2) => {
|
|
1009
|
+
const stepDecimals = MathUtils.decimalsCount(step.value);
|
|
1010
|
+
return Number(
|
|
1011
|
+
(Math.round((value2 - min.value) / step.value) * step.value + min.value).toFixed(
|
|
1012
|
+
stepDecimals
|
|
1013
|
+
)
|
|
1014
|
+
);
|
|
1015
|
+
}).sort((a, b) => a - b);
|
|
1016
|
+
return values;
|
|
1017
|
+
};
|
|
1070
1018
|
});
|
|
1071
|
-
const
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1019
|
+
const normalizedValue = computed(
|
|
1020
|
+
() => getNormalizedValue.value(toValue(options.value))
|
|
1021
|
+
);
|
|
1022
|
+
const updateValue = (value, index) => {
|
|
1023
|
+
const currentValue = normalizedValue.value.slice();
|
|
1024
|
+
const otherIndex = index === 0 ? 1 : 0;
|
|
1025
|
+
const otherValue = currentValue[otherIndex];
|
|
1026
|
+
if (otherValue != void 0) {
|
|
1027
|
+
if (index < otherIndex && value > otherValue) {
|
|
1028
|
+
value = otherValue;
|
|
1029
|
+
} else if (index > otherIndex && value < otherValue) {
|
|
1030
|
+
value = otherValue;
|
|
1077
1031
|
}
|
|
1078
1032
|
}
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
if (typeof nextValue !== "undefined") {
|
|
1085
|
-
options.onCommit?.(nextValue);
|
|
1086
|
-
}
|
|
1033
|
+
currentValue[index] = value;
|
|
1034
|
+
const normalized = getNormalizedValue.value(currentValue);
|
|
1035
|
+
const newValue = normalized.length > 1 ? normalized : normalized[0];
|
|
1036
|
+
if (areArraysEqual(normalized, normalizedValue.value)) return;
|
|
1037
|
+
options.onChange?.(newValue);
|
|
1087
1038
|
};
|
|
1088
|
-
const
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
if (slider.contains(document.activeElement) && Number(document.activeElement?.getAttribute("data-index")) !== index) {
|
|
1093
|
-
slider.querySelector(`[type="range"][data-index="${index}"]`)?.focus();
|
|
1094
|
-
}
|
|
1095
|
-
if (shouldSetActive) {
|
|
1096
|
-
activeThumbIndex.value = index;
|
|
1097
|
-
}
|
|
1098
|
-
};
|
|
1099
|
-
const eventToCoords = (event, touchId2) => {
|
|
1100
|
-
if (touchId2 !== void 0 && isTouchEvent(event)) {
|
|
1101
|
-
for (let i = 0; i < event.changedTouches.length; i += 1) {
|
|
1102
|
-
const touch = event.changedTouches[i];
|
|
1103
|
-
if (touch && touch.identifier === touchId2) {
|
|
1104
|
-
return {
|
|
1105
|
-
x: touch.clientX,
|
|
1106
|
-
y: touch.clientY
|
|
1107
|
-
};
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
return false;
|
|
1111
|
-
}
|
|
1112
|
-
const mouseEvent = event;
|
|
1113
|
-
return {
|
|
1114
|
-
x: mouseEvent.clientX,
|
|
1115
|
-
y: mouseEvent.clientY
|
|
1039
|
+
const getValueInPercentage = computed(() => {
|
|
1040
|
+
return (value) => {
|
|
1041
|
+
const percentage = MathUtils.valueToPercent(value, min.value, max.value);
|
|
1042
|
+
return MathUtils.clamp(percentage, 0, 100);
|
|
1116
1043
|
};
|
|
1117
|
-
};
|
|
1118
|
-
const
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
const snapped = !isDiscrete.value ? roundToStep(raw, step.value, min.value) : marksValues.value[findClosestIndex(marksValues.value, raw)];
|
|
1127
|
-
if (typeof snapped !== "number") return null;
|
|
1128
|
-
const candidate = MathUtils.clamp(snapped, min.value, max.value);
|
|
1129
|
-
if (!isRange.value) {
|
|
1130
|
-
return { newValue: candidate, activeIndex: 0 };
|
|
1131
|
-
}
|
|
1132
|
-
const closestIndex = findClosestIndex(normalizedValues.value, candidate);
|
|
1133
|
-
const index = isMoving && previousActiveIndex != null ? previousActiveIndex : closestIndex;
|
|
1134
|
-
const adjustedValues = adjustValueByIndex({
|
|
1135
|
-
values: normalizedValues.value,
|
|
1136
|
-
newValue: candidate,
|
|
1137
|
-
index
|
|
1138
|
-
});
|
|
1139
|
-
const adjustedIndex = findClosestIndex(adjustedValues, candidate);
|
|
1140
|
-
previousActiveIndex = adjustedIndex;
|
|
1141
|
-
return { newValue: adjustedValues, activeIndex: adjustedIndex };
|
|
1142
|
-
};
|
|
1143
|
-
const commitValueFromEvent = (event, input) => {
|
|
1144
|
-
const index = readThumbIndex(event);
|
|
1145
|
-
const current = normalizedValues.value[index];
|
|
1146
|
-
if (typeof current !== "number") {
|
|
1147
|
-
return;
|
|
1148
|
-
}
|
|
1149
|
-
const useMarks = isDiscrete.value && marksList.value.length > 0;
|
|
1150
|
-
const snapByMarks = (candidate) => {
|
|
1151
|
-
const list = marksList.value;
|
|
1152
|
-
const first = list[0];
|
|
1153
|
-
const last = list.at(-1);
|
|
1154
|
-
if (!first || !last) {
|
|
1155
|
-
return current;
|
|
1156
|
-
}
|
|
1157
|
-
if (candidate <= first.value) {
|
|
1158
|
-
return first.value;
|
|
1159
|
-
}
|
|
1160
|
-
if (candidate >= last.value) {
|
|
1161
|
-
return last.value;
|
|
1162
|
-
}
|
|
1163
|
-
const pos = marksValues.value.indexOf(current);
|
|
1164
|
-
const neighbor = candidate < current ? list[pos - 1] : list[pos + 1];
|
|
1165
|
-
return neighbor?.value ?? current;
|
|
1166
|
-
};
|
|
1167
|
-
const scalar = MathUtils.clamp(useMarks ? snapByMarks(input) : input, min.value, max.value);
|
|
1168
|
-
const nextValues = isRange.value ? adjustValueByIndex({ values: normalizedValues.value, newValue: scalar, index }) : [scalar];
|
|
1169
|
-
if (isRange.value) {
|
|
1170
|
-
const activeIndex = nextValues.indexOf(scalar);
|
|
1171
|
-
ensureFocusOnThumb({ index: activeIndex, shouldSetActive: true });
|
|
1172
|
-
}
|
|
1173
|
-
if (!areArraysEqual(normalizedValues.value, nextValues)) {
|
|
1174
|
-
emitChange(nextValues);
|
|
1175
|
-
}
|
|
1176
|
-
emitCommit(nextValues);
|
|
1177
|
-
};
|
|
1178
|
-
const handlePointerEnd = (event) => {
|
|
1179
|
-
const coords = eventToCoords(event, touchId);
|
|
1180
|
-
isDragging.value = false;
|
|
1181
|
-
if (!coords) {
|
|
1182
|
-
return;
|
|
1183
|
-
}
|
|
1184
|
-
const next = getNextFromCoords({ coords, isMoving: true });
|
|
1185
|
-
if (!next) {
|
|
1186
|
-
return;
|
|
1187
|
-
}
|
|
1188
|
-
const { newValue } = next;
|
|
1189
|
-
activeThumbIndex.value = -1;
|
|
1190
|
-
emitCommit(valueToArray(newValue));
|
|
1191
|
-
movesSinceStart = 0;
|
|
1192
|
-
touchId = null;
|
|
1193
|
-
stopPointerListening();
|
|
1194
|
-
};
|
|
1195
|
-
const handlePointerMove = (event) => {
|
|
1196
|
-
const coords = eventToCoords(event, touchId);
|
|
1197
|
-
if (!coords) return;
|
|
1198
|
-
movesSinceStart += 1;
|
|
1199
|
-
if (event.type === "mousemove" && event.buttons === 0) {
|
|
1200
|
-
handlePointerEnd(event);
|
|
1201
|
-
return;
|
|
1202
|
-
}
|
|
1203
|
-
const nextState = getNextFromCoords({ coords, isMoving: true });
|
|
1204
|
-
if (!nextState) {
|
|
1205
|
-
handlePointerEnd(event);
|
|
1206
|
-
return;
|
|
1207
|
-
}
|
|
1208
|
-
const { newValue, activeIndex } = nextState;
|
|
1209
|
-
if (!isDragging.value && movesSinceStart > DRAG_MOVE_THRESHOLD) {
|
|
1210
|
-
isDragging.value = true;
|
|
1211
|
-
}
|
|
1212
|
-
ensureFocusOnThumb({ index: activeIndex, shouldSetActive: true });
|
|
1213
|
-
emitChange(valueToArray(newValue));
|
|
1214
|
-
isDragging.value = true;
|
|
1215
|
-
};
|
|
1216
|
-
const handlePointerStart = (event) => {
|
|
1217
|
-
if (isDisabled.value) {
|
|
1218
|
-
return;
|
|
1044
|
+
});
|
|
1045
|
+
const handleKeydown = (event, thumbIndex) => {
|
|
1046
|
+
if (!NAVIGATION_KEYS.has(event.key)) return;
|
|
1047
|
+
event.preventDefault();
|
|
1048
|
+
const currentValue = normalizedValue.value.slice();
|
|
1049
|
+
if (currentValue[thumbIndex] == void 0) return;
|
|
1050
|
+
const stepSize = event.shiftKey ? shiftStep.value : step.value;
|
|
1051
|
+
if (event.key === "Home") {
|
|
1052
|
+
return updateValue(min.value, thumbIndex);
|
|
1219
1053
|
}
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
touchId = touch.identifier;
|
|
1054
|
+
if (event.key === "End") {
|
|
1055
|
+
return updateValue(max.value, thumbIndex);
|
|
1223
1056
|
}
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
const { newValue, activeIndex } = nextState;
|
|
1229
|
-
ensureFocusOnThumb({ index: activeIndex, shouldSetActive: true });
|
|
1230
|
-
emitChange(valueToArray(newValue));
|
|
1231
|
-
}
|
|
1057
|
+
if (INCREMENT_KEYS.has(event.key)) {
|
|
1058
|
+
updateValue(currentValue[thumbIndex] + stepSize, thumbIndex);
|
|
1059
|
+
} else if (DECREMENT_KEYS.has(event.key)) {
|
|
1060
|
+
updateValue(currentValue[thumbIndex] - stepSize, thumbIndex);
|
|
1232
1061
|
}
|
|
1233
|
-
movesSinceStart = 0;
|
|
1234
|
-
document.addEventListener("touchmove", handlePointerMove, {
|
|
1235
|
-
passive: true
|
|
1236
|
-
});
|
|
1237
|
-
document.addEventListener("touchend", handlePointerEnd);
|
|
1238
|
-
};
|
|
1239
|
-
const stopPointerListening = () => {
|
|
1240
|
-
document.removeEventListener("mousemove", handlePointerMove);
|
|
1241
|
-
document.removeEventListener("mouseup", handlePointerEnd);
|
|
1242
|
-
document.removeEventListener("touchmove", handlePointerMove);
|
|
1243
|
-
document.removeEventListener("touchend", handlePointerEnd);
|
|
1244
1062
|
};
|
|
1245
|
-
const
|
|
1246
|
-
if (isDisabled.value) {
|
|
1247
|
-
return;
|
|
1248
|
-
}
|
|
1249
|
-
if (event.button !== 0) {
|
|
1250
|
-
return;
|
|
1251
|
-
}
|
|
1252
|
-
if (event.defaultPrevented) {
|
|
1253
|
-
return;
|
|
1254
|
-
}
|
|
1063
|
+
const handlePointerdown = (event) => {
|
|
1255
1064
|
event.preventDefault();
|
|
1256
|
-
const
|
|
1257
|
-
if (
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
const
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
}
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
});
|
|
1269
|
-
document.addEventListener("mouseup", handlePointerEnd);
|
|
1270
|
-
};
|
|
1271
|
-
const handleHiddenInputChange = (event) => {
|
|
1272
|
-
if (isDisabled.value) {
|
|
1273
|
-
return;
|
|
1274
|
-
}
|
|
1275
|
-
const value = event.target.valueAsNumber;
|
|
1276
|
-
commitValueFromEvent(event, value);
|
|
1065
|
+
const value = getValueFromCoordinates(event.x);
|
|
1066
|
+
if (value == void 0) return;
|
|
1067
|
+
const thumb = normalizedValue.value.reduce(
|
|
1068
|
+
(previous, thumbValue, index) => {
|
|
1069
|
+
const distance = Math.abs(thumbValue - value);
|
|
1070
|
+
if (distance < previous.distance) return { index, distance };
|
|
1071
|
+
return previous;
|
|
1072
|
+
},
|
|
1073
|
+
{ index: 0, distance: Number.POSITIVE_INFINITY }
|
|
1074
|
+
);
|
|
1075
|
+
updateValue(value, thumb.index);
|
|
1076
|
+
draggingThumbIndex.value = thumb.index;
|
|
1277
1077
|
};
|
|
1278
|
-
const
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
};
|
|
1284
|
-
const handleHiddenInputBlur = (event) => {
|
|
1285
|
-
if (!isFocusVisible(event.target)) {
|
|
1286
|
-
activeThumbIndex.value = -1;
|
|
1287
|
-
}
|
|
1078
|
+
const handlePointermove = (event) => {
|
|
1079
|
+
if (draggingThumbIndex.value == void 0) return;
|
|
1080
|
+
const value = getValueFromCoordinates(event.x);
|
|
1081
|
+
if (value == void 0) return;
|
|
1082
|
+
updateValue(value, draggingThumbIndex.value);
|
|
1288
1083
|
};
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
}
|
|
1297
|
-
if (!isDiscrete.value) {
|
|
1298
|
-
const stepSize = event.shiftKey ? shiftStep.value : step.value;
|
|
1299
|
-
if (event.key === "Home") return commitValueFromEvent(event, min.value);
|
|
1300
|
-
if (event.key === "End") return commitValueFromEvent(event, max.value);
|
|
1301
|
-
if (INCREMENT_KEYS.has(event.key)) {
|
|
1302
|
-
const next = MathUtils.clamp(value + stepSize, min.value, max.value);
|
|
1303
|
-
if (next !== value) commitValueFromEvent(event, next);
|
|
1304
|
-
return;
|
|
1305
|
-
}
|
|
1306
|
-
if (DECREMENT_KEYS.has(event.key)) {
|
|
1307
|
-
const next = MathUtils.clamp(value - stepSize, min.value, max.value);
|
|
1308
|
-
if (next !== value) commitValueFromEvent(event, next);
|
|
1309
|
-
return;
|
|
1310
|
-
}
|
|
1311
|
-
return;
|
|
1312
|
-
} else {
|
|
1313
|
-
const values = marksValues.value;
|
|
1314
|
-
const lastIndex = values.length - 1;
|
|
1315
|
-
const currentIndex = values.indexOf(value);
|
|
1316
|
-
const first = values[0];
|
|
1317
|
-
const last = values[lastIndex];
|
|
1318
|
-
if (event.key === "Home" && typeof first === "number")
|
|
1319
|
-
return commitValueFromEvent(event, first);
|
|
1320
|
-
if (event.key === "End" && typeof last === "number")
|
|
1321
|
-
return commitValueFromEvent(event, last);
|
|
1322
|
-
if (INCREMENT_KEYS.has(event.key)) {
|
|
1323
|
-
const nextIdx = currentIndex < 0 ? 0 : Math.min(lastIndex, currentIndex + 1);
|
|
1324
|
-
const next = values[nextIdx];
|
|
1325
|
-
if (next !== value && typeof next === "number") commitValueFromEvent(event, next);
|
|
1326
|
-
return;
|
|
1327
|
-
}
|
|
1328
|
-
if (DECREMENT_KEYS.has(event.key)) {
|
|
1329
|
-
const nextIdx = currentIndex < 0 ? 0 : Math.max(0, currentIndex - 1);
|
|
1330
|
-
const next = values[nextIdx];
|
|
1331
|
-
if (next !== value && typeof next === "number") commitValueFromEvent(event, next);
|
|
1332
|
-
return;
|
|
1333
|
-
}
|
|
1334
|
-
}
|
|
1084
|
+
useGlobalEventListener({
|
|
1085
|
+
type: "pointermove",
|
|
1086
|
+
listener: handlePointermove,
|
|
1087
|
+
disabled: computed(() => draggingThumbIndex.value == void 0)
|
|
1088
|
+
});
|
|
1089
|
+
const handlePointerup = () => {
|
|
1090
|
+
draggingThumbIndex.value = void 0;
|
|
1335
1091
|
};
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
const trackStyle = computed(() => ({
|
|
1347
|
-
left: `${trackOffset.value}%`,
|
|
1348
|
-
width: `${trackLength.value}%`
|
|
1349
|
-
}));
|
|
1350
|
-
onBeforeUnmount(stopPointerListening);
|
|
1351
|
-
watch(
|
|
1352
|
-
() => isDisabled.value,
|
|
1353
|
-
() => {
|
|
1354
|
-
if (isDisabled.value) {
|
|
1355
|
-
isDragging.value = false;
|
|
1356
|
-
activeThumbIndex.value = -1;
|
|
1357
|
-
stopPointerListening();
|
|
1358
|
-
}
|
|
1359
|
-
}
|
|
1360
|
-
);
|
|
1361
|
-
const adjustMarkPosition = (percentage, offset) => {
|
|
1362
|
-
if (offset && percentage <= 0) return offset;
|
|
1363
|
-
if (offset && percentage >= 100) return `calc(100% - ${offset})`;
|
|
1364
|
-
return `${percentage}%`;
|
|
1092
|
+
useGlobalEventListener({
|
|
1093
|
+
type: "pointerup",
|
|
1094
|
+
listener: handlePointerup,
|
|
1095
|
+
disabled: computed(() => draggingThumbIndex.value == void 0)
|
|
1096
|
+
});
|
|
1097
|
+
const getValueFromCoordinates = (x) => {
|
|
1098
|
+
const rect = sliderRef.value.getBoundingClientRect();
|
|
1099
|
+
if (rect.width <= 0) return;
|
|
1100
|
+
const percent = MathUtils.clamp((x - rect.left) / rect.width, 0, 1);
|
|
1101
|
+
return MathUtils.percentToValue(percent, min.value, max.value);
|
|
1365
1102
|
};
|
|
1366
1103
|
return {
|
|
1367
1104
|
elements: {
|
|
1368
1105
|
/**
|
|
1369
1106
|
* Root slider container element
|
|
1370
1107
|
*/
|
|
1371
|
-
root: computed(() =>
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1108
|
+
root: computed(() => {
|
|
1109
|
+
const events = {
|
|
1110
|
+
onPointerdown: handlePointerdown
|
|
1111
|
+
};
|
|
1112
|
+
return {
|
|
1113
|
+
ref: sliderRef,
|
|
1114
|
+
style: { touchAction: "pan-y" },
|
|
1115
|
+
...toValue(options.disabled) ? void 0 : events
|
|
1116
|
+
};
|
|
1117
|
+
}),
|
|
1377
1118
|
/**
|
|
1378
1119
|
* Individual thumb elements for each value (span)
|
|
1379
1120
|
*/
|
|
1380
1121
|
thumbContainer: computed(() => (data) => ({
|
|
1381
|
-
|
|
1382
|
-
style: {
|
|
1383
|
-
left: `${MathUtils.valueToPercent(data.value, min.value, max.value)}%`
|
|
1384
|
-
}
|
|
1122
|
+
style: { left: `${getValueInPercentage.value(data.value)}%` }
|
|
1385
1123
|
})),
|
|
1386
1124
|
/**
|
|
1387
|
-
*
|
|
1125
|
+
* Input inside each thumb for accessibility
|
|
1388
1126
|
*/
|
|
1389
|
-
thumbInput: computed(() => (data) =>
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
})
|
|
1127
|
+
thumbInput: computed(() => (data) => {
|
|
1128
|
+
const events = {
|
|
1129
|
+
onKeydown: (event) => handleKeydown(event, data.index)
|
|
1130
|
+
};
|
|
1131
|
+
return {
|
|
1132
|
+
min: min.value,
|
|
1133
|
+
max: max.value,
|
|
1134
|
+
value: data.value,
|
|
1135
|
+
role: "slider",
|
|
1136
|
+
type: "range",
|
|
1137
|
+
"aria-label": toValue(options.label),
|
|
1138
|
+
"aria-valuemin": min.value,
|
|
1139
|
+
"aria-valuemax": max.value,
|
|
1140
|
+
"aria-valuenow": data.value,
|
|
1141
|
+
"aria-orientation": "horizontal",
|
|
1142
|
+
step: step.value,
|
|
1143
|
+
disabled: toValue(options.disabled),
|
|
1144
|
+
...toValue(options.disabled) ? void 0 : events
|
|
1145
|
+
};
|
|
1146
|
+
}),
|
|
1409
1147
|
/**
|
|
1410
|
-
* Mark
|
|
1148
|
+
* Single Mark element inside the rail
|
|
1411
1149
|
*/
|
|
1412
1150
|
mark: computed(() => (data) => {
|
|
1413
|
-
const percentage =
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1151
|
+
const percentage = getValueInPercentage.value(data.value);
|
|
1152
|
+
let position = `${percentage}%`;
|
|
1153
|
+
if (data.positionOffset && percentage <= 0) {
|
|
1154
|
+
position = data.positionOffset;
|
|
1155
|
+
}
|
|
1156
|
+
if (data.positionOffset && percentage >= 100) {
|
|
1157
|
+
position = `calc(100% - ${data.positionOffset})`;
|
|
1158
|
+
}
|
|
1419
1159
|
return {
|
|
1420
|
-
"data-value": data.value,
|
|
1421
1160
|
"aria-hidden": true,
|
|
1422
1161
|
style: { left: position }
|
|
1423
1162
|
};
|
|
@@ -1425,83 +1164,46 @@ const _unstableCreateSlider = createBuilder(
|
|
|
1425
1164
|
/**
|
|
1426
1165
|
* Label for each mark
|
|
1427
1166
|
*/
|
|
1428
|
-
markLabel: computed(() => (data) =>
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1167
|
+
markLabel: computed(() => (data) => {
|
|
1168
|
+
const left = getValueInPercentage.value(data.value);
|
|
1169
|
+
let translate = "-50%";
|
|
1170
|
+
if (left === 0) {
|
|
1171
|
+
translate = "0%";
|
|
1172
|
+
} else if (left === 100) {
|
|
1173
|
+
translate = "-100%";
|
|
1174
|
+
}
|
|
1175
|
+
return {
|
|
1176
|
+
"aria-hidden": true,
|
|
1177
|
+
style: {
|
|
1178
|
+
left: `${left}%`,
|
|
1179
|
+
transform: translate ? `translateX(${translate})` : void 0
|
|
1180
|
+
}
|
|
1181
|
+
};
|
|
1182
|
+
}),
|
|
1435
1183
|
/**
|
|
1436
1184
|
* Track element representing the selected range
|
|
1437
1185
|
*/
|
|
1438
|
-
track: computed(() =>
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1186
|
+
track: computed(() => {
|
|
1187
|
+
const isRange = normalizedValue.value.length > 1;
|
|
1188
|
+
const offsetValue = isRange ? normalizedValue.value[0] : min.value;
|
|
1189
|
+
const left = getValueInPercentage.value(offsetValue);
|
|
1190
|
+
const lengthValue = normalizedValue.value.at(-1);
|
|
1191
|
+
const width = getValueInPercentage.value(lengthValue) - left;
|
|
1192
|
+
return {
|
|
1193
|
+
style: {
|
|
1194
|
+
left: `${left}%`,
|
|
1195
|
+
width: `${width}%`
|
|
1196
|
+
}
|
|
1197
|
+
};
|
|
1198
|
+
})
|
|
1450
1199
|
},
|
|
1451
1200
|
state: {
|
|
1452
|
-
|
|
1453
|
-
* True if the slider is currently being dragged.
|
|
1454
|
-
*/
|
|
1455
|
-
isDragging,
|
|
1456
|
-
/**
|
|
1457
|
-
* Index of the currently active thumb.
|
|
1458
|
-
* Thumb could be active even if not dragging (e.g. click on the rail to move the thumb there).
|
|
1459
|
-
* `-1` if no thumb is active.
|
|
1460
|
-
*/
|
|
1461
|
-
activeThumbIndex,
|
|
1462
|
-
/**
|
|
1463
|
-
* `true` if the slider is a range slider (with two or more thumbs).
|
|
1464
|
-
*/
|
|
1465
|
-
isRange,
|
|
1466
|
-
/**
|
|
1467
|
-
* Offset of the track as a percentage (0-100).
|
|
1468
|
-
*/
|
|
1469
|
-
trackOffset,
|
|
1470
|
-
/**
|
|
1471
|
-
* Length of the track as a percentage (0-100).
|
|
1472
|
-
*/
|
|
1473
|
-
trackLength,
|
|
1474
|
-
/**
|
|
1475
|
-
* List of marks to display on the slider.
|
|
1476
|
-
* - If marks option is `true`, marks are generated based on the step value.
|
|
1477
|
-
* - If marks option is an array of numbers or objects, it is used as provided (filtered to be within range).
|
|
1478
|
-
* - If marks option is `false`, no marks are shown.
|
|
1479
|
-
*/
|
|
1480
|
-
marksList,
|
|
1481
|
-
/**
|
|
1482
|
-
* Step size when holding shift key or using Page Up/Page Down keys.
|
|
1483
|
-
*/
|
|
1201
|
+
normalizedValue,
|
|
1484
1202
|
shiftStep,
|
|
1485
|
-
|
|
1486
|
-
* Normalized slider values (clamped to min/max and rounded to nearest step/mark).
|
|
1487
|
-
*/
|
|
1488
|
-
normalizedValues
|
|
1203
|
+
marks
|
|
1489
1204
|
},
|
|
1490
1205
|
internals: {
|
|
1491
|
-
|
|
1492
|
-
* Clamps a value to the slider's range.
|
|
1493
|
-
* @param value - value to clamp
|
|
1494
|
-
* @returns clamped value
|
|
1495
|
-
*/
|
|
1496
|
-
clampValue: computed(() => (value) => MathUtils.clamp(value, min.value, max.value)),
|
|
1497
|
-
/**
|
|
1498
|
-
* Rounds a value to the nearest valid step.
|
|
1499
|
-
* @param value - value to round
|
|
1500
|
-
* @returns rounded value
|
|
1501
|
-
*/
|
|
1502
|
-
roundToStep: computed(
|
|
1503
|
-
() => (value) => !isDiscrete.value ? roundToStep(value, step.value, min.value) : marksValues.value[findClosestIndex(marksValues.value, value)]
|
|
1504
|
-
)
|
|
1206
|
+
updateValue
|
|
1505
1207
|
}
|
|
1506
1208
|
};
|
|
1507
1209
|
}
|