mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
Add snap to table scrolls
This commit is contained in:
parent
ff48364536
commit
91c5993b10
|
@ -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'
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -155,6 +155,7 @@ function DataTable<TData extends RowData>({
|
|||
<TableBody
|
||||
table={tableImpl}
|
||||
dense={dense}
|
||||
noHeader={noHeader}
|
||||
conditionalRowStyles={conditionalRowStyles}
|
||||
enableRowSelection={enableRowSelection}
|
||||
lastSelected={lastSelected}
|
||||
|
|
|
@ -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'>
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user