feat(tgu-ui): Shift+клик ближе к якорю сжимает выделение полосы
This commit is contained in:
@@ -781,7 +781,8 @@ export function TguSlotsTab({ range }: TguSlotsTabProps) {
|
|||||||
return !(slot && slotIsBusy(slot));
|
return !(slot && slotIsBusy(slot));
|
||||||
});
|
});
|
||||||
setSelectedKeys((current) => selectStripRange(current, members, anchorKey, targetKey));
|
setSelectedKeys((current) => selectStripRange(current, members, anchorKey, targetKey));
|
||||||
setAnchorKey(targetKey);
|
// Якорь НЕ двигаем: остаётся первым кликом, чтобы повторный Shift+клик задавал диапазон
|
||||||
|
// от того же якоря — ближе к нему «сжимал» выделение, дальше — расширял.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setSelectedKeys((current) =>
|
setSelectedKeys((current) =>
|
||||||
|
|||||||
@@ -60,6 +60,20 @@ describe("selectStripRange", () => {
|
|||||||
expect([...next]).toEqual(["c"]);
|
expect([...next]).toEqual(["c"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("сжимает выделение: повторный диапазон ближе к якорю снимает хвост полосы", () => {
|
||||||
|
// якорь "a", сначала растянули до "d" (a..d), потом Shift+клик по "b" → остаётся a..b, c и d сняты.
|
||||||
|
const expanded = selectStripRange(new Set(), members, "a", "d");
|
||||||
|
expect([...expanded].sort()).toEqual(["a", "b", "c", "d"]);
|
||||||
|
const shrunk = selectStripRange(expanded, members, "a", "b");
|
||||||
|
expect([...shrunk].sort()).toEqual(["a", "b"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("снимает хвост полосы, но не трогает выбор в других полосах", () => {
|
||||||
|
const current = new Set(["a", "b", "c", "d", "x"]);
|
||||||
|
const next = selectStripRange(current, members, "a", "b");
|
||||||
|
expect([...next].sort()).toEqual(["a", "b", "x"]);
|
||||||
|
});
|
||||||
|
|
||||||
it("сохраняет уже выбранное за пределами полосы", () => {
|
it("сохраняет уже выбранное за пределами полосы", () => {
|
||||||
const next = selectStripRange(new Set(["x"]), members, "a", "b");
|
const next = selectStripRange(new Set(["x"]), members, "a", "b");
|
||||||
expect([...next].sort()).toEqual(["a", "b", "x"]);
|
expect([...next].sort()).toEqual(["a", "b", "x"]);
|
||||||
|
|||||||
@@ -40,15 +40,17 @@ export function selectionAfterCheck(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Новое множество выбора после жеста «полоса от первого к последнему»: добавляет всех членов
|
* Новое множество выбора после жеста «полоса от первого к последнему»: выбор полосы становится
|
||||||
* полосы между fromKey и toKey включительно (в порядке времени). Это ВЫДЕЛЕНИЕ, не toggle —
|
* РОВНО диапазоном [fromKey..toKey] (в порядке времени). Члены полосы вне диапазона снимаются —
|
||||||
* существующий выбор сохраняется. Жест ограничен одной полосой: вызывающий передаёт members
|
* так Shift+клик по слоту ближе к якорю «сжимает» выделение. Выбор за пределами полосы (другие
|
||||||
* именно её (один КА, один крен, подряд по времени); граница полосы — гарантия «нельзя выделить
|
* полосы/КА) сохраняется: снимаем/добавляем только ключи из members. Жест ограничен одной полосой:
|
||||||
* не полосу». Если fromKey или toKey не из members — выбор не меняется (страховка). Вход не мутируется.
|
* вызывающий передаёт members именно её (один КА, один крен, подряд по времени); граница полосы —
|
||||||
|
* гарантия «нельзя выделить не полосу». Если fromKey или toKey не из members — выбор не меняется
|
||||||
|
* (страховка). Вход не мутируется.
|
||||||
*
|
*
|
||||||
* @param current Текущее множество выбранных ключей.
|
* @param current Текущее множество выбранных ключей.
|
||||||
* @param members Ключи членов полосы в порядке времени.
|
* @param members Ключи членов полосы в порядке времени.
|
||||||
* @param fromKey Ключ первого клика (якорь).
|
* @param fromKey Ключ якоря (первый клик).
|
||||||
* @param toKey Ключ второго клика.
|
* @param toKey Ключ второго клика.
|
||||||
*/
|
*/
|
||||||
export function selectStripRange(
|
export function selectStripRange(
|
||||||
@@ -63,7 +65,10 @@ export function selectStripRange(
|
|||||||
if (from < 0 || to < 0) return next
|
if (from < 0 || to < 0) return next
|
||||||
const lo = Math.min(from, to)
|
const lo = Math.min(from, to)
|
||||||
const hi = Math.max(from, to)
|
const hi = Math.max(from, to)
|
||||||
for (let i = lo; i <= hi; i++) next.add(members[i]!)
|
members.forEach((key, i) => {
|
||||||
|
if (i >= lo && i <= hi) next.add(key)
|
||||||
|
else next.delete(key)
|
||||||
|
})
|
||||||
return next
|
return next
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user