Add snap to table scrolls

This commit is contained in:
IRBorisov 2024-05-02 21:19:23 +03:00
parent ff48364536
commit 91c5993b10
14 changed files with 37 additions and 24 deletions

View File

@ -94,7 +94,7 @@ function ConstituentaMultiPicker({ id, schema, prefixID, rows, selected, setSele
noFooter
rows={rows}
contentHeight='1.3rem'
className={clsx('overflow-y-auto', 'border', 'text-sm', 'select-none')}
className={clsx('cc-scroll-y', 'border', 'text-sm', 'select-none')}
data={schema?.items ?? []}
columns={columns}
headPosition='0rem'

View File

@ -101,7 +101,7 @@ function ConstituentaPicker({
dense
noHeader
noFooter
className='overflow-y-auto text-sm select-none'
className='text-sm select-none cc-scroll-y'
data={filteredData}
columns={columns}
conditionalRowStyles={conditionalRowStyles}

View File

@ -98,7 +98,7 @@ function SchemaPicker({ id, initialFilter = '', rows = 4, value, onSelectValue }
dense
noHeader
noFooter
className='overflow-y-auto text-sm select-none'
className='text-sm select-none cc-scroll-y'
data={items}
columns={columns}
conditionalRowStyles={conditionalRowStyles}

View File

@ -155,6 +155,7 @@ function DataTable<TData extends RowData>({
<TableBody
table={tableImpl}
dense={dense}
noHeader={noHeader}
conditionalRowStyles={conditionalRowStyles}
enableRowSelection={enableRowSelection}
lastSelected={lastSelected}

View File

@ -1,4 +1,5 @@
import { Cell, flexRender, Row, Table } from '@tanstack/react-table';
import clsx from 'clsx';
import { CProps } from '@/components/props';
@ -8,6 +9,7 @@ import SelectRow from './SelectRow';
interface TableBodyProps<TData> {
table: Table<TData>;
dense?: boolean;
noHeader?: boolean;
enableRowSelection?: boolean;
conditionalRowStyles?: IConditionalStyle<TData>[];
@ -21,6 +23,7 @@ interface TableBodyProps<TData> {
function TableBody<TData>({
table,
dense,
noHeader,
enableRowSelection,
conditionalRowStyles,
lastSelected,
@ -67,14 +70,16 @@ function TableBody<TData>({
{table.getRowModel().rows.map((row: Row<TData>, index) => (
<tr
key={row.id}
className={
className={clsx(
'cc-table-row',
!noHeader && 'scroll-mt-[calc(2px+2rem)]',
row.getIsSelected()
? 'clr-selected clr-hover'
: index % 2 === 0
? 'clr-controls clr-hover'
: 'clr-app clr-hover'
}
style={conditionalRowStyles && getRowStyles(row)}
)}
style={{ ...(conditionalRowStyles ? getRowStyles(row) : []) }}
>
{enableRowSelection ? (
<td key={`select-${row.id}`} className='pl-3 pr-1 align-middle border-y'>

View File

@ -152,7 +152,7 @@ function ArgumentsTab({ state, schema, partialUpdate }: ArgumentsTabProps) {
noHeader
className={clsx(
'max-h-[5.8rem] min-h-[5.8rem]', // prettier: split lines
'overflow-y-auto',
'cc-scroll-y',
'text-sm',
'border',
'select-none'

View File

@ -92,10 +92,10 @@ function VersionsTable({ processing, items, onDelete, selected, onSelect }: Vers
<DataTable
dense
noFooter
className={clsx('mb-2', 'max-h-[17.4rem] min-h-[17.4rem]', 'border', 'overflow-y-auto')}
headPosition='0'
className={clsx('mb-2', 'max-h-[17.4rem] min-h-[17.4rem]', 'border', 'cc-scroll-y')}
data={items}
columns={columns}
headPosition='0'
onRowClicked={rowData => onSelect(rowData.id)}
conditionalRowStyles={conditionalRowStyles}
/>

View File

@ -37,7 +37,6 @@ function WordFormsTable({ forms, setForms, onFormSelect }: WordFormsTableProps)
() => [
columnHelper.accessor('text', {
id: 'text',
header: 'Текст',
size: 350,
minSize: 500,
maxSize: 500,
@ -45,7 +44,6 @@ function WordFormsTable({ forms, setForms, onFormSelect }: WordFormsTableProps)
}),
columnHelper.accessor('grams', {
id: 'grams',
header: 'Граммемы',
maxSize: 150,
cell: props => <WordFormBadge keyPrefix={props.cell.id} form={props.row.original} />
}),
@ -74,7 +72,8 @@ function WordFormsTable({ forms, setForms, onFormSelect }: WordFormsTableProps)
<DataTable
dense
noFooter
className={clsx('mb-2', 'max-h-[17.4rem] min-h-[17.4rem]', 'border', 'text-sm', 'overflow-y-auto')}
noHeader
className={clsx('mb-2', 'max-h-[17.4rem] min-h-[17.4rem]', 'border', 'text-sm', 'cc-scroll-y')}
data={forms}
columns={columns}
headPosition='0'

View File

@ -7,7 +7,6 @@ import DataLoader from '@/components/wrap/DataLoader';
import { useAuth } from '@/context/AuthContext';
import { useLibrary } from '@/context/LibraryContext';
import { useConceptNavigation } from '@/context/NavigationContext';
import { useConceptOptions } from '@/context/OptionsContext';
import useLocalStorage from '@/hooks/useLocalStorage';
import useQueryStrings from '@/hooks/useQueryStrings';
import { ILibraryItem } from '@/models/library';
@ -26,7 +25,6 @@ function LibraryPage() {
const { user } = useAuth();
const library = useLibrary();
const { setShowScroll } = useConceptOptions();
const [filter, setFilter] = useState<ILibraryFilter>({});
const [items, setItems] = useState<ILibraryItem[]>([]);
@ -47,11 +45,6 @@ function LibraryPage() {
setFilter(filterFromStrategy(queryFilter));
}, [user, router, setQuery, setFilter, setStrategy, strategy, queryFilter]);
useLayoutEffect(() => {
setShowScroll(true);
return () => setShowScroll(false);
}, [setShowScroll]);
useLayoutEffect(() => {
setItems(library.applyFilter(filter));
}, [library, filter, filter.query]);

View File

@ -11,6 +11,7 @@ import DataTable, { createColumnHelper, VisibilityState } from '@/components/ui/
import FlexColumn from '@/components/ui/FlexColumn';
import TextURL from '@/components/ui/TextURL';
import { useConceptNavigation } from '@/context/NavigationContext';
import { useConceptOptions } from '@/context/OptionsContext';
import { useUsers } from '@/context/UsersContext';
import useLocalStorage from '@/hooks/useLocalStorage';
import useWindowSize from '@/hooks/useWindowSize';
@ -31,6 +32,7 @@ function ViewLibrary({ items, resetQuery }: ViewLibraryProps) {
const router = useConceptNavigation();
const intl = useIntl();
const { getUserLabel } = useUsers();
const { calculateHeight } = useConceptOptions();
const [itemsPerPage, setItemsPerPage] = useLocalStorage<number>(storage.libraryPagination, 50);
function handleOpenItem(item: ILibraryItem, event: CProps.EventMouse) {
@ -109,6 +111,8 @@ function ViewLibrary({ items, resetQuery }: ViewLibraryProps) {
[intl, getUserLabel, windowSize]
);
const tableHeight = useMemo(() => calculateHeight('2.2rem'), [calculateHeight]);
return (
<>
<div className='sticky top-[2.3rem]'>
@ -127,8 +131,9 @@ function ViewLibrary({ items, resetQuery }: ViewLibraryProps) {
id='library_data'
columns={columns}
data={items}
headPosition='2.2rem'
className='text-xs sm:text-sm'
headPosition='0'
className='text-xs sm:text-sm cc-scroll-y'
style={{ maxHeight: tableHeight }}
noDataComponent={
<FlexColumn className='p-3 items-center min-h-[6rem]'>
<p>Список схем пуст</p>

View File

@ -121,7 +121,7 @@ function RSTable({ items, maxHeight, enableSelection, selected, setSelected, onE
<DataTable
dense
noFooter
className={clsx('min-h-[16rem]', 'overflow-y-auto', 'text-sm', 'select-none')}
className={clsx('min-h-[16rem]', 'cc-scroll-y', 'text-sm', 'select-none')}
style={{ maxHeight: maxHeight }}
data={items ?? []}
columns={columns}

View File

@ -129,7 +129,7 @@ function ConstituentsTable({ items, activeID, onOpenEdit, maxHeight, denseThresh
<DataTable
dense
noFooter
className='overflow-y-auto text-sm select-none overscroll-none'
className='text-sm select-none cc-scroll-y overscroll-none'
style={{ maxHeight: maxHeight }}
data={items}
columns={columns}

View File

@ -65,7 +65,7 @@ function ViewSubscriptions({ items }: ViewSubscriptionsProps) {
<DataTable
dense
noFooter
className='max-h-[23.8rem] overflow-y-auto text-sm border'
className='max-h-[23.8rem] cc-scroll-y text-sm border'
columns={columns}
data={items}
headPosition='0'

View File

@ -216,6 +216,16 @@
@apply flex gap-1;
}
.cc-table-row {
scroll-snap-align: start;
scroll-snap-stop: always;
}
.cc-scroll-y {
overflow-y: auto;
scroll-snap-type: y mandatory;
}
.cc-blur {
backdrop-filter: blur(3px);
}