Don't select text when shift is held

This commit is contained in:
SergeantPanda 2025-04-29 12:47:16 -05:00
parent 7503ef9dd2
commit 9be42ce532
2 changed files with 194 additions and 75 deletions

View file

@ -7,7 +7,7 @@ import {
getCoreRowModel,
flexRender,
} from '@tanstack/react-table';
import { useCallback, useMemo, useState } from 'react';
import { useCallback, useMemo, useState, useEffect } from 'react';
import { ChevronDown, ChevronRight } from 'lucide-react';
const useTable = ({
@ -22,6 +22,63 @@ const useTable = ({
const [selectedTableIds, setSelectedTableIds] = useState([]);
const [expandedRowIds, setExpandedRowIds] = useState([]);
const [lastClickedId, setLastClickedId] = useState(null);
const [isShiftKeyDown, setIsShiftKeyDown] = useState(false);
// Event handlers for shift key detection with improved handling
const handleKeyDown = useCallback((e) => {
if (e.key === 'Shift') {
setIsShiftKeyDown(true);
// Apply the class to disable text selection immediately
document.body.classList.add('shift-key-active');
// Set a style attribute directly on body for extra assurance
document.body.style.userSelect = 'none';
document.body.style.webkitUserSelect = 'none';
document.body.style.msUserSelect = 'none';
document.body.style.cursor = 'pointer';
}
}, []);
const handleKeyUp = useCallback((e) => {
if (e.key === 'Shift') {
setIsShiftKeyDown(false);
// Remove the class when shift is released
document.body.classList.remove('shift-key-active');
// Reset the style attributes
document.body.style.removeProperty('user-select');
document.body.style.removeProperty('-webkit-user-select');
document.body.style.removeProperty('-ms-user-select');
document.body.style.removeProperty('cursor');
}
}, []);
// Add global event listeners for shift key detection with improved cleanup
useEffect(() => {
window.addEventListener('keydown', handleKeyDown);
window.addEventListener('keyup', handleKeyUp);
// Also detect blur/focus events to handle cases where shift is held and window loses focus
window.addEventListener('blur', () => {
setIsShiftKeyDown(false);
document.body.classList.remove('shift-key-active');
document.body.style.removeProperty('user-select');
document.body.style.removeProperty('-webkit-user-select');
document.body.style.removeProperty('-ms-user-select');
document.body.style.removeProperty('cursor');
});
return () => {
window.removeEventListener('keydown', handleKeyDown);
window.removeEventListener('keyup', handleKeyUp);
window.removeEventListener('blur', () => {
setIsShiftKeyDown(false);
document.body.classList.remove('shift-key-active');
document.body.style.removeProperty('user-select');
document.body.style.removeProperty('-webkit-user-select');
document.body.style.removeProperty('-ms-user-select');
document.body.style.removeProperty('cursor');
});
};
}, [handleKeyDown, handleKeyUp]);
const rowCount = allRowIds.length;
@ -175,8 +232,9 @@ const useTable = ({
expandedRowIds,
expandedRowRenderer,
setSelectedTableIds,
isShiftKeyDown, // Include shift key state in the table instance
}),
[selectedTableIdsSet, expandedRowIds, allRowIds]
[selectedTableIdsSet, expandedRowIds, allRowIds, isShiftKeyDown]
);
return {

View file

@ -1,94 +1,155 @@
* {
/* box-sizing: border-box; */
}
/* box-sizing: border-box; */
}
html {
font-family: sans-serif;
/* font-size: 14px; */
}
html {
font-family: sans-serif;
/* font-size: 14px; */
}
.divTable {
/* border: 1px solid lightgray; */
/* width: fit-content; */
/* display: flex;
.divTable {
/* border: 1px solid lightgray; */
/* width: fit-content; */
/* display: flex;
flex-direction: column; */
}
}
.tr {
display: flex;
}
.tr {
display: flex;
}
.table-striped .tbody .tr:hover {
background-color: rgb(68,68,68);
}
.table-striped .tbody .tr:hover {
background-color: rgb(68, 68, 68);
}
.tr {
/* width: fit-content;
.tr {
/* width: fit-content;
width: 100%; */
/* height: 30px; */
}
/* height: 30px; */
}
.th,
.td {
/* box-shadow: inset 0 0 0 1px lightgray; */
/* padding: 0.25rem; */
padding-left: 4px;
padding-right: 4px;
}
.th,
.td {
/* box-shadow: inset 0 0 0 1px lightgray; */
/* padding: 0.25rem; */
padding-left: 4px;
padding-right: 4px;
}
.th {
/* padding: 2px 4px; */
position: relative;
font-weight: bold;
text-align: center;
/* height: 30px; */
}
.th {
/* padding: 2px 4px; */
position: relative;
font-weight: bold;
text-align: center;
/* height: 30px; */
}
.td {
height: 28px;
border-bottom: solid 1px rgb(68,68,68);
}
.td {
height: 28px;
border-bottom: solid 1px rgb(68, 68, 68);
}
.resizer {
position: absolute;
top: 0;
height: 100%;
width: 5px;
background: rgba(0, 0, 0, 0.5);
cursor: col-resize;
user-select: none;
touch-action: none;
}
.resizer.ltr {
right: 0;
}
.resizer.rtl {
left: 0;
}
.resizer.isResizing {
background: blue;
opacity: 1;
}
@media (hover: hover) {
.resizer {
position: absolute;
top: 0;
height: 100%;
width: 5px;
background: rgba(0, 0, 0, 0.5);
cursor: col-resize;
user-select: none;
touch-action: none;
opacity: 0;
}
.resizer.ltr {
right: 0;
}
.resizer.rtl {
left: 0;
}
.resizer.isResizing {
background: blue;
*:hover>.resizer {
opacity: 1;
}
}
@media (hover: hover) {
.resizer {
opacity: 0;
}
/* .table-striped .tbody .tr:nth-child(odd), */
.table-striped .tbody .tr-odd {
background-color: #18181b;
}
*:hover > .resizer {
opacity: 1;
}
}
/* .table-striped .tbody .tr:nth-child(even), */
.table-striped .tbody .tr-even {
background-color: #27272A;
}
/* .table-striped .tbody .tr:nth-child(odd), */
.table-striped .tbody .tr-odd {
background-color: #18181b;
}
/* Prevent text selection when shift key is pressed */
.shift-key-active {
cursor: pointer !important;
}
/* .table-striped .tbody .tr:nth-child(even), */
.table-striped .tbody .tr-even {
background-color: #27272A;
}
.shift-key-active *,
.shift-key-active .tr,
.shift-key-active .td,
.shift-key-active .tbody {
user-select: none !important;
-webkit-user-select: none !important;
-moz-user-select: none !important;
-ms-user-select: none !important;
}
/* Always allow text selection in editable elements */
.shift-key-active input,
.shift-key-active textarea,
.shift-key-active [contenteditable="true"],
.shift-key-active .table-input-header input {
user-select: text !important;
-webkit-user-select: text !important;
-moz-user-select: text !important;
-ms-user-select: text !important;
cursor: text !important;
}
/* Improve specificity and ensure text selection is disabled when shift is pressed */
.shift-key-active,
.shift-key-active * {
user-select: none !important;
-webkit-user-select: none !important;
-moz-user-select: none !important;
-ms-user-select: none !important;
cursor: pointer !important;
}
/* Add a visual indicator when shift is pressed */
.shift-key-active .tbody .tr {
transition: background-color 0.1s;
}
.shift-key-active .tbody .tr:hover {
background-color: rgba(68, 68, 68, 0.7) !important;
}
/* Always allow text selection in inputs even when shift is pressed */
.shift-key-active input,
.shift-key-active textarea,
.shift-key-active [contenteditable="true"],
.shift-key-active select,
.shift-key-active .mantine-Select-input,
.shift-key-active .mantine-MultiSelect-input,
.shift-key-active .table-input-header input {
user-select: text !important;
-webkit-user-select: text !important;
-moz-user-select: text !important;
-ms-user-select: text !important;
cursor: text !important;
}