diff --git a/webapp/packages/core-blocks/src/FormControls/Checkboxes/CheckboxMarkup.tsx b/webapp/packages/core-blocks/src/FormControls/Checkboxes/CheckboxMarkup.tsx index 3c6b8d0ed9..fb71d93f70 100644 --- a/webapp/packages/core-blocks/src/FormControls/Checkboxes/CheckboxMarkup.tsx +++ b/webapp/packages/core-blocks/src/FormControls/Checkboxes/CheckboxMarkup.tsx @@ -20,12 +20,14 @@ export type CheckboxMod = 'primary' | 'surface' | 'small'; const checkboxStyles = css` checkbox { composes: theme-checkbox from global; + box-sizing: content-box !important; } checkbox-input { composes: theme-checkbox_native-control from global; } checkbox-background { composes: theme-checkbox__background from global; + box-sizing: border-box !important; } checkbox-checkmark { composes: theme-checkbox__checkmark from global; diff --git a/webapp/packages/core-blocks/src/useCombinedHandler.ts b/webapp/packages/core-blocks/src/useCombinedHandler.ts index 316eb6698b..cee48b0bab 100644 --- a/webapp/packages/core-blocks/src/useCombinedHandler.ts +++ b/webapp/packages/core-blocks/src/useCombinedHandler.ts @@ -7,7 +7,7 @@ */ import { useObjectRef } from './useObjectRef'; -export function useCombinedHandler(...handlers: Array<((...args: T) => any) | undefined>): (...args: T) => void { +export function useCombinedHandler(...handlers: Array<((...args: T) => any) | null | undefined>): (...args: T) => void { const optionsRef = useObjectRef({ handlers }); const state = useObjectRef( () => ({ diff --git a/webapp/packages/core-theming/src/styles/_branding.scss b/webapp/packages/core-theming/src/styles/_branding.scss index dc0a6eeb8e..9a2231a11a 100644 --- a/webapp/packages/core-theming/src/styles/_branding.scss +++ b/webapp/packages/core-theming/src/styles/_branding.scss @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. */ -@mixin stripes-background($color) { +@mixin stripes-background($color, $important: false) { // background-image: linear-gradient( // 45deg, // transparent 37.5%, @@ -18,7 +18,7 @@ // $color 100% // ); // background-size: 8px 8px; - background-color: $color; + background-color: $color #{if($important, '!important', '')}; } @mixin delimiter($color) { diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellEditor.m.css b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellEditor.m.css new file mode 100644 index 0000000000..8dd6684737 --- /dev/null +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellEditor.m.css @@ -0,0 +1,23 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2023 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +.editor { + composes: theme-typography--body2 from global; +} +.box { + position: absolute; + left: 0; + top: 0; + width: 0; + height: 100%; +} +.inlineEditor { + font-size: 12px; + left: -1px; + top: 0; +} diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellEditor/CellEditor.tsx b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellEditor.tsx similarity index 83% rename from webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellEditor/CellEditor.tsx rename to webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellEditor.tsx index b06883984b..ffcc6095ec 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellEditor/CellEditor.tsx +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellEditor.tsx @@ -9,33 +9,16 @@ import { observer } from 'mobx-react-lite'; import { forwardRef, useContext, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; import { usePopper } from 'react-popper'; -import styled, { css } from 'reshadow'; +import { s, useS } from '@cloudbeaver/core-blocks'; import { EventContext, EventStopPropagationFlag } from '@cloudbeaver/core-events'; import { InlineEditor } from '@cloudbeaver/core-ui'; import type { IResultSetElementKey, IResultSetRowKey } from '@cloudbeaver/plugin-data-viewer'; -import type { EditorProps } from '@cloudbeaver/plugin-react-data-grid'; - -import { DataGridContext, IColumnResizeInfo } from '../DataGridContext'; -import { TableDataContext } from '../TableDataContext'; - -const styles = css` - editor { - composes: theme-typography--body2 from global; - } - box { - position: absolute; - left: 0; - top: 0; - width: 0; - height: 100%; - } - InlineEditor { - font-size: 12px; - left: -1px; - top: 0; - } -`; +import type { RenderEditCellProps } from '@cloudbeaver/plugin-react-data-grid'; + +import style from './CellEditor.m.css'; +import { DataGridContext, IColumnResizeInfo } from './DataGridContext'; +import { TableDataContext } from './TableDataContext'; export interface IEditorRef { focus: () => void; @@ -43,7 +26,7 @@ export interface IEditorRef { const lockNavigation = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End', 'Enter']; -export const CellEditor = observer, 'row' | 'column' | 'onClose'>, IEditorRef>( +export const CellEditor = observer, 'row' | 'column' | 'onClose'>, IEditorRef>( forwardRef(function CellEditor({ row, column, onClose }, ref) { const dataGridContext = useContext(DataGridContext); const tableDataContext = useContext(TableDataContext); @@ -54,6 +37,7 @@ export const CellEditor = observer, 'row' | ' placement: 'right', modifiers: [{ name: 'flip', enabled: false }], }); + const styles = useS(style); if (!dataGridContext || !tableDataContext || column.columnDataIndex === null) { throw new Error('DataGridContext should be provided'); @@ -114,10 +98,10 @@ export const CellEditor = observer, 'row' | ' event.stopPropagation(); }; - return styled(styles)( - , 'row' | ' > { createPortal( - +
, 'row' | ' onChange={handleChange} onUndo={handleUndo} /> - , +
, dataGridContext.getEditorPortal()!, ) as any } -
, + ); }), ); diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellRenderer/CellContext.ts b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellRenderer/CellContext.ts index 0bb702b6ca..a9b221ea2c 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellRenderer/CellContext.ts +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellRenderer/CellContext.ts @@ -18,6 +18,7 @@ export interface ICellContext { position: CellPosition; isEditing: boolean; isSelected: boolean; + isFocused: boolean; editionState: DatabaseEditChangeType | null; } diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellRenderer/CellRenderer.tsx b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellRenderer/CellRenderer.tsx index 3353cbb247..e86adf0b1b 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellRenderer/CellRenderer.tsx +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/CellRenderer/CellRenderer.tsx @@ -9,7 +9,7 @@ import { computed, observable } from 'mobx'; import { observer } from 'mobx-react-lite'; import { useContext, useEffect } from 'react'; -import { getComputed, useMouse, useObjectRef, useObservableRef } from '@cloudbeaver/core-blocks'; +import { getComputed, useCombinedHandler, useMouse, useObjectRef, useObservableRef } from '@cloudbeaver/core-blocks'; import { EventContext, EventStopPropagationFlag } from '@cloudbeaver/core-events'; import { clsx } from '@cloudbeaver/core-utils'; import { DatabaseEditChangeType, IResultSetElementKey, IResultSetRowKey, isBooleanValuePresentationAvailable } from '@cloudbeaver/plugin-data-viewer'; @@ -22,7 +22,7 @@ import { TableDataContext } from '../TableDataContext'; import { CellContext } from './CellContext'; export const CellRenderer = observer>(function CellRenderer(props) { - const { row, column, isCellSelected, selectCell } = props; + const { row, column, isCellSelected, onDoubleClick, selectCell } = props; const dataGridContext = useContext(DataGridContext); const tableDataContext = useContext(TableDataContext); const selectionContext = useContext(DataGridSelectionContext); @@ -49,6 +49,9 @@ export const CellRenderer = observer @@ -120,7 +125,7 @@ export const CellRenderer = observer) { + doubleClick(args: any, event: React.MouseEvent) { if ( !this.isEditable(this.column) || // !this.dataGridContext.isGridInFocus() @@ -136,11 +141,9 @@ export const CellRenderer = observer () => editingContext.closeEditor(cellContext.position), []); + const handleDoubleClick = useCombinedHandler(state.doubleClick, onDoubleClick); return ( @@ -158,9 +162,8 @@ export const CellRenderer = observer ); diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/DataGridTable.tsx b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/DataGridTable.tsx index 7933561aa4..9ed01b9ccf 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/DataGridTable.tsx +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/DataGridTable.tsx @@ -27,6 +27,7 @@ import { } from '@cloudbeaver/plugin-data-viewer'; import type { DataGridHandle, Position } from '@cloudbeaver/plugin-react-data-grid'; import DataGrid from '@cloudbeaver/plugin-react-data-grid'; +import '@cloudbeaver/plugin-react-data-grid/lib/lib/styles.css'; import { CellPosition, EditingContext } from '../Editing/EditingContext'; import { useEditing } from '../Editing/useEditing'; @@ -293,7 +294,7 @@ export const DataGridTable = observer , }} rows={tableData.rows} rowKeyGetter={ResultSetDataKeysUtils.serialize} headerRowHeight={headerHeight} rowHeight={rowHeight} - components={{ - cellRenderer: CellRenderer, + renderers={{ + renderCell: (key, props) => , }} onSelectedCellChange={handleFocusChange} onColumnResize={(idx, width) => columnResize.execute({ column: idx, width })} diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatter.m.css b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatter.m.css new file mode 100644 index 0000000000..b8ec0b4eff --- /dev/null +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatter.m.css @@ -0,0 +1,26 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2023 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +.wrapper { + height: 100%; + display: flex; + overflow: hidden; + box-sizing: border-box; +} + +.container { + flex: 1; + overflow: hidden; +} + +.menuContainer { + width: 25px; + height: 100%; + box-sizing: border-box; + overflow: hidden; +} diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatter.tsx b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatter.tsx index aed928f2b6..3a11d52dfa 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatter.tsx +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatter.tsx @@ -7,42 +7,23 @@ */ import { observer } from 'mobx-react-lite'; import { useContext, useState } from 'react'; -import styled, { css } from 'reshadow'; -import { getComputed, useObjectRef } from '@cloudbeaver/core-blocks'; +import { getComputed, s, useObjectRef, useS } from '@cloudbeaver/core-blocks'; import type { IDataPresentationActions, IResultSetElementKey, IResultSetRowKey } from '@cloudbeaver/plugin-data-viewer'; -import type { FormatterProps } from '@cloudbeaver/plugin-react-data-grid'; +import type { RenderCellProps } from '@cloudbeaver/plugin-react-data-grid'; import { EditingContext } from '../../Editing/EditingContext'; import { CellContext } from '../CellRenderer/CellContext'; import { DataGridContext } from '../DataGridContext'; import { TableDataContext } from '../TableDataContext'; +import style from './CellFormatter.m.css'; import { CellFormatterFactory } from './CellFormatterFactory'; import { CellMenu } from './Menu/CellMenu'; -interface Props extends FormatterProps { +interface Props extends RenderCellProps { className?: string; } -const styles = css` - formatter-wrapper { - height: 100%; - display: flex; - overflow: hidden; - box-sizing: border-box; - } - formatter-container { - flex: 1; - overflow: hidden; - } - menu-container { - width: 25px; - height: 100%; - box-sizing: border-box; - overflow: hidden; - } -`; - export const CellFormatter = observer(function CellFormatter({ className, ...rest }) { const context = useContext(DataGridContext); const tableDataContext = useContext(TableDataContext); @@ -50,7 +31,8 @@ export const CellFormatter = observer(function CellFormatter({ className, const editingContext = useContext(EditingContext); const [menuVisible, setMenuVisible] = useState(false); const isEditing = cellContext.isEditing; - const showCellMenu = getComputed(() => !isEditing && (rest.isCellSelected || cellContext.mouse.state.mouseEnter || menuVisible)); + const showCellMenu = getComputed(() => !isEditing && (cellContext.isFocused || cellContext.mouse.state.mouseEnter || menuVisible)); + const styles = useS(style); const spreadsheetActions = useObjectRef>({ edit(position) { @@ -63,13 +45,13 @@ export const CellFormatter = observer(function CellFormatter({ className, }, }); - return styled(styles)( - - + return ( +
+
- - {showCellMenu && cellContext.cell && !rest.isScrolling && ( - +
+ {showCellMenu && cellContext.cell && ( +
(function CellFormatter({ className, simple={context.simple} onStateSwitch={setMenuVisible} /> - +
)} - , +
); }); diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatterFactory.tsx b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatterFactory.tsx index b0951a4d52..397149fd59 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatterFactory.tsx +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatterFactory.tsx @@ -9,19 +9,19 @@ import { observer } from 'mobx-react-lite'; import { useContext, useRef } from 'react'; import { IResultSetRowKey, isBooleanValuePresentationAvailable } from '@cloudbeaver/plugin-data-viewer'; -import type { FormatterProps } from '@cloudbeaver/plugin-react-data-grid'; +import type { RenderCellProps } from '@cloudbeaver/plugin-react-data-grid'; import { CellContext } from '../CellRenderer/CellContext'; import { TableDataContext } from '../TableDataContext'; import { BooleanFormatter } from './CellFormatters/BooleanFormatter'; import { TextFormatter } from './CellFormatters/TextFormatter'; -interface IProps extends FormatterProps { +interface IProps extends RenderCellProps { isEditing: boolean; } export const CellFormatterFactory = observer(function CellFormatterFactory(props) { - const formatterRef = useRef> | null>(null); + const formatterRef = useRef> | null>(null); const tableDataContext = useContext(TableDataContext); const cellContext = useContext(CellContext); diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/BooleanFormatter.m.css b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/BooleanFormatter.m.css new file mode 100644 index 0000000000..af9904cde0 --- /dev/null +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/BooleanFormatter.m.css @@ -0,0 +1,26 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2023 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +.booleanFormatter { + cursor: pointer; +} + +.disabled { + cursor: auto; +} + +.nullValue { + composes: nullValue from './CellNullValue.m.css'; +} + +.booleanFormatter:not(.nullValue) { + font-family: monospace; + white-space: pre; + line-height: 1; + vertical-align: text-top; +} diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/BooleanFormatter.tsx b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/BooleanFormatter.tsx index 3089039b9d..61d805ce2a 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/BooleanFormatter.tsx +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/BooleanFormatter.tsx @@ -8,32 +8,18 @@ import { computed } from 'mobx'; import { observer } from 'mobx-react-lite'; import { useContext, useMemo } from 'react'; -import styled, { css, use } from 'reshadow'; +import { s, useS } from '@cloudbeaver/core-blocks'; import type { IResultSetRowKey } from '@cloudbeaver/plugin-data-viewer'; -import type { FormatterProps } from '@cloudbeaver/plugin-react-data-grid'; +import type { RenderCellProps } from '@cloudbeaver/plugin-react-data-grid'; import { EditingContext } from '../../../Editing/EditingContext'; import { CellContext } from '../../CellRenderer/CellContext'; import { DataGridContext } from '../../DataGridContext'; import { TableDataContext } from '../../TableDataContext'; +import style from './BooleanFormatter.m.css'; -const styles = css` - boolean-formatter { - cursor: pointer; - } - boolean-formatter[|disabled] { - cursor: auto; - } - boolean-formatter[|boolean] { - font-family: monospace; - white-space: pre; - line-height: 1; - vertical-align: text-top; - } -`; - -export const BooleanFormatter = observer>(function BooleanFormatter({ column, row }) { +export const BooleanFormatter = observer>(function BooleanFormatter({ column, row }) { const context = useContext(DataGridContext); const tableDataContext = useContext(TableDataContext); const editingContext = useContext(EditingContext); @@ -43,6 +29,8 @@ export const BooleanFormatter = observer>(funct throw new Error('Contexts required'); } + const styles = useS(style); + const formatter = tableDataContext.format; const rawValue = useMemo( () => computed(() => formatter.get(tableDataContext.getCellValue(cellContext!.cell!)!)), @@ -68,15 +56,9 @@ export const BooleanFormatter = observer>(funct tableDataContext.editor.set(cellContext.cell, nextValue); } - return styled(styles)( - + return ( + {valueRepresentation} - , + ); }); diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/CellNullValue.m.css b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/CellNullValue.m.css new file mode 100644 index 0000000000..6a8f0c528c --- /dev/null +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/CellNullValue.m.css @@ -0,0 +1,12 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2023 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +.nullValue { + text-transform: uppercase; + opacity: 0.65; +} diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/TextFormatter.m.css b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/TextFormatter.m.css new file mode 100644 index 0000000000..9bc33bd293 --- /dev/null +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/TextFormatter.m.css @@ -0,0 +1,36 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2023 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +.textFormatter { + display: flex; + align-items: center; + + & .a { + display: flex; + align-items: center; + justify-content: center; + min-width: 16px; + height: 24px; + margin-right: 8px; + + & .icon { + width: 12px; + height: 12px; + } + } +} + +.textFormatterValue { + overflow: hidden; + white-space: pre; + text-overflow: ellipsis; +} + +.nullValue { + composes: nullValue from './CellNullValue.m.css'; +} diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/TextFormatter.tsx b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/TextFormatter.tsx index d7635f5f7c..2b3ce9d003 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/TextFormatter.tsx +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/CellFormatters/TextFormatter.tsx @@ -8,17 +8,18 @@ import { observer } from 'mobx-react-lite'; import { useCallback, useContext, useEffect, useRef } from 'react'; -import { getComputed, IconOrImage } from '@cloudbeaver/core-blocks'; -import { clsx, isValidUrl } from '@cloudbeaver/core-utils'; +import { getComputed, IconOrImage, s, useS } from '@cloudbeaver/core-blocks'; +import { isValidUrl } from '@cloudbeaver/core-utils'; import type { IResultSetRowKey } from '@cloudbeaver/plugin-data-viewer'; -import type { FormatterProps } from '@cloudbeaver/plugin-react-data-grid'; +import type { RenderCellProps } from '@cloudbeaver/plugin-react-data-grid'; import { EditingContext } from '../../../Editing/EditingContext'; -import { CellEditor, IEditorRef } from '../../CellEditor/CellEditor'; +import { CellEditor, IEditorRef } from '../../CellEditor'; import { CellContext } from '../../CellRenderer/CellContext'; import { TableDataContext } from '../../TableDataContext'; +import styles from './TextFormatter.m.css'; -export const TextFormatter = observer>(function TextFormatter({ row, column, isCellSelected }) { +export const TextFormatter = observer>(function TextFormatter({ row, column }) { const editorRef = useRef(null); const editingContext = useContext(EditingContext); const tableDataContext = useContext(TableDataContext); @@ -28,10 +29,11 @@ export const TextFormatter = observer>(function throw new Error('Contexts required'); } + const style = useS(styles); const formatter = tableDataContext.format; const rawValue = getComputed(() => formatter.get(tableDataContext.getCellValue(cellContext.cell!)!)); - const classes = clsx('text-formatter', { 'cell-null': rawValue === null }); + const classes = s(style, { textFormatter: true, nullValue: rawValue === null }); const value = formatter.toDisplayString(rawValue); @@ -39,13 +41,14 @@ export const TextFormatter = observer>(function editingContext.closeEditor(cellContext.position); }, [cellContext]); + const isFocused = cellContext.isFocused; useEffect(() => { - if (isCellSelected) { + if (isFocused) { if (cellContext.isEditing) { editorRef.current?.focus(); } } - }, [isCellSelected]); + }, [isFocused]); if (cellContext.isEditing) { return ( @@ -60,11 +63,11 @@ export const TextFormatter = observer>(function return (
{isUrl && ( - - + + )} -
{value}
+
{value}
); }); diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/IndexFormatter.tsx b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/IndexFormatter.tsx index 88f3a132e3..70248aa345 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/IndexFormatter.tsx +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/Formatters/IndexFormatter.tsx @@ -8,11 +8,11 @@ import { useContext } from 'react'; import type { IResultSetRowKey } from '@cloudbeaver/plugin-data-viewer'; -import type { FormatterProps } from '@cloudbeaver/plugin-react-data-grid'; +import type { RenderCellProps } from '@cloudbeaver/plugin-react-data-grid'; import { CellContext } from '../CellRenderer/CellContext'; -export const IndexFormatter: React.FC> = function IndexFormatter(props) { +export const IndexFormatter: React.FC> = function IndexFormatter(props) { const context = useContext(CellContext); return
{context.position.rowIdx + 1}
; diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/OrderButton.m.css b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/OrderButton.m.css new file mode 100644 index 0000000000..0ca86c00ee --- /dev/null +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/OrderButton.m.css @@ -0,0 +1,23 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2023 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +.orderButton { + display: flex; + flex-direction: column; + justify-content: center; + flex-shrink: 0; + height: 28px; + width: 16px; + box-sizing: border-box; + cursor: pointer; + background: transparent; + outline: none; + color: inherit; + padding: 0; + margin-left: 8px; +} diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/OrderButton.tsx b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/OrderButton.tsx index 24b67aace6..e6d4bab82f 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/OrderButton.tsx +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/OrderButton.tsx @@ -6,28 +6,11 @@ * you may not use this file except in compliance with the License. */ import { observer } from 'mobx-react-lite'; -import styled, { css } from 'reshadow'; -import { IconOrImage, useTranslate } from '@cloudbeaver/core-blocks'; +import { IconOrImage, s, useS, useTranslate } from '@cloudbeaver/core-blocks'; import { EOrder, getNextOrder, IDatabaseDataModel, ResultSetConstraintAction } from '@cloudbeaver/plugin-data-viewer'; -const styles = css` - order-button { - display: flex; - flex-direction: column; - justify-content: center; - flex-shrink: 0; - height: 28px; - width: 16px; - box-sizing: border-box; - cursor: pointer; - background: transparent; - outline: none; - color: inherit; - padding: 0; - margin-left: 8px; - } -`; +import style from './OrderButton.m.css'; interface Props { model: IDatabaseDataModel; @@ -41,6 +24,7 @@ export const OrderButton = observer(function OrderButton({ model, resultI const constraints = model.source.getAction(resultIndex, ResultSetConstraintAction); const currentOrder = constraints.getOrder(attributePosition); const disabled = model.isDisabled(resultIndex) || model.isLoading(); + const styles = useS(style); let icon = 'order-arrow-unknown'; if (currentOrder === EOrder.asc) { @@ -61,16 +45,15 @@ export const OrderButton = observer(function OrderButton({ model, resultI event.preventDefault(); } - return styled(styles)( - - - , + + ); }); diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableColumnHeader.m.css b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableColumnHeader.m.css new file mode 100644 index 0000000000..cb30b7e623 --- /dev/null +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableColumnHeader.m.css @@ -0,0 +1,59 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2023 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +.header { + display: flex; + align-items: center; + align-content: center; + width: 100%; +} +.container { + display: flex; + align-items: center; + flex: 1 1 auto; + overflow: hidden; + cursor: pointer; +} +.icon { + display: flex; + position: relative; +} +.staticImage { + height: 16px; +} +.name { + margin-left: 8px; + font-weight: 400; + flex-grow: 1; +} +.readonlyStatus { + position: absolute; + bottom: 0; + right: 0; + width: 8px; + height: 8px; + border-radius: 50%; + border: 1px solid; +} +.dragging { + opacity: 0.5; +} +.header:before { + position: absolute; + z-index: 10; + height: 100%; + border-left: solid 2px var(--theme-primary); +} +[data-s-rearrange='left']:before { + content: ''; + left: 0; +} +[data-s-rearrange='right']:before { + content: ''; + right: 0; +} diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableColumnHeader.tsx b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableColumnHeader.tsx index 9c44c6a8ba..49457451d2 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableColumnHeader.tsx +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableColumnHeader.tsx @@ -7,76 +7,23 @@ */ import { observer } from 'mobx-react-lite'; import { useContext } from 'react'; -import styled, { css, use } from 'reshadow'; -import { getComputed, StaticImage } from '@cloudbeaver/core-blocks'; +import { getComputed, s, StaticImage, useS } from '@cloudbeaver/core-blocks'; import type { SqlResultColumn } from '@cloudbeaver/core-sdk'; -import type { HeaderRendererProps } from '@cloudbeaver/plugin-react-data-grid'; +import type { RenderHeaderCellProps } from '@cloudbeaver/plugin-react-data-grid'; import { DataGridContext } from '../DataGridContext'; import { DataGridSelectionContext } from '../DataGridSelection/DataGridSelectionContext'; import { TableDataContext } from '../TableDataContext'; import { OrderButton } from './OrderButton'; +import style from './TableColumnHeader.m.css'; import { useTableColumnDnD } from './useTableColumnDnD'; -const headerStyles = css` - table-header { - display: flex; - align-items: center; - align-content: center; - width: 100%; - } - shrink-container { - display: flex; - align-items: center; - flex: 1 1 auto; - overflow: hidden; - cursor: pointer; - } - icon { - display: flex; - position: relative; - } - StaticImage { - height: 16px; - } - name { - margin-left: 8px; - font-weight: 400; - flex-grow: 1; - } - readonly-status { - position: absolute; - bottom: 0; - right: 0; - width: 8px; - height: 8px; - border-radius: 50%; - border: 1px solid; - } - [|dragging] { - opacity: 0.5; - } - table-header:before { - position: absolute; - z-index: 10; - height: 100%; - border-left: solid 2px var(--theme-primary); - } - [|rearrange='left']:before { - content: ''; - left: 0; - } - [|rearrange='right']:before { - content: ''; - right: 0; - } -`; - -export const TableColumnHeader = observer>(function TableColumnHeader({ column: calculatedColumn }) { +export const TableColumnHeader = observer>(function TableColumnHeader({ column: calculatedColumn }) { const dataGridContext = useContext(DataGridContext); const tableDataContext = useContext(TableDataContext); const gridSelectionContext = useContext(DataGridSelectionContext); + const styles = useS(style); const resultIndex = dataGridContext.resultIndex; const model = dataGridContext.model; @@ -118,16 +65,16 @@ export const TableColumnHeader = observer>(function Tab dataGridContext.focus(); } - return styled(headerStyles)( - - - - {icon && } - {!dataReadonly && columnReadOnly && } - - {columnName} - + return ( +
+
+
+ {icon && } + {!dataReadonly && columnReadOnly &&
} +
+
{columnName}
+
{!sortingDisabled && resultColumn && } - , +
); }); diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableIndexColumnHeader.m.css b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableIndexColumnHeader.m.css new file mode 100644 index 0000000000..6fc0c0c5dd --- /dev/null +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableIndexColumnHeader.m.css @@ -0,0 +1,20 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2023 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +.container { + width: 100%; + cursor: pointer; +} +.iconOrImage { + cursor: auto; + width: 10px; + position: absolute; + right: 8px; + top: 50%; + transform: translateY(-50%); +} diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableIndexColumnHeader.tsx b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableIndexColumnHeader.tsx index 4fd9893c75..9351c5f06d 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableIndexColumnHeader.tsx +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/TableColumnHeader/TableIndexColumnHeader.tsx @@ -7,35 +7,21 @@ */ import { observer } from 'mobx-react-lite'; import { useContext } from 'react'; -import styled, { css } from 'reshadow'; -import { getComputed, IconOrImage, useTranslate } from '@cloudbeaver/core-blocks'; -import type { HeaderRendererProps } from '@cloudbeaver/plugin-react-data-grid'; +import { getComputed, IconOrImage, s, useS, useTranslate } from '@cloudbeaver/core-blocks'; +import type { RenderHeaderCellProps } from '@cloudbeaver/plugin-react-data-grid'; import { DataGridContext } from '../DataGridContext'; import { DataGridSelectionContext } from '../DataGridSelection/DataGridSelectionContext'; import { TableDataContext } from '../TableDataContext'; +import style from './TableIndexColumnHeader.m.css'; -const styles = css` - container { - width: 100%; - cursor: pointer; - } - IconOrImage { - cursor: auto; - width: 10px; - position: absolute; - right: 8px; - top: 50%; - transform: translateY(-50%); - } -`; - -export const TableIndexColumnHeader = observer>(function TableIndexColumnHeader(props) { +export const TableIndexColumnHeader = observer>(function TableIndexColumnHeader(props) { const dataGridContext = useContext(DataGridContext); const selectionContext = useContext(DataGridSelectionContext); const tableDataContext = useContext(TableDataContext); const translate = useTranslate(); + const styles = useS(style); if (!tableDataContext || !selectionContext || !dataGridContext) { throw new Error('Contexts required'); @@ -43,15 +29,17 @@ export const TableIndexColumnHeader = observer>(functio const readonly = getComputed(() => tableDataContext.isReadOnly() || dataGridContext.model.isReadonly(dataGridContext.resultIndex)); - function handleClick(event: React.MouseEvent) { + function handleClick(event: React.MouseEvent) { selectionContext.selectTable(); dataGridContext.focus(); } - return styled(styles)( - - {readonly && } + return ( +
+ {readonly && ( + + )} {props.column.name} - , +
); }); diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/useTableData.ts b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/useTableData.tsx similarity index 95% rename from webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/useTableData.ts rename to webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/useTableData.tsx index 271a88b2fa..3167d1e2a4 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/useTableData.ts +++ b/webapp/packages/plugin-data-spreadsheet-new/src/DataGrid/useTableData.tsx @@ -35,11 +35,10 @@ export const indexColumn: Column = { name: '#', minWidth: 60, width: 60, - selectable: false, resizable: false, frozen: true, - headerRenderer: TableIndexColumnHeader, - formatter: IndexFormatter, + renderHeaderCell: props => , + renderCell: props => , }; const COLUMN_PADDING = 16 + 2; @@ -54,7 +53,6 @@ export function useTableData( model: IDatabaseDataModel, resultIndex: number, gridDIVElement: React.RefObject, - onCellKeyDown?: (event: React.KeyboardEvent) => void, ): ITableData { const format = model.source.getAction(resultIndex, ResultSetFormatAction); const data = model.source.getAction(resultIndex, ResultSetDataAction); @@ -94,16 +92,12 @@ export function useTableData( }).map(width => width + COLUMN_PADDING); const columns: Array> = this.columnKeys.map>((col, index) => ({ - // key: uuid(), key: ResultSetDataKeysUtils.serialize(col), columnDataIndex: col, name: this.getColumnInfo(col)?.label || '?', editable: true, width: Math.min(300, Math.max(columnsWidth[index], cellsWidth[index] ?? 0)), - headerRenderer: TableColumnHeader, - editorOptions: { - onCellKeyDown, - }, + renderHeaderCell: props => , })); columns.unshift(indexColumn); diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/styles/base.scss b/webapp/packages/plugin-data-spreadsheet-new/src/styles/base.scss index 81a6db29eb..2d512b83a9 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/styles/base.scss +++ b/webapp/packages/plugin-data-spreadsheet-new/src/styles/base.scss @@ -16,41 +16,23 @@ -webkit-user-select: none; .cb-react-grid-theme { - font-family: inherit; - outline: 0; - height: 100%; - background-color: inherit; - border: none; + outline: 0 !important; + height: 100% !important; + background-color: inherit !important; + border: none !important; + font-family: inherit !important; + font-size: inherit !important; .rdg-header-row, .rdg-row { - background-color: transparent; + background-color: var(--theme-surface) !important; } - .rdg-cell.rdg-cell-frozen { - box-shadow: none; - } - - .text-formatter { - display: flex; - align-items: center; - & a { - display: flex; - align-items: center; - justify-content: center; - min-width: 16px; - height: 24px; - margin-right: 8px; - } - & svg { - width: 12px; - height: 12px; - } + * { + font-size: inherit !important; + font-family: inherit !important; } - - .text-formatter__value { - overflow: hidden; - white-space: pre; - text-overflow: ellipsis; + .rdg-cell.rdg-cell-frozen { + box-shadow: none !important; } .rdg-cell-editing { diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/styles/themes/_base-react-grid.scss b/webapp/packages/plugin-data-spreadsheet-new/src/styles/themes/_base-react-grid.scss index c2d40e65a5..ef78221205 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/styles/themes/_base-react-grid.scss +++ b/webapp/packages/plugin-data-spreadsheet-new/src/styles/themes/_base-react-grid.scss @@ -27,11 +27,11 @@ $deleted-color: rgba(255, 51, 0, 0.3); } .rdg-cell:global([aria-selected='true']) { - box-shadow: inset 0 0 0 1px #0091ea; + box-shadow: inset 0 0 0 1px #0091ea !important; } .rdg-cell-custom-editing { - box-shadow: none; + box-shadow: none !important; &::before { background-color: transparent; @@ -39,71 +39,71 @@ $deleted-color: rgba(255, 51, 0, 0.3); } .rdg-cell-custom-edited { - background-color: $edited-color; + background-color: $edited-color !important; } .rdg-cell-custom-added { - background-color: $added-color; + background-color: $added-color !important; } .rdg-cell-custom-deleted { - background-color: $deleted-color; + background-color: $deleted-color !important; } } .cb-react-grid-theme { @include mdc-typography(caption); - @include mdc-theme-prop(color, on-surface, false); + @include mdc-theme-prop(color, on-surface, true); .rdg-table-header__readonly-status { - background-color: #e28835; - @include mdc-theme-prop(border-color, surface, false); + background-color: #e28835 !important; + @include mdc-theme-prop(border-color, surface, true); } .rdg-table-header__order-button_unordered { - color: #c4c4c4; + color: #c4c4c4 !important; &:hover { - color: $mdc-theme-primary; + color: $mdc-theme-primary !important; } } .rdg-header-row { - @include mdc-theme-prop(background-color, surface, false); + @include mdc-theme-prop(background-color, surface, true); } .rdg-row { - @include mdc-theme-prop(border-color, background, false); + @include mdc-theme-prop(border-color, background, true); } .rdg-row:hover .rdg-cell, .rdg-row:hover .rdg-cell-frozen { - border-bottom: 1px solid; - border-bottom-color: $color-positive; + border-bottom: 1px solid !important; + border-bottom-color: $color-positive !important; } .rdg-row:hover { - @include stripes-background($mdc-theme-sub-secondary); + @include stripes-background($mdc-theme-sub-secondary, true); } .rdg-cell { - @include mdc-theme-prop(border-color, background, false); + @include mdc-theme-prop(border-color, background, true); &:focus { - outline: 0; + outline: 0 !important; } &:global([aria-selected='true']) { - outline: 0; - box-shadow: inset 0 0 0 1px #808080; + outline: 0 !important; + box-shadow: inset 0 0 0 1px #808080 !important; } } .rdg-cell-frozen { - @include mdc-theme-prop(background-color, surface, false); + @include mdc-theme-prop(background-color, surface, true); } .rdg-cell-custom-selected { - box-shadow: none; + box-shadow: none !important; } .rdg-cell-custom-selected::before { @@ -117,20 +117,20 @@ $deleted-color: rgba(255, 51, 0, 0.3); } .rdg-cell-custom-editing { - box-shadow: none; - background-color: inherit; + box-shadow: none !important; + background-color: inherit !important; } .rdg-cell-custom-edited { - background-color: $edited-color; + background-color: $edited-color !important; } .rdg-cell-custom-added { - background-color: $added-color; + background-color: $added-color !important; } .rdg-cell-custom-deleted { - background-color: $deleted-color; + background-color: $deleted-color !important; } .cell-formatter { @@ -138,11 +138,6 @@ $deleted-color: rgba(255, 51, 0, 0.3); white-space: nowrap; text-overflow: ellipsis; } - - .cell-null { - text-transform: uppercase; - opacity: 0.65; - } } } } diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/styles/themes/dark.module.scss b/webapp/packages/plugin-data-spreadsheet-new/src/styles/themes/dark.module.scss index 786bef306e..8eb55d2612 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/styles/themes/dark.module.scss +++ b/webapp/packages/plugin-data-spreadsheet-new/src/styles/themes/dark.module.scss @@ -6,9 +6,13 @@ * you may not use this file except in compliance with the License. */ - @import "@cloudbeaver/core-theming/src/styles/theme-dark"; - @import "base-react-grid"; - - :global .#{$theme-class} { - @include base-react-grid; - } \ No newline at end of file +@import '@cloudbeaver/core-theming/src/styles/theme-dark'; +@import 'base-react-grid'; + +:global .#{$theme-class} { + @include base-react-grid; + + .cb-react-grid-theme { + --rdg-color-scheme: dark; + } +} diff --git a/webapp/packages/plugin-data-spreadsheet-new/src/styles/themes/light.module.scss b/webapp/packages/plugin-data-spreadsheet-new/src/styles/themes/light.module.scss index 8f9b945aa1..8131f082f8 100644 --- a/webapp/packages/plugin-data-spreadsheet-new/src/styles/themes/light.module.scss +++ b/webapp/packages/plugin-data-spreadsheet-new/src/styles/themes/light.module.scss @@ -6,9 +6,13 @@ * you may not use this file except in compliance with the License. */ -@import "@cloudbeaver/core-theming/src/styles/theme-light"; -@import "base-react-grid"; +@import '@cloudbeaver/core-theming/src/styles/theme-light'; +@import 'base-react-grid'; :global .#{$theme-class} { @include base-react-grid; + + .cb-react-grid-theme { + --rdg-color-scheme: light; + } } diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/ObjectPropertyTableFooterService.ts b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/ObjectPropertyTableFooterService.ts index 14265d7fa1..38d9b09fbd 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/ObjectPropertyTableFooterService.ts +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/ObjectPropertyTableFooterService.ts @@ -8,24 +8,9 @@ import { CoreSettingsService } from '@cloudbeaver/core-app'; import type { TableState } from '@cloudbeaver/core-blocks'; import { injectable } from '@cloudbeaver/core-di'; -import { - CommonDialogService, - ConfirmationDialogDelete, - ContextMenuService, - DialogueStateResult, - IContextMenuItem, - IMenuContext, - IMenuItem, -} from '@cloudbeaver/core-dialogs'; +import { CommonDialogService, ContextMenuService, IContextMenuItem, IMenuContext, IMenuItem } from '@cloudbeaver/core-dialogs'; import { NotificationService } from '@cloudbeaver/core-events'; -import { - ENodeFeature, - getNodeDisplayName, - type NavNode, - NavNodeInfoResource, - NavTreeResource, - NavTreeSettingsService, -} from '@cloudbeaver/core-navigation-tree'; +import { ENodeFeature, type NavNode, NavNodeInfoResource, NavTreeResource, NavTreeSettingsService } from '@cloudbeaver/core-navigation-tree'; import { resourceKeyList } from '@cloudbeaver/core-sdk'; interface IObjectPropertyTableFooterContext { diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/CellFormatter.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/CellFormatter.tsx index 7d43547c61..66c3392f17 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/CellFormatter.tsx +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/CellFormatter.tsx @@ -17,7 +17,7 @@ import { ContextMenu } from '@cloudbeaver/core-ui'; import { useMenu } from '@cloudbeaver/core-view'; import { DATA_CONTEXT_CONNECTION } from '@cloudbeaver/plugin-connections'; import { MENU_NAV_TREE, useNode } from '@cloudbeaver/plugin-navigation-tree'; -import type { FormatterProps } from '@cloudbeaver/plugin-react-data-grid'; +import type { RenderCellProps } from '@cloudbeaver/plugin-react-data-grid'; import { getValue } from '../../helpers'; import { TableContext } from './TableContext'; @@ -99,7 +99,7 @@ export const Menu = observer(function Menu({ value, node }) { ); }); -export const CellFormatter = observer>(function CellFormatter(props) { +export const CellFormatter = observer>(function CellFormatter(props) { const tableContext = useContext(TableContext); if (!tableContext.tableData) { diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnIcon/ColumnIcon.ts b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnIcon/ColumnIcon.tsx similarity index 90% rename from webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnIcon/ColumnIcon.ts rename to webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnIcon/ColumnIcon.tsx index cf06baa2f2..deefbb2733 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnIcon/ColumnIcon.ts +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnIcon/ColumnIcon.tsx @@ -16,6 +16,6 @@ export const ColumnIcon: ICustomColumn = { maxWidth: 40, minWidth: 40, frozen: true, - formatter: IconFormatter, + renderCell: props => , order: 1, }; diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnIcon/IconFormatter.m.css b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnIcon/IconFormatter.m.css new file mode 100644 index 0000000000..35e8174277 --- /dev/null +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnIcon/IconFormatter.m.css @@ -0,0 +1,18 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2023 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +.icon { + width: 100%; + display: flex; + align-items: center; + justify-content: center; +} + +.staticImage { + width: 16px; +} diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnIcon/IconFormatter.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnIcon/IconFormatter.tsx index 72cd818aef..766f8d74ab 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnIcon/IconFormatter.tsx +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnIcon/IconFormatter.tsx @@ -6,27 +6,19 @@ * you may not use this file except in compliance with the License. */ import { observer } from 'mobx-react-lite'; -import styled, { css } from 'reshadow'; -import { StaticImage } from '@cloudbeaver/core-blocks'; +import { s, StaticImage, useS } from '@cloudbeaver/core-blocks'; import type { DBObject } from '@cloudbeaver/core-navigation-tree'; import { useNode } from '@cloudbeaver/plugin-navigation-tree'; -import type { FormatterProps } from '@cloudbeaver/plugin-react-data-grid'; +import type { RenderCellProps } from '@cloudbeaver/plugin-react-data-grid'; -const styles = css` - icon { - width: 100%; - display: flex; - align-items: center; - justify-content: center; - & StaticImage { - width: 16px; - } - } -`; +import style from './IconFormatter.m.css'; -export const IconFormatter = observer>(function IconFormatter(props) { +export const IconFormatter = observer>(function IconFormatter(props) { const { node } = useNode(props.row.id); + const styles = useS(style); - return styled(styles)({node?.icon && }); + return ( +
{node?.icon && }
+ ); }); diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnSelect/ColumnSelect.ts b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnSelect/ColumnSelect.tsx similarity index 89% rename from webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnSelect/ColumnSelect.ts rename to webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnSelect/ColumnSelect.tsx index c799ef81ec..276329e999 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnSelect/ColumnSelect.ts +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnSelect/ColumnSelect.tsx @@ -16,6 +16,6 @@ export const ColumnSelect: ICustomColumn = { maxWidth: 40, minWidth: 40, frozen: true, - formatter: SelectorFormatter, + renderCell: props => , order: 0, }; diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnSelect/SelectorFormatter.m.css b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnSelect/SelectorFormatter.m.css new file mode 100644 index 0000000000..22891dccc3 --- /dev/null +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnSelect/SelectorFormatter.m.css @@ -0,0 +1,18 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2023 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ + +.container { + display: flex; + width: 100%; + align-items: center; + justify-content: center; +} +.checkbox { + margin-left: -10px; + margin-right: -10px; +} diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnSelect/SelectorFormatter.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnSelect/SelectorFormatter.tsx index 884acfc708..661922d56d 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnSelect/SelectorFormatter.tsx +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Columns/ColumnSelect/SelectorFormatter.tsx @@ -7,39 +7,27 @@ */ import { observer } from 'mobx-react-lite'; import { useCallback, useContext } from 'react'; -import styled, { css } from 'reshadow'; -import { Checkbox, getComputed } from '@cloudbeaver/core-blocks'; +import { Checkbox, getComputed, s, useS } from '@cloudbeaver/core-blocks'; import type { DBObject } from '@cloudbeaver/core-navigation-tree'; -import type { FormatterProps } from '@cloudbeaver/plugin-react-data-grid'; +import type { RenderCellProps } from '@cloudbeaver/plugin-react-data-grid'; import { TableContext } from '../../TableContext'; +import style from './SelectorFormatter.m.css'; -const styles = css` - container { - display: flex; - width: 100%; - align-items: center; - justify-content: center; - } - Checkbox { - margin-left: -10px; - margin-right: -10px; - } -`; - -export const SelectorFormatter = observer>(function SelectorFormatter(props) { +export const SelectorFormatter = observer>(function SelectorFormatter(props) { const context = useContext(TableContext); const id = props.row.id; const selected = getComputed(() => context.tableState?.selected.get(id)); + const styles = useS(style); const select = useCallback(() => { context.tableState?.selected.set(id, !selected); }, [id, selected]); - return styled(styles)( - - - , + return ( +
+ +
); }); diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/HeaderRenderer.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/HeaderRenderer.tsx index 18aa8c2583..cbaed491e3 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/HeaderRenderer.tsx +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/HeaderRenderer.tsx @@ -9,11 +9,11 @@ import { observer } from 'mobx-react-lite'; import { useContext } from 'react'; import type { DBObject } from '@cloudbeaver/core-navigation-tree'; -import type { HeaderRendererProps } from '@cloudbeaver/plugin-react-data-grid'; +import type { RenderHeaderCellProps } from '@cloudbeaver/plugin-react-data-grid'; import { TableContext } from './TableContext'; -export const HeaderRenderer = observer>(function HeaderRenderer(props) { +export const HeaderRenderer = observer>(function HeaderRenderer(props) { const tableContext = useContext(TableContext); const dataColumn = tableContext.tableData?.columns.find(column => column.key === props.column.key); diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Table.tsx b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Table.tsx index 41a4b17389..ad0314c170 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Table.tsx +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/Table.tsx @@ -15,6 +15,7 @@ import type { ObjectPropertyInfo } from '@cloudbeaver/core-sdk'; import { useTabLocalState } from '@cloudbeaver/core-ui'; import { isDefined, TextTools } from '@cloudbeaver/core-utils'; import DataGrid from '@cloudbeaver/plugin-react-data-grid'; +import '@cloudbeaver/plugin-react-data-grid/lib/lib/styles.css'; import { getValue } from '../../helpers'; import { ObjectPropertyTableFooter } from '../ObjectPropertyTableFooter'; @@ -117,8 +118,8 @@ export const Table = observer(function Table({ objects, hasNextPage, width: Math.min(300, measuredCells[index]), minWidth: 40, resizable: true, - formatter: CellFormatter, - headerRenderer: HeaderRenderer, + renderCell: props => , + renderHeaderCell: props => , })); const tableData = useTableData(dataColumns, CUSTOM_COLUMNS); diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/styles/base.scss b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/styles/base.scss index 528f63ac1f..6ffffb451c 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/styles/base.scss +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/styles/base.scss @@ -10,45 +10,52 @@ .metadata-grid-container { .cb-metadata-grid-theme { - outline: 0; - height: 100%; - background-color: inherit; - border: none; + outline: 0 !important; + height: 100% !important; + background-color: inherit !important; + border: none !important; + font-family: inherit !important; + font-size: inherit !important; + + * { + font-size: inherit !important; + font-family: inherit !important; + } .rdg-header-row, .rdg-row { - background-color: transparent; + background-color: transparent !important; } .rdg-header-row { - text-transform: uppercase; + text-transform: uppercase !important; } .rdg-cell { - border-color: transparent; - display: flex; - flex-direction: row; - user-select: text; + border-color: transparent !important; + display: flex !important; + flex-direction: row !important; + user-select: text !important; &.rdg-cell-frozen { - box-shadow: none; + box-shadow: none !important; } } .rdg-cell:global([aria-selected='true']) { - box-shadow: none; + box-shadow: none !important; } .cell-formatter { - display: flex; - align-items: center; - width: 100%; + display: flex !important; + align-items: center !important; + width: 100% !important; } .cell-formatter__value { - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; + overflow: hidden !important; + white-space: nowrap !important; + text-overflow: ellipsis !important; } } } diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/styles/themes/_base-metadata-grid.scss b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/styles/themes/_base-metadata-grid.scss index ade77fffea..c64bad9ee6 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/styles/themes/_base-metadata-grid.scss +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/styles/themes/_base-metadata-grid.scss @@ -6,7 +6,7 @@ * you may not use this file except in compliance with the License. */ -@import "@cloudbeaver/core-theming/src/styles/branding"; +@import '@cloudbeaver/core-theming/src/styles/branding'; @mixin base-metadata-grid() { :global { @@ -18,41 +18,41 @@ } } .metadata-grid-container:focus-within { - .rdg-cell:global([aria-selected=true]) { - box-shadow: inset 0 0 0 1px #0091ea; + .rdg-cell:global([aria-selected='true']) { + box-shadow: inset 0 0 0 1px #0091ea !important; } } .cb-metadata-grid-theme { @include mdc-typography(caption); - @include mdc-theme-prop(color, on-surface, false); + @include mdc-theme-prop(color, on-surface, true); .rdg-header-row { - @include mdc-theme-prop(background-color, surface, false); + @include mdc-theme-prop(background-color, surface, true); } .rdg-row { - @include mdc-theme-prop(border-color, background, false); + @include mdc-theme-prop(border-color, background, true); } .rdg-row:hover { - @include stripes-background($mdc-theme-sub-secondary); + @include stripes-background($mdc-theme-sub-secondary, true); } .rdg-cell { - @include mdc-theme-prop(border-color, background, false); + @include mdc-theme-prop(border-color, background, true); &:focus { - outline: 0; + outline: 0 !important; } - - &:global([aria-selected=true]) { - outline: 0; - box-shadow: inset 0 0 0 1px #808080; + + &:global([aria-selected='true']) { + outline: 0 !important; + box-shadow: inset 0 0 0 1px #808080 !important; } } .rdg-cell-frozen { - @include mdc-theme-prop(background-color, surface, false); + @include mdc-theme-prop(background-color, surface, true); } } } diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/styles/themes/dark.module.scss b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/styles/themes/dark.module.scss index 6c210cfbec..5b4a165a77 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/styles/themes/dark.module.scss +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/styles/themes/dark.module.scss @@ -6,9 +6,13 @@ * you may not use this file except in compliance with the License. */ - @import "@cloudbeaver/core-theming/src/styles/theme-dark"; - @import "base-metadata-grid"; - - :global .#{$theme-class} { - @include base-metadata-grid; - } \ No newline at end of file +@import '@cloudbeaver/core-theming/src/styles/theme-dark'; +@import 'base-metadata-grid'; + +:global .#{$theme-class} { + @include base-metadata-grid; + + .cb-metadata-grid-theme { + --rdg-color-scheme: dark; + } +} diff --git a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/styles/themes/light.module.scss b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/styles/themes/light.module.scss index 2e815cb4af..f1b5a481ce 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/styles/themes/light.module.scss +++ b/webapp/packages/plugin-object-viewer/src/ObjectPropertiesPage/ObjectPropertyTable/Table/styles/themes/light.module.scss @@ -6,9 +6,13 @@ * you may not use this file except in compliance with the License. */ -@import "@cloudbeaver/core-theming/src/styles/theme-light"; -@import "base-metadata-grid"; +@import '@cloudbeaver/core-theming/src/styles/theme-light'; +@import 'base-metadata-grid'; :global .#{$theme-class} { @include base-metadata-grid; + + .cb-metadata-grid-theme { + --rdg-color-scheme: light; + } } diff --git a/webapp/packages/plugin-react-data-grid/lib/lib/bundle.cjs b/webapp/packages/plugin-react-data-grid/lib/lib/bundle.cjs index 6941246d78..fb5b793ba7 100644 --- a/webapp/packages/plugin-react-data-grid/lib/lib/bundle.cjs +++ b/webapp/packages/plugin-react-data-grid/lib/lib/bundle.cjs @@ -3,281 +3,21 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } }); const react = require('react'); +const reactDom = require('react-dom'); const clsx = require('clsx'); const jsxRuntime = require('react/jsx-runtime'); -function styleInject(css, ref) { - if ( ref === void 0 ) ref = {}; - var insertAt = ref.insertAt; - - if (!css || typeof document === 'undefined') { return; } - - var head = document.head || document.getElementsByTagName('head')[0]; - var style = document.createElement('style'); - style.type = 'text/css'; - - if (insertAt === 'top') { - if (head.firstChild) { - head.insertBefore(style, head.firstChild); - } else { - head.appendChild(style); - } - } else { - head.appendChild(style); - } - - if (style.styleSheet) { - style.styleSheet.cssText = css; - } else { - style.appendChild(document.createTextNode(css)); - } -} - -var css_248z$f = ".cj343x0700-beta13{background-color:inherit;border-block-end:1px solid var(--rdg-border-color);border-inline-end:1px solid var(--rdg-border-color);contain:size style;grid-row-start:var(--rdg-grid-row-start);outline:none;overflow:hidden;overflow:clip;padding-block:0;padding-inline:8px;position:relative;text-overflow:ellipsis;white-space:nowrap}.cj343x0700-beta13[aria-selected=true]{outline:2px solid var(--rdg-selection-color);outline-offset:-2px}.csofj7r700-beta13 .cj343x0700-beta13{contain:content}.ch2wcw8700-beta13{position:sticky;z-index:1}.c1wvphzh700-beta13{box-shadow:calc(2px*var(--rdg-sign)) 0 5px -2px hsla(0,0%,53%,.3)}"; -styleInject(css_248z$f,{"insertAt":"top"}); - -const cell = "cj343x0700-beta13"; -const cellClassname = `rdg-cell ${cell}`; -const cellAutoResizeClassname = "csofj7r700-beta13"; -const cellFrozen = "ch2wcw8700-beta13"; -const cellFrozenClassname = `rdg-cell-frozen ${cellFrozen}`; -const cellFrozenLast = "c1wvphzh700-beta13"; -const cellFrozenLastClassname = `rdg-cell-frozen-last ${cellFrozenLast}`; - -var css_248z$e = ".rnvodz5700-beta13{--rdg-color:#000;--rdg-border-color:#ddd;--rdg-summary-border-color:#aaa;--rdg-background-color:#fff;--rdg-header-background-color:#f9f9f9;--rdg-row-hover-background-color:#f5f5f5;--rdg-row-selected-background-color:#dbecfa;--row-selected-hover-background-color:#c9e3f8;--rdg-checkbox-color:#005194;--rdg-checkbox-focus-color:#61b8ff;--rdg-checkbox-disabled-border-color:#ccc;--rdg-checkbox-disabled-background-color:#ddd;--rdg-selection-color:#66afe9;--rdg-font-size:14px;background-color:var(--rdg-background-color);block-size:350px;border:1px solid var(--rdg-border-color);box-sizing:border-box;color:var(--rdg-color);color-scheme:var(--rdg-color-scheme,light dark);contain:strict;contain:size layout style paint;content-visibility:auto;display:grid;font-size:var(--rdg-font-size);overflow:auto;user-select:none}@supports not (contain:strict){.rnvodz5700-beta13{position:relative;z-index:0}}.rnvodz5700-beta13 *,.rnvodz5700-beta13 :after,.rnvodz5700-beta13 :before{box-sizing:inherit}.rnvodz5700-beta13:before{content:\"\";grid-column:1/-1;grid-row:1/-1}.rnvodz5700-beta13.rdg-dark{--rdg-color-scheme:dark;--rdg-color:#ddd;--rdg-border-color:#444;--rdg-summary-border-color:#555;--rdg-background-color:#212121;--rdg-header-background-color:#1b1b1b;--rdg-row-hover-background-color:#171717;--rdg-row-selected-background-color:#1a73bc;--row-selected-hover-background-color:#1768ab;--rdg-checkbox-color:#94cfff;--rdg-checkbox-focus-color:#c7e6ff;--rdg-checkbox-disabled-border-color:#000;--rdg-checkbox-disabled-background-color:#333}.rnvodz5700-beta13.rdg-light{--rdg-color-scheme:light}@media (prefers-color-scheme:dark){.rnvodz5700-beta13:not(.rdg-light){--rdg-color:#ddd;--rdg-border-color:#444;--rdg-summary-border-color:#555;--rdg-background-color:#212121;--rdg-header-background-color:#1b1b1b;--rdg-row-hover-background-color:#171717;--rdg-row-selected-background-color:#1a73bc;--row-selected-hover-background-color:#1768ab;--rdg-checkbox-color:#94cfff;--rdg-checkbox-focus-color:#c7e6ff;--rdg-checkbox-disabled-border-color:#000;--rdg-checkbox-disabled-background-color:#333}}.vlqv91k700-beta13.r1upfr80700-beta13{cursor:move}.f1lsfrzw700-beta13{grid-column:1/-1;pointer-events:none;z-index:4}"; -styleInject(css_248z$e,{"insertAt":"top"}); - -const root = "rnvodz5700-beta13"; -const rootClassname = `rdg ${root}`; -const viewportDragging = "vlqv91k700-beta13"; -const viewportDraggingClassname = `rdg-viewport-dragging ${viewportDragging}`; -const focusSinkClassname = "f1lsfrzw700-beta13"; - -var css_248z$d = ".r1upfr80700-beta13{background-color:var(--rdg-background-color);display:contents;line-height:var(--rdg-row-height)}.r1upfr80700-beta13:hover{background-color:var(--rdg-row-hover-background-color)}.r1upfr80700-beta13[aria-selected=true]{background-color:var(--rdg-row-selected-background-color)}.r1upfr80700-beta13[aria-selected=true]:hover{background-color:var(--row-selected-hover-background-color)}.r190mhd3700-beta13{outline:2px solid var(--rdg-selection-color);outline-offset:-2px}.r139qu9m700-beta13:before{border-inline-start:2px solid var(--rdg-selection-color);content:\"\";display:inline-block;height:100%;inset-inline-start:0;position:sticky}"; -styleInject(css_248z$d,{"insertAt":"top"}); - -const row = "r1upfr80700-beta13"; -const rowClassname = `rdg-row ${row}`; -const rowSelected = "r190mhd3700-beta13"; -const rowSelectedClassname = `rdg-row-selected`; -const rowSelectedWithFrozenCell = "r139qu9m700-beta13"; - -var css_248z$c = ".c2xai5k700-beta13{align-items:center;cursor:pointer;display:flex;inset:0;justify-content:center;margin-inline-end:1px;position:absolute}.c1nhzyev700-beta13{all:unset}.cdhtjkm700-beta13{background-color:var(--rdg-background-color);block-size:20px;border:2px solid var(--rdg-border-color);content:\"\";inline-size:20px}.c1nhzyev700-beta13:checked+.cdhtjkm700-beta13{background-color:var(--rdg-checkbox-color);outline:4px solid var(--rdg-background-color);outline-offset:-6px}.c1nhzyev700-beta13:focus+.cdhtjkm700-beta13{border-color:var(--rdg-checkbox-focus-color)}.cy65rq2700-beta13{cursor:default}.cy65rq2700-beta13 .cdhtjkm700-beta13{background-color:var(--rdg-checkbox-disabled-background-color);border-color:var(--rdg-checkbox-disabled-border-color)}"; -styleInject(css_248z$c,{"insertAt":"top"}); - -const checkboxLabel = "c2xai5k700-beta13"; -const checkboxLabelClassname = `rdg-checkbox-label ${checkboxLabel}`; -const checkboxInput = "c1nhzyev700-beta13"; -const checkboxInputClassname = `rdg-checkbox-input ${checkboxInput}`; -const checkbox = "cdhtjkm700-beta13"; -const checkboxClassname = `rdg-checkbox ${checkbox}`; -const checkboxLabelDisabled = "cy65rq2700-beta13"; -const checkboxLabelDisabledClassname = `rdg-checkbox-label-disabled ${checkboxLabelDisabled}`; -const CheckboxFormatter = /*#__PURE__*/react.forwardRef(function CheckboxFormatter({ - onChange, - ...props -}, ref) { - function handleChange(e) { - onChange(e.target.checked, e.nativeEvent.shiftKey); - } - - return /*#__PURE__*/jsxRuntime.jsxs("label", { - className: clsx(checkboxLabelClassname, props.disabled && checkboxLabelDisabledClassname), - children: [/*#__PURE__*/jsxRuntime.jsx("input", { - type: "checkbox", - ref: ref, - ...props, - className: checkboxInputClassname, - onChange: handleChange - }), /*#__PURE__*/jsxRuntime.jsx("div", { - className: checkboxClassname - })] - }); -}); - -const useLayoutEffect = typeof window === 'undefined' ? react.useEffect : react.useLayoutEffect; - -function useFocusRef(isSelected) { - const ref = react.useRef(null); - useLayoutEffect(() => { - if (!isSelected) return; - ref.current?.focus({ - preventScroll: true - }); - }, [isSelected]); - return { - ref, - tabIndex: isSelected ? 0 : -1 - }; -} - -const DataGridDefaultComponentsContext = /*#__PURE__*/react.createContext(undefined); -const DataGridDefaultComponentsProvider = DataGridDefaultComponentsContext.Provider; -function useDefaultComponents() { - return react.useContext(DataGridDefaultComponentsContext); -} - -function SelectCellFormatter({ - value, - isCellSelected, - disabled, - onChange, - 'aria-label': ariaLabel, - 'aria-labelledby': ariaLabelledBy -}) { - const { - ref, - tabIndex - } = useFocusRef(isCellSelected); - const Formatter = useDefaultComponents().checkboxFormatter; - return /*#__PURE__*/jsxRuntime.jsx(Formatter, { - "aria-label": ariaLabel, - "aria-labelledby": ariaLabelledBy, - ref: ref, - tabIndex: tabIndex, - disabled: disabled, - checked: value, - onChange: onChange - }); -} - -function ValueFormatter(props) { - try { - return /*#__PURE__*/jsxRuntime.jsx(jsxRuntime.Fragment, { - children: props.row[props.column.key] - }); - } catch { - return null; - } -} - -var css_248z$b = ".g1vzro7t700-beta13{outline:none}.c1fsqdic700-beta13{stroke:currentColor;stroke-width:1.5px;fill:transparent;margin-inline-start:4px;vertical-align:middle}.c1fsqdic700-beta13>path{transition:d .1s}"; -styleInject(css_248z$b,{"insertAt":"top"}); - -const groupCellContent = "g1vzro7t700-beta13"; -const groupCellContentClassname = `rdg-group-cell-content ${groupCellContent}`; -const caret = "c1fsqdic700-beta13"; -const caretClassname = `rdg-caret ${caret}`; -function ToggleGroupFormatter({ - groupKey, - isExpanded, - isCellSelected, - toggleGroup -}) { - const { - ref, - tabIndex - } = useFocusRef(isCellSelected); - - function handleKeyDown({ - key - }) { - if (key === 'Enter') { - toggleGroup(); - } - } - - const d = isExpanded ? 'M1 1 L 7 7 L 13 1' : 'M1 7 L 7 1 L 13 7'; - return /*#__PURE__*/jsxRuntime.jsxs("span", { - ref: ref, - className: groupCellContentClassname, - tabIndex: tabIndex, - onKeyDown: handleKeyDown, - children: [groupKey, /*#__PURE__*/jsxRuntime.jsx("svg", { - viewBox: "0 0 14 8", - width: "14", - height: "8", - className: caretClassname, - "aria-hidden": true, - children: /*#__PURE__*/jsxRuntime.jsx("path", { - d: d - }) - })] - }); -} - -const RowSelectionContext = /*#__PURE__*/react.createContext(undefined); -const RowSelectionProvider = RowSelectionContext.Provider; -const RowSelectionChangeContext = /*#__PURE__*/react.createContext(undefined); -const RowSelectionChangeProvider = RowSelectionChangeContext.Provider; -function useRowSelection() { - const rowSelectionContext = react.useContext(RowSelectionContext); - const rowSelectionChangeContext = react.useContext(RowSelectionChangeContext); - - if (rowSelectionContext === undefined || rowSelectionChangeContext === undefined) { - throw new Error('useRowSelection must be used within DataGrid cells'); - } - - return [rowSelectionContext, rowSelectionChangeContext]; -} - -const SELECT_COLUMN_KEY = 'select-row'; - -function SelectFormatter(props) { - const [isRowSelected, onRowSelectionChange] = useRowSelection(); - return /*#__PURE__*/jsxRuntime.jsx(SelectCellFormatter, { - "aria-label": "Select", - isCellSelected: props.isCellSelected, - value: isRowSelected, - onChange: (checked, isShiftClick) => { - onRowSelectionChange({ - row: props.row, - checked, - isShiftClick - }); - } - }); -} - -function SelectGroupFormatter(props) { - const [isRowSelected, onRowSelectionChange] = useRowSelection(); - return /*#__PURE__*/jsxRuntime.jsx(SelectCellFormatter, { - "aria-label": "Select Group", - isCellSelected: props.isCellSelected, - value: isRowSelected, - onChange: checked => { - onRowSelectionChange({ - row: props.row, - checked, - isShiftClick: false - }); - } - }); -} - -const SelectColumn = { - key: SELECT_COLUMN_KEY, - name: '', - width: 35, - minWidth: 35, - maxWidth: 35, - resizable: false, - sortable: false, - frozen: true, - - headerRenderer(props) { - return /*#__PURE__*/jsxRuntime.jsx(SelectCellFormatter, { - "aria-label": "Select All", - isCellSelected: props.isCellSelected, - value: props.allRowsSelected, - onChange: props.onAllRowsSelectionChange - }); - }, - - formatter: SelectFormatter, - groupFormatter: SelectGroupFormatter -}; - function getColSpan(column, lastFrozenColumnIndex, args) { const colSpan = typeof column.colSpan === 'function' ? column.colSpan(args) : 1; - if (Number.isInteger(colSpan) && colSpan > 1 && (!column.frozen || column.idx + colSpan - 1 <= lastFrozenColumnIndex)) { return colSpan; } - return undefined; } +function stopPropagation(event) { + event.stopPropagation(); +} function scrollIntoView(element) { element?.scrollIntoView({ inline: 'nearest', @@ -285,6 +25,21 @@ function scrollIntoView(element) { }); } +function createCellEvent(event) { + let defaultPrevented = false; + const cellEvent = { + ...event, + preventGridDefault() { + defaultPrevented = true; + }, + isGridDefaultPrevented() { + return defaultPrevented; + } + }; + Object.setPrototypeOf(cellEvent, Object.getPrototypeOf(event)); + return cellEvent; +} + const nonInputKeys = new Set(['Unidentified', 'Alt', 'AltGraph', 'CapsLock', 'Control', 'Fn', 'FnLock', 'Meta', 'NumLock', 'ScrollLock', 'Shift', 'Tab', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'End', 'Home', 'PageDown', 'PageUp', 'Insert', 'ContextMenu', 'Escape', 'Pause', 'Play', 'PrintScreen', 'F1', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12']); function isCtrlKeyHeldDown(e) { return (e.ctrlKey || e.metaKey) && e.key !== 'Control'; @@ -297,154 +52,200 @@ function onEditorNavigation({ target }) { if (key === 'Tab' && (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLSelectElement)) { - return target.matches('.rdg-editor-container > :only-child, .rdg-editor-container > label:only-child > :only-child'); + return target.closest('.rdg-editor-container')?.querySelectorAll('input, textarea, select').length === 1; } - return false; } -function isSelectedCellSelectable(columns, selectedPosition) { - const column = columns[selectedPosition.idx]; - return column.selectable !== false; +const measuringCellClassname = "m1l09lto7-0-0-beta-37"; +function renderMeasuringCells(viewportColumns) { + return viewportColumns.map(({ + key, + idx, + minWidth, + maxWidth + }) => /*#__PURE__*/jsxRuntime.jsx("div", { + className: measuringCellClassname, + style: { + gridColumnStart: idx + 1, + minWidth, + maxWidth + }, + "data-measuring-cell-key": key + }, key)); } + function isSelectedCellEditable({ selectedPosition, columns, - rows, - isGroupRow + rows }) { const column = columns[selectedPosition.idx]; const row = rows[selectedPosition.rowIdx]; - return !isGroupRow(row) && isCellEditable(column, row); + return isCellEditable(column, row); } function isCellEditable(column, row) { - return column.editor != null && !column.rowGroup && (typeof column.editable === 'function' ? column.editable(row) : column.editable) !== false; + return column.renderEditCell != null && (typeof column.editable === 'function' ? column.editable(row) : column.editable) !== false; } function getSelectedCellColSpan({ rows, - summaryRows, + topSummaryRows, + bottomSummaryRows, rowIdx, + mainHeaderRowIdx, lastFrozenColumnIndex, - column, - isGroupRow + column }) { - if (rowIdx === -1) { + const topSummaryRowsCount = topSummaryRows?.length ?? 0; + if (rowIdx === mainHeaderRowIdx) { return getColSpan(column, lastFrozenColumnIndex, { type: 'HEADER' }); } - + if (topSummaryRows && rowIdx > mainHeaderRowIdx && rowIdx <= topSummaryRowsCount + mainHeaderRowIdx) { + return getColSpan(column, lastFrozenColumnIndex, { + type: 'SUMMARY', + row: topSummaryRows[rowIdx + topSummaryRowsCount] + }); + } if (rowIdx >= 0 && rowIdx < rows.length) { const row = rows[rowIdx]; - - if (!isGroupRow(row)) { - return getColSpan(column, lastFrozenColumnIndex, { - type: 'ROW', - row - }); - } - - return undefined; + return getColSpan(column, lastFrozenColumnIndex, { + type: 'ROW', + row + }); } - - if (summaryRows) { + if (bottomSummaryRows) { return getColSpan(column, lastFrozenColumnIndex, { type: 'SUMMARY', - row: summaryRows[rowIdx - rows.length] + row: bottomSummaryRows[rowIdx - rows.length] }); } - return undefined; } function getNextSelectedCellPosition({ + moveUp, + moveNext, cellNavigationMode, columns, colSpanColumns, rows, - summaryRows, + topSummaryRows, + bottomSummaryRows, minRowIdx, + mainHeaderRowIdx, maxRowIdx, currentPosition: { - idx: currentIdx + idx: currentIdx, + rowIdx: currentRowIdx }, nextPosition, lastFrozenColumnIndex, - isCellWithinBounds, - isGroupRow + isCellWithinBounds }) { let { idx: nextIdx, rowIdx: nextRowIdx } = nextPosition; - - const setColSpan = moveRight => { - if (nextRowIdx >= 0 && nextRowIdx < rows.length) { - const row = rows[nextRowIdx]; - if (isGroupRow(row)) return; - } - + const columnsCount = columns.length; + const setColSpan = moveNext => { for (const column of colSpanColumns) { const colIdx = column.idx; if (colIdx > nextIdx) break; const colSpan = getSelectedCellColSpan({ rows, - summaryRows, + topSummaryRows, + bottomSummaryRows, rowIdx: nextRowIdx, + mainHeaderRowIdx, lastFrozenColumnIndex, - column, - isGroupRow + column }); - if (colSpan && nextIdx > colIdx && nextIdx < colSpan + colIdx) { - nextIdx = colIdx + (moveRight ? colSpan : 0); + nextIdx = colIdx + (moveNext ? colSpan : 0); break; } } }; - + const getParentRowIdx = parent => { + return parent.level + mainHeaderRowIdx; + }; + const setHeaderGroupColAndRowSpan = () => { + if (moveNext) { + const nextColumn = columns[nextIdx]; + let parent = nextColumn.parent; + while (parent !== undefined) { + const parentRowIdx = getParentRowIdx(parent); + if (nextRowIdx === parentRowIdx) { + nextIdx = parent.idx + parent.colSpan; + break; + } + parent = parent.parent; + } + } else if (moveUp) { + const nextColumn = columns[nextIdx]; + let parent = nextColumn.parent; + let found = false; + while (parent !== undefined) { + const parentRowIdx = getParentRowIdx(parent); + if (nextRowIdx >= parentRowIdx) { + nextIdx = parent.idx; + nextRowIdx = parentRowIdx; + found = true; + break; + } + parent = parent.parent; + } + if (!found) { + nextIdx = currentIdx; + nextRowIdx = currentRowIdx; + } + } + }; if (isCellWithinBounds(nextPosition)) { - setColSpan(nextIdx - currentIdx > 0); + setColSpan(moveNext); + if (nextRowIdx < mainHeaderRowIdx) { + setHeaderGroupColAndRowSpan(); + } } - - if (cellNavigationMode !== 'NONE') { - const columnsCount = columns.length; + if (cellNavigationMode === 'CHANGE_ROW') { const isAfterLastColumn = nextIdx === columnsCount; const isBeforeFirstColumn = nextIdx === -1; - if (isAfterLastColumn) { - if (cellNavigationMode === 'CHANGE_ROW') { - const isLastRow = nextRowIdx === maxRowIdx; - - if (!isLastRow) { - nextIdx = 0; - nextRowIdx += 1; - } - } else { + const isLastRow = nextRowIdx === maxRowIdx; + if (!isLastRow) { nextIdx = 0; + nextRowIdx += 1; } } else if (isBeforeFirstColumn) { - if (cellNavigationMode === 'CHANGE_ROW') { - const isFirstRow = nextRowIdx === minRowIdx; - - if (!isFirstRow) { - nextRowIdx -= 1; - nextIdx = columnsCount - 1; - } - } else { + const isFirstRow = nextRowIdx === minRowIdx; + if (!isFirstRow) { + nextRowIdx -= 1; nextIdx = columnsCount - 1; } - setColSpan(false); } } - + if (nextRowIdx < mainHeaderRowIdx) { + const nextColumn = columns[nextIdx]; + let parent = nextColumn.parent; + const nextParentRowIdx = nextRowIdx; + nextRowIdx = mainHeaderRowIdx; + while (parent !== undefined) { + const parentRowIdx = getParentRowIdx(parent); + if (parentRowIdx >= nextParentRowIdx) { + nextRowIdx = parentRowIdx; + nextIdx = parent.idx; + } + parent = parent.parent; + } + } return { idx: nextIdx, rowIdx: nextRowIdx }; } function canExitGrid({ - cellNavigationMode, maxColIdx, minRowIdx, maxRowIdx, @@ -454,17 +255,20 @@ function canExitGrid({ }, shiftKey }) { - if (cellNavigationMode === 'NONE' || cellNavigationMode === 'CHANGE_ROW') { - const atLastCellInRow = idx === maxColIdx; - const atFirstCellInRow = idx === 0; - const atLastRow = rowIdx === maxRowIdx; - const atFirstRow = rowIdx === minRowIdx; - return shiftKey ? atFirstCellInRow && atFirstRow : atLastCellInRow && atLastRow; - } - - return false; + const atLastCellInRow = idx === maxColIdx; + const atFirstCellInRow = idx === 0; + const atLastRow = rowIdx === maxRowIdx; + const atFirstRow = rowIdx === minRowIdx; + return shiftKey ? atFirstCellInRow && atFirstRow : atLastCellInRow && atLastRow; } +const cell = "c1wupbe7-0-0-beta-37"; +const cellClassname = `rdg-cell ${cell}`; +const cellFrozen = "cd0kgiy7-0-0-beta-37"; +const cellFrozenClassname = `rdg-cell-frozen ${cellFrozen}`; +const cellFrozenLast = "c1730fa47-0-0-beta-37"; +const cellFrozenLastClassname = `rdg-cell-frozen-last ${cellFrozenLast}`; + function getRowStyle(rowIdx, height) { if (height !== undefined) { return { @@ -472,16 +276,34 @@ function getRowStyle(rowIdx, height) { '--rdg-row-height': `${height}px` }; } - return { '--rdg-grid-row-start': rowIdx }; } -function getCellStyle(column, colSpan) { - return { - gridColumnStart: column.idx + 1, - gridColumnEnd: colSpan !== undefined ? `span ${colSpan}` : undefined, - insetInlineStart: column.frozen ? `var(--rdg-frozen-left-${column.idx})` : undefined +function getHeaderCellStyle(column, rowIdx, rowSpan) { + const gridRowEnd = rowIdx + 1; + const paddingBlockStart = `calc(${rowSpan - 1} * var(--rdg-header-row-height))`; + if (column.parent === undefined) { + return { + insetBlockStart: 0, + gridRowStart: 1, + gridRowEnd, + paddingBlockStart + }; + } + return { + insetBlockStart: `calc(${rowIdx - rowSpan} * var(--rdg-header-row-height))`, + gridRowStart: gridRowEnd - rowSpan, + gridRowEnd, + paddingBlockStart + }; +} +function getCellStyle(column, colSpan = 1) { + const index = column.idx + 1; + return { + gridColumnStart: index, + gridColumnEnd: index + colSpan, + insetInlineStart: column.frozen ? `var(--rdg-frozen-left-${column.idx})` : undefined }; } function getCellClassname(column, ...extraClasses) { @@ -494,8 +316,7 @@ const { round, floor, sign, - abs, - ceil + abs } = Math; function assertIsValidKeyGetter(keyGetter) { if (typeof keyGetter !== 'function') { @@ -507,63 +328,267 @@ function clampColumnWidth(width, { maxWidth }) { width = max(width, minWidth); - if (typeof maxWidth === 'number' && maxWidth >= minWidth) { return min(width, maxWidth); } - return width; } +function getHeaderCellRowSpan(column, rowIdx) { + return column.parent === undefined ? rowIdx : column.level - column.parent.level; +} + +const checkboxLabel = "c1hs68w07-0-0-beta-37"; +const checkboxLabelClassname = `rdg-checkbox-label ${checkboxLabel}`; +const checkboxInput = "cojpd0n7-0-0-beta-37"; +const checkboxInputClassname = `rdg-checkbox-input ${checkboxInput}`; +const checkbox = "cwsfieb7-0-0-beta-37"; +const checkboxClassname = `rdg-checkbox ${checkbox}`; +const checkboxLabelDisabled = "c1fgadbl7-0-0-beta-37"; +const checkboxLabelDisabledClassname = `rdg-checkbox-label-disabled ${checkboxLabelDisabled}`; +function renderCheckbox({ + onChange, + ...props +}) { + function handleChange(e) { + onChange(e.target.checked, e.nativeEvent.shiftKey); + } + return /*#__PURE__*/jsxRuntime.jsxs("label", { + className: clsx(checkboxLabelClassname, props.disabled && checkboxLabelDisabledClassname), + children: [/*#__PURE__*/jsxRuntime.jsx("input", { + type: "checkbox", + ...props, + className: checkboxInputClassname, + onChange: handleChange + }), /*#__PURE__*/jsxRuntime.jsx("div", { + className: checkboxClassname + })] + }); +} + +const groupCellContent = "g1w3c5217-0-0-beta-37"; +const groupCellContentClassname = `rdg-group-cell-content ${groupCellContent}`; +const caret = "cm5tyhw7-0-0-beta-37"; +const caretClassname = `rdg-caret ${caret}`; +function renderToggleGroup(props) { + return /*#__PURE__*/jsxRuntime.jsx(ToggleGroup, { + ...props + }); +} +function ToggleGroup({ + groupKey, + isExpanded, + tabIndex, + toggleGroup +}) { + function handleKeyDown({ + key + }) { + if (key === 'Enter') { + toggleGroup(); + } + } + const d = isExpanded ? 'M1 1 L 7 7 L 13 1' : 'M1 7 L 7 1 L 13 7'; + return /*#__PURE__*/jsxRuntime.jsxs("span", { + className: groupCellContentClassname, + tabIndex: tabIndex, + onKeyDown: handleKeyDown, + children: [groupKey, /*#__PURE__*/jsxRuntime.jsx("svg", { + viewBox: "0 0 14 8", + width: "14", + height: "8", + className: caretClassname, + "aria-hidden": true, + children: /*#__PURE__*/jsxRuntime.jsx("path", { + d: d + }) + })] + }); +} + +function renderValue(props) { + try { + return props.row[props.column.key]; + } catch { + return null; + } +} + +const DataGridDefaultRenderersContext = /*#__PURE__*/react.createContext(undefined); +const DataGridDefaultRenderersProvider = DataGridDefaultRenderersContext.Provider; +function useDefaultRenderers() { + return react.useContext(DataGridDefaultRenderersContext); +} + +function SelectCellFormatter({ + value, + tabIndex, + disabled, + onChange, + 'aria-label': ariaLabel, + 'aria-labelledby': ariaLabelledBy +}) { + const renderCheckbox = useDefaultRenderers().renderCheckbox; + return renderCheckbox({ + 'aria-label': ariaLabel, + 'aria-labelledby': ariaLabelledBy, + tabIndex, + disabled, + checked: value, + onChange + }); +} + +const RowSelectionContext = /*#__PURE__*/react.createContext(undefined); +const RowSelectionProvider = RowSelectionContext.Provider; +const RowSelectionChangeContext = /*#__PURE__*/react.createContext(undefined); +const RowSelectionChangeProvider = RowSelectionChangeContext.Provider; +function useRowSelection() { + const rowSelectionContext = react.useContext(RowSelectionContext); + const rowSelectionChangeContext = react.useContext(RowSelectionChangeContext); + if (rowSelectionContext === undefined || rowSelectionChangeContext === undefined) { + throw new Error('useRowSelection must be used within DataGrid cells'); + } + return [rowSelectionContext, rowSelectionChangeContext]; +} + +const SELECT_COLUMN_KEY = 'select-row'; +function HeaderRenderer(props) { + const [isRowSelected, onRowSelectionChange] = useRowSelection(); + return /*#__PURE__*/jsxRuntime.jsx(SelectCellFormatter, { + "aria-label": "Select All", + tabIndex: props.tabIndex, + value: isRowSelected, + onChange: checked => { + onRowSelectionChange({ + type: 'HEADER', + checked + }); + } + }); +} +function SelectFormatter(props) { + const [isRowSelected, onRowSelectionChange] = useRowSelection(); + return /*#__PURE__*/jsxRuntime.jsx(SelectCellFormatter, { + "aria-label": "Select", + tabIndex: props.tabIndex, + value: isRowSelected, + onChange: (checked, isShiftClick) => { + onRowSelectionChange({ + type: 'ROW', + row: props.row, + checked, + isShiftClick + }); + } + }); +} +function SelectGroupFormatter(props) { + const [isRowSelected, onRowSelectionChange] = useRowSelection(); + return /*#__PURE__*/jsxRuntime.jsx(SelectCellFormatter, { + "aria-label": "Select Group", + tabIndex: props.tabIndex, + value: isRowSelected, + onChange: checked => { + onRowSelectionChange({ + type: 'ROW', + row: props.row, + checked, + isShiftClick: false + }); + } + }); +} +const SelectColumn = { + key: SELECT_COLUMN_KEY, + name: '', + width: 35, + minWidth: 35, + maxWidth: 35, + resizable: false, + sortable: false, + frozen: true, + renderHeaderCell(props) { + return /*#__PURE__*/jsxRuntime.jsx(HeaderRenderer, { + ...props + }); + }, + renderCell(props) { + return /*#__PURE__*/jsxRuntime.jsx(SelectFormatter, { + ...props + }); + }, + renderGroupCell(props) { + return /*#__PURE__*/jsxRuntime.jsx(SelectGroupFormatter, { + ...props + }); + } +}; +const DEFAULT_COLUMN_WIDTH = 'auto'; +const DEFAULT_COLUMN_MIN_WIDTH = 50; function useCalculatedColumns({ rawColumns, - columnWidths, + defaultColumnOptions, + measuredColumnWidths, + resizedColumnWidths, viewportWidth, scrollLeft, - defaultColumnOptions, - rawGroupBy, enableVirtualization }) { - const defaultWidth = defaultColumnOptions?.width; - const defaultMinWidth = defaultColumnOptions?.minWidth ?? 80; - const defaultMaxWidth = defaultColumnOptions?.maxWidth; - const defaultFormatter = defaultColumnOptions?.formatter ?? ValueFormatter; + const defaultWidth = defaultColumnOptions?.width ?? DEFAULT_COLUMN_WIDTH; + const defaultMinWidth = defaultColumnOptions?.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH; + const defaultMaxWidth = defaultColumnOptions?.maxWidth ?? undefined; + const defaultCellRenderer = defaultColumnOptions?.renderCell ?? renderValue; const defaultSortable = defaultColumnOptions?.sortable ?? false; const defaultResizable = defaultColumnOptions?.resizable ?? false; const { columns, colSpanColumns, lastFrozenColumnIndex, - groupBy + headerRowsCount } = react.useMemo(() => { - const groupBy = []; let lastFrozenColumnIndex = -1; - const columns = rawColumns.map(rawColumn => { - const rowGroup = rawGroupBy?.includes(rawColumn.key) ?? false; - const frozen = rowGroup || rawColumn.frozen || false; - const column = { ...rawColumn, - idx: 0, - frozen, - isLastFrozenColumn: false, - rowGroup, - width: rawColumn.width ?? defaultWidth, - minWidth: rawColumn.minWidth ?? defaultMinWidth, - maxWidth: rawColumn.maxWidth ?? defaultMaxWidth, - sortable: rawColumn.sortable ?? defaultSortable, - resizable: rawColumn.resizable ?? defaultResizable, - formatter: rawColumn.formatter ?? defaultFormatter - }; - - if (rowGroup) { - column.groupFormatter ?? (column.groupFormatter = ToggleGroupFormatter); - } - - if (frozen) { - lastFrozenColumnIndex++; + let headerRowsCount = 1; + const columns = []; + collectColumns(rawColumns, 1); + function collectColumns(rawColumns, level, parent) { + for (const rawColumn of rawColumns) { + if ('children' in rawColumn) { + const calculatedColumnParent = { + name: rawColumn.name, + parent, + idx: -1, + colSpan: 0, + level: 0, + headerCellClass: rawColumn.headerCellClass + }; + collectColumns(rawColumn.children, level + 1, calculatedColumnParent); + continue; + } + const frozen = rawColumn.frozen ?? false; + const column = { + ...rawColumn, + parent, + idx: 0, + level: 0, + frozen, + isLastFrozenColumn: false, + width: rawColumn.width ?? defaultWidth, + minWidth: rawColumn.minWidth ?? defaultMinWidth, + maxWidth: rawColumn.maxWidth ?? defaultMaxWidth, + sortable: rawColumn.sortable ?? defaultSortable, + resizable: rawColumn.resizable ?? defaultResizable, + renderCell: rawColumn.renderCell ?? defaultCellRenderer + }; + columns.push(column); + if (frozen) { + lastFrozenColumnIndex++; + } + if (level > headerRowsCount) { + headerRowsCount = level; + } } - - return column; - }); + } columns.sort(({ key: aKey, frozen: frozenA @@ -573,50 +598,33 @@ function useCalculatedColumns({ }) => { if (aKey === SELECT_COLUMN_KEY) return -1; if (bKey === SELECT_COLUMN_KEY) return 1; - - if (rawGroupBy?.includes(aKey)) { - if (rawGroupBy.includes(bKey)) { - return rawGroupBy.indexOf(aKey) - rawGroupBy.indexOf(bKey); - } - - return -1; - } - - if (rawGroupBy?.includes(bKey)) return 1; - if (frozenA) { if (frozenB) return 0; return -1; } - if (frozenB) return 1; return 0; }); const colSpanColumns = []; columns.forEach((column, idx) => { column.idx = idx; - - if (column.rowGroup) { - groupBy.push(column.key); - } - + updateColumnParent(column, idx, 0); if (column.colSpan != null) { colSpanColumns.push(column); } }); - if (lastFrozenColumnIndex !== -1) { columns[lastFrozenColumnIndex].isLastFrozenColumn = true; } - return { columns, colSpanColumns, lastFrozenColumnIndex, - groupBy + headerRowsCount }; - }, [rawColumns, defaultWidth, defaultMinWidth, defaultMaxWidth, defaultFormatter, defaultResizable, defaultSortable, rawGroupBy]); + }, [rawColumns, defaultWidth, defaultMinWidth, defaultMaxWidth, defaultCellRenderer, defaultResizable, defaultSortable]); const { + templateColumns, layoutCssVars, totalFrozenColumnWidth, columnMetrics @@ -624,114 +632,70 @@ function useCalculatedColumns({ const columnMetrics = new Map(); let left = 0; let totalFrozenColumnWidth = 0; - let templateColumns = ''; - let allocatedWidth = 0; - let unassignedColumnsCount = 0; - + const templateColumns = []; for (const column of columns) { - let width = getSpecifiedWidth(column, columnWidths, viewportWidth); - - if (width === undefined) { - unassignedColumnsCount++; - } else { + let width = resizedColumnWidths.get(column.key) ?? measuredColumnWidths.get(column.key) ?? column.width; + if (typeof width === 'number') { width = clampColumnWidth(width, column); - allocatedWidth += width; - columnMetrics.set(column, { - width, - left: 0 - }); - } - } - - for (const column of columns) { - let width; - - if (columnMetrics.has(column)) { - const columnMetric = columnMetrics.get(column); - columnMetric.left = left; - ({ - width - } = columnMetric); } else { - const unallocatedWidth = viewportWidth - allocatedWidth; - const unallocatedColumnWidth = round(unallocatedWidth / unassignedColumnsCount); - width = clampColumnWidth(unallocatedColumnWidth, column); - allocatedWidth += width; - unassignedColumnsCount--; - columnMetrics.set(column, { - width, - left - }); + width = column.minWidth; } - + templateColumns.push(`${width}px`); + columnMetrics.set(column, { + width, + left + }); left += width; - templateColumns += `${width}px `; } - if (lastFrozenColumnIndex !== -1) { const columnMetric = columnMetrics.get(columns[lastFrozenColumnIndex]); totalFrozenColumnWidth = columnMetric.left + columnMetric.width; } - - const layoutCssVars = { - gridTemplateColumns: templateColumns - }; - + const layoutCssVars = {}; for (let i = 0; i <= lastFrozenColumnIndex; i++) { const column = columns[i]; layoutCssVars[`--rdg-frozen-left-${column.idx}`] = `${columnMetrics.get(column).left}px`; } - return { + templateColumns, layoutCssVars, totalFrozenColumnWidth, columnMetrics }; - }, [columnWidths, columns, viewportWidth, lastFrozenColumnIndex]); + }, [measuredColumnWidths, resizedColumnWidths, columns, lastFrozenColumnIndex]); const [colOverscanStartIdx, colOverscanEndIdx] = react.useMemo(() => { if (!enableVirtualization) { return [0, columns.length - 1]; } - const viewportLeft = scrollLeft + totalFrozenColumnWidth; const viewportRight = scrollLeft + viewportWidth; const lastColIdx = columns.length - 1; const firstUnfrozenColumnIdx = min(lastFrozenColumnIndex + 1, lastColIdx); - if (viewportLeft >= viewportRight) { return [firstUnfrozenColumnIdx, firstUnfrozenColumnIdx]; } - let colVisibleStartIdx = firstUnfrozenColumnIdx; - while (colVisibleStartIdx < lastColIdx) { const { left, width } = columnMetrics.get(columns[colVisibleStartIdx]); - if (left + width > viewportLeft) { break; } - colVisibleStartIdx++; } - let colVisibleEndIdx = colVisibleStartIdx; - while (colVisibleEndIdx < lastColIdx) { const { left, width } = columnMetrics.get(columns[colVisibleEndIdx]); - if (left + width >= viewportRight) { break; } - colVisibleEndIdx++; } - const colOverscanStartIdx = max(firstUnfrozenColumnIdx, colVisibleStartIdx - 1); const colOverscanEndIdx = min(lastColIdx, colVisibleEndIdx + 1); return [colOverscanStartIdx, colOverscanEndIdx]; @@ -741,31 +705,109 @@ function useCalculatedColumns({ colSpanColumns, colOverscanStartIdx, colOverscanEndIdx, + templateColumns, layoutCssVars, - columnMetrics, + headerRowsCount, lastFrozenColumnIndex, - totalFrozenColumnWidth, - groupBy + totalFrozenColumnWidth }; } - -function getSpecifiedWidth({ - key, - width -}, columnWidths, viewportWidth) { - if (columnWidths.has(key)) { - return columnWidths.get(key); +function updateColumnParent(column, index, level) { + if (level < column.level) { + column.level = level; } - - if (typeof width === 'number') { - return width; + if (column.parent !== undefined) { + const { + parent + } = column; + if (parent.idx === -1) { + parent.idx = index; + } + parent.colSpan += 1; + updateColumnParent(parent, index, level - 1); } +} - if (typeof width === 'string' && /^\d+%$/.test(width)) { - return floor(viewportWidth * parseInt(width, 10) / 100); - } +const useLayoutEffect = typeof window === 'undefined' ? react.useEffect : react.useLayoutEffect; - return undefined; +function useColumnWidths(columns, viewportColumns, templateColumns, gridRef, gridWidth, resizedColumnWidths, measuredColumnWidths, setResizedColumnWidths, setMeasuredColumnWidths, onColumnResize) { + const prevGridWidthRef = react.useRef(gridWidth); + const columnsCanFlex = columns.length === viewportColumns.length; + const ignorePreviouslyMeasuredColumns = columnsCanFlex && gridWidth !== prevGridWidthRef.current; + const newTemplateColumns = [...templateColumns]; + const columnsToMeasure = []; + for (const { + key, + idx, + width + } of viewportColumns) { + if (typeof width === 'string' && (ignorePreviouslyMeasuredColumns || !measuredColumnWidths.has(key)) && !resizedColumnWidths.has(key)) { + newTemplateColumns[idx] = width; + columnsToMeasure.push(key); + } + } + const gridTemplateColumns = newTemplateColumns.join(' '); + useLayoutEffect(() => { + prevGridWidthRef.current = gridWidth; + updateMeasuredWidths(columnsToMeasure); + }); + function updateMeasuredWidths(columnsToMeasure) { + if (columnsToMeasure.length === 0) return; + setMeasuredColumnWidths(measuredColumnWidths => { + const newMeasuredColumnWidths = new Map(measuredColumnWidths); + let hasChanges = false; + for (const key of columnsToMeasure) { + const measuredWidth = measureColumnWidth(gridRef, key); + hasChanges ||= measuredWidth !== measuredColumnWidths.get(key); + if (measuredWidth === undefined) { + newMeasuredColumnWidths.delete(key); + } else { + newMeasuredColumnWidths.set(key, measuredWidth); + } + } + return hasChanges ? newMeasuredColumnWidths : measuredColumnWidths; + }); + } + function handleColumnResize(column, nextWidth) { + const { + key: resizingKey + } = column; + const newTemplateColumns = [...templateColumns]; + const columnsToMeasure = []; + for (const { + key, + idx, + width + } of viewportColumns) { + if (resizingKey === key) { + const width = typeof nextWidth === 'number' ? `${nextWidth}px` : nextWidth; + newTemplateColumns[idx] = width; + } else if (columnsCanFlex && typeof width === 'string' && !resizedColumnWidths.has(key)) { + newTemplateColumns[idx] = width; + columnsToMeasure.push(key); + } + } + gridRef.current.style.gridTemplateColumns = newTemplateColumns.join(' '); + const measuredWidth = typeof nextWidth === 'number' ? nextWidth : measureColumnWidth(gridRef, resizingKey); + reactDom.flushSync(() => { + setResizedColumnWidths(resizedColumnWidths => { + const newResizedColumnWidths = new Map(resizedColumnWidths); + newResizedColumnWidths.set(resizingKey, measuredWidth); + return newResizedColumnWidths; + }); + updateMeasuredWidths(columnsToMeasure); + }); + onColumnResize?.(column.idx, measuredWidth); + } + return { + gridTemplateColumns, + handleColumnResize + }; +} +function measureColumnWidth(gridRef, key) { + const selector = `[data-measuring-cell-key="${CSS.escape(key)}"]`; + const measuringCell = gridRef.current.querySelector(selector); + return measuringCell?.getBoundingClientRect().width; } function useGridDimensions() { @@ -789,14 +831,14 @@ function useGridDimensions() { } = gridRef.current.getBoundingClientRect(); const initialWidth = width - offsetWidth + clientWidth; const initialHeight = height - offsetHeight + clientHeight; - setInlineSize(handleDevicePixelRatio(initialWidth)); + setInlineSize(initialWidth); setBlockSize(initialHeight); const resizeObserver = new ResizeObserver(entries => { - if (entries[0].contentBoxSize?.length > 0) { - const size = entries[0].contentBoxSize[0]; - setInlineSize(handleDevicePixelRatio(size.inlineSize)); + const size = entries[0].contentBoxSize[0]; + reactDom.flushSync(() => { + setInlineSize(size.inlineSize); setBlockSize(size.blockSize); - } + }); }); resizeObserver.observe(gridRef.current); return () => { @@ -806,47 +848,31 @@ function useGridDimensions() { return [gridRef, inlineSize, blockSize]; } -function handleDevicePixelRatio(size) { - return size - (devicePixelRatio === 1 ? 0 : ceil(devicePixelRatio)); -} - function useLatestFunc(fn) { const ref = react.useRef(fn); react.useEffect(() => { ref.current = fn; }); - return react.useCallback((...args) => { + const callbackFn = react.useCallback((...args) => { ref.current(...args); }, []); + return fn ? callbackFn : fn; } -function useRovingCellRef(isSelected) { +function useRovingTabIndex(isSelected) { const [isChildFocused, setIsChildFocused] = react.useState(false); - const [cell, setRef] = react.useState(null); - if (isChildFocused && !isSelected) { setIsChildFocused(false); } - function onFocus(event) { if (event.target !== event.currentTarget) { setIsChildFocused(true); } } - - useLayoutEffect(() => { - if (isSelected && cell) { - scrollIntoView(cell); - if (cell.contains(document.activeElement)) return; - cell.focus({ - preventScroll: true - }); - } - }, [isSelected, cell]); - const isFocused = isSelected && !isChildFocused; + const isFocusable = isSelected && !isChildFocused; return { - ref: setRef, - tabIndex: isFocused ? 0 : -1, + tabIndex: isFocusable ? 0 : -1, + childTabIndex: isSelected ? 0 : -1, onFocus: isSelected ? onFocus : undefined }; } @@ -855,41 +881,34 @@ function useViewportColumns({ columns, colSpanColumns, rows, - summaryRows, + topSummaryRows, + bottomSummaryRows, colOverscanStartIdx, colOverscanEndIdx, lastFrozenColumnIndex, rowOverscanStartIdx, - rowOverscanEndIdx, - isGroupRow + rowOverscanEndIdx }) { const startIdx = react.useMemo(() => { if (colOverscanStartIdx === 0) return 0; let startIdx = colOverscanStartIdx; - const updateStartIdx = (colIdx, colSpan) => { if (colSpan !== undefined && colIdx + colSpan > colOverscanStartIdx) { startIdx = colIdx; return true; } - return false; }; - for (const column of colSpanColumns) { const colIdx = column.idx; if (colIdx >= startIdx) break; - if (updateStartIdx(colIdx, getColSpan(column, lastFrozenColumnIndex, { type: 'HEADER' }))) { break; } - for (let rowIdx = rowOverscanStartIdx; rowIdx <= rowOverscanEndIdx; rowIdx++) { const row = rows[rowIdx]; - if (isGroupRow(row)) continue; - if (updateStartIdx(colIdx, getColSpan(column, lastFrozenColumnIndex, { type: 'ROW', row @@ -897,9 +916,18 @@ function useViewportColumns({ break; } } - - if (summaryRows != null) { - for (const row of summaryRows) { + if (topSummaryRows != null) { + for (const row of topSummaryRows) { + if (updateStartIdx(colIdx, getColSpan(column, lastFrozenColumnIndex, { + type: 'SUMMARY', + row + }))) { + break; + } + } + } + if (bottomSummaryRows != null) { + for (const row of bottomSummaryRows) { if (updateStartIdx(colIdx, getColSpan(column, lastFrozenColumnIndex, { type: 'SUMMARY', row @@ -909,104 +937,26 @@ function useViewportColumns({ } } } - return startIdx; - }, [rowOverscanStartIdx, rowOverscanEndIdx, rows, summaryRows, colOverscanStartIdx, lastFrozenColumnIndex, colSpanColumns, isGroupRow]); + }, [rowOverscanStartIdx, rowOverscanEndIdx, rows, topSummaryRows, bottomSummaryRows, colOverscanStartIdx, lastFrozenColumnIndex, colSpanColumns]); return react.useMemo(() => { const viewportColumns = []; - for (let colIdx = 0; colIdx <= colOverscanEndIdx; colIdx++) { const column = columns[colIdx]; if (colIdx < startIdx && !column.frozen) continue; viewportColumns.push(column); } - return viewportColumns; }, [startIdx, colOverscanEndIdx, columns]); } -function isReadonlyArray(arr) { - return Array.isArray(arr); -} - function useViewportRows({ - rawRows, + rows, rowHeight, clientHeight, scrollTop, - groupBy, - rowGrouper, - expandedGroupIds, enableVirtualization }) { - const [groupedRows, rowsCount] = react.useMemo(() => { - if (groupBy.length === 0 || rowGrouper == null) return [undefined, rawRows.length]; - - const groupRows = (rows, [groupByKey, ...remainingGroupByKeys], startRowIndex) => { - let groupRowsCount = 0; - const groups = {}; - - for (const [key, childRows] of Object.entries(rowGrouper(rows, groupByKey))) { - const [childGroups, childRowsCount] = remainingGroupByKeys.length === 0 ? [childRows, childRows.length] : groupRows(childRows, remainingGroupByKeys, startRowIndex + groupRowsCount + 1); - groups[key] = { - childRows, - childGroups, - startRowIndex: startRowIndex + groupRowsCount - }; - groupRowsCount += childRowsCount + 1; - } - - return [groups, groupRowsCount]; - }; - - return groupRows(rawRows, groupBy, 0); - }, [groupBy, rowGrouper, rawRows]); - const [rows, isGroupRow] = react.useMemo(() => { - const allGroupRows = new Set(); - if (!groupedRows) return [rawRows, isGroupRow]; - const flattenedRows = []; - - const expandGroup = (rows, parentId, level) => { - if (isReadonlyArray(rows)) { - flattenedRows.push(...rows); - return; - } - - Object.keys(rows).forEach((groupKey, posInSet, keys) => { - const id = parentId !== undefined ? `${parentId}__${groupKey}` : groupKey; - const isExpanded = expandedGroupIds?.has(id) ?? false; - const { - childRows, - childGroups, - startRowIndex - } = rows[groupKey]; - const groupRow = { - id, - parentId, - groupKey, - isExpanded, - childRows, - level, - posInSet, - startRowIndex, - setSize: keys.length - }; - flattenedRows.push(groupRow); - allGroupRows.add(groupRow); - - if (isExpanded) { - expandGroup(childGroups, id, level + 1); - } - }); - }; - - expandGroup(groupedRows, undefined, 0); - return [flattenedRows, isGroupRow]; - - function isGroupRow(row) { - return allGroupRows.has(row); - } - }, [expandedGroupIds, groupedRows, rawRows]); const { totalRowHeight, gridTemplateRows, @@ -1023,17 +973,10 @@ function useViewportRows({ findRowIdx: offset => floor(offset / rowHeight) }; } - let totalRowHeight = 0; let gridTemplateRows = ' '; const rowPositions = rows.map(row => { - const currentRowHeight = isGroupRow(row) ? rowHeight({ - type: 'GROUP', - row - }) : rowHeight({ - type: 'ROW', - row - }); + const currentRowHeight = rowHeight(row); const position = { top: totalRowHeight, height: currentRowHeight @@ -1042,43 +985,34 @@ function useViewportRows({ totalRowHeight += currentRowHeight; return position; }); - const validateRowIdx = rowIdx => { return max(0, min(rows.length - 1, rowIdx)); }; - return { totalRowHeight, gridTemplateRows, getRowTop: rowIdx => rowPositions[validateRowIdx(rowIdx)].top, getRowHeight: rowIdx => rowPositions[validateRowIdx(rowIdx)].height, - findRowIdx(offset) { let start = 0; let end = rowPositions.length - 1; - while (start <= end) { const middle = start + floor((end - start) / 2); const currentOffset = rowPositions[middle].top; if (currentOffset === offset) return middle; - if (currentOffset < offset) { start = middle + 1; } else if (currentOffset > offset) { end = middle - 1; } - if (start > end) return end; } - return 0; } - }; - }, [isGroupRow, rowHeight, rows]); + }, [rowHeight, rows]); let rowOverscanStartIdx = 0; let rowOverscanEndIdx = rows.length - 1; - if (enableVirtualization) { const overscanThreshold = 4; const rowVisibleStartIdx = findRowIdx(scrollTop); @@ -1086,167 +1020,456 @@ function useViewportRows({ rowOverscanStartIdx = max(0, rowVisibleStartIdx - overscanThreshold); rowOverscanEndIdx = min(rows.length - 1, rowVisibleEndIdx + overscanThreshold); } - return { rowOverscanStartIdx, rowOverscanEndIdx, - rows, - rowsCount, totalRowHeight, gridTemplateRows, - isGroupRow, getRowTop, getRowHeight, findRowIdx }; } -var css_248z$a = ".h1af91pe700-beta13{cursor:pointer;display:flex}.h1af91pe700-beta13:focus{outline:none}.hifiwer700-beta13{flex-grow:1;overflow:hidden;overflow:clip;text-overflow:ellipsis}"; -styleInject(css_248z$a,{"insertAt":"top"}); - -const headerSortCell = "h1af91pe700-beta13"; -const headerSortCellClassname = `rdg-header-sort-cell ${headerSortCell}`; -const headerSortName = "hifiwer700-beta13"; -const headerSortNameClassname = `rdg-header-sort-name ${headerSortName}`; -function HeaderRenderer({ +const cellCopied = "ccpfvsn7-0-0-beta-37"; +const cellCopiedClassname = `rdg-cell-copied ${cellCopied}`; +const cellDraggedOver = "c1bmg16t7-0-0-beta-37"; +const cellDraggedOverClassname = `rdg-cell-dragged-over ${cellDraggedOver}`; +function Cell({ column, - sortDirection, - priority, - onSort, - isCellSelected -}) { - if (!column.sortable) return /*#__PURE__*/jsxRuntime.jsx(jsxRuntime.Fragment, { - children: column.name - }); - return /*#__PURE__*/jsxRuntime.jsx(SortableHeaderCell, { - onSort: onSort, - sortDirection: sortDirection, - priority: priority, - isCellSelected: isCellSelected, - children: column.name - }); -} - -function SortableHeaderCell({ - onSort, - sortDirection, - priority, - children, - isCellSelected -}) { - const SortIcon = useDefaultComponents().sortIcon; + colSpan, + isCellSelected, + isCopied, + isDraggedOver, + row, + rowIdx, + className, + onClick, + onDoubleClick, + onContextMenu, + onRowChange, + selectCell, + ...props +}, refComponent) { const { - ref, - tabIndex - } = useFocusRef(isCellSelected); - - function handleKeyDown(event) { - if (event.key === ' ' || event.key === 'Enter') { - event.preventDefault(); - onSort(event.ctrlKey || event.metaKey); - } + tabIndex, + childTabIndex, + onFocus + } = useRovingTabIndex(isCellSelected); + const { + cellClass + } = column; + className = getCellClassname(column, typeof cellClass === 'function' ? cellClass(row) : cellClass, className, isCopied && cellCopiedClassname, isDraggedOver && cellDraggedOverClassname); + const isEditable = isCellEditable(column, row); + function selectCellWrapper(openEditor) { + selectCell({ + rowIdx, + idx: column.idx + }, openEditor); } - function handleClick(event) { - onSort(event.ctrlKey || event.metaKey); + if (onClick) { + const cellEvent = createCellEvent(event); + onClick({ + row, + column, + selectCell: selectCellWrapper + }, cellEvent); + if (cellEvent.isGridDefaultPrevented()) return; + } + selectCellWrapper(); } - - return /*#__PURE__*/jsxRuntime.jsxs("span", { - ref: ref, + function handleContextMenu(event) { + if (onContextMenu) { + const cellEvent = createCellEvent(event); + onContextMenu({ + row, + column, + selectCell: selectCellWrapper + }, cellEvent); + if (cellEvent.isGridDefaultPrevented()) return; + } + selectCellWrapper(); + } + function handleDoubleClick(event) { + if (onDoubleClick) { + const cellEvent = createCellEvent(event); + onDoubleClick({ + row, + column, + selectCell: selectCellWrapper + }, cellEvent); + if (cellEvent.isGridDefaultPrevented()) return; + } + selectCellWrapper(true); + } + function handleRowChange(newRow) { + onRowChange(column, newRow); + } + return /*#__PURE__*/jsxRuntime.jsx("div", { + role: "gridcell", + "aria-colindex": column.idx + 1, + "aria-colspan": colSpan, + "aria-selected": isCellSelected, + "aria-readonly": !isEditable || undefined, + ref: refComponent, tabIndex: tabIndex, - className: headerSortCellClassname, + className: className, + style: getCellStyle(column, colSpan), onClick: handleClick, - onKeyDown: handleKeyDown, - children: [/*#__PURE__*/jsxRuntime.jsx("span", { - className: headerSortNameClassname, - children: children - }), /*#__PURE__*/jsxRuntime.jsxs("span", { - children: [/*#__PURE__*/jsxRuntime.jsx(SortIcon, { - sortDirection: sortDirection - }), priority] - })] + onDoubleClick: handleDoubleClick, + onContextMenu: handleContextMenu, + onFocus: onFocus, + ...props, + children: column.renderCell({ + column, + row, + isCellEditable: isEditable, + tabIndex: childTabIndex, + onRowChange: handleRowChange + }) }); } +const CellComponent = /*#__PURE__*/react.memo( /*#__PURE__*/react.forwardRef(Cell)); +const CellComponent$1 = CellComponent; +function defaultRenderCell(key, props) { + return /*#__PURE__*/jsxRuntime.jsx(CellComponent, { + ...props + }, key); +} -var css_248z$9 = ".c6l2wv1700-beta13{touch-action:none}.c6l2wv1700-beta13:after{content:\"\";cursor:col-resize;inline-size:10px;inset-block-end:0;inset-block-start:0;inset-inline-end:0;position:absolute}"; -styleInject(css_248z$9,{"insertAt":"top"}); - -const cellResizable = "c6l2wv1700-beta13"; -const cellResizableClassname = `rdg-cell-resizable ${cellResizable}`; -function HeaderCell({ - column, - colSpan, - isCellSelected, - onColumnResize, - allRowsSelected, - onAllRowsSelectionChange, - sortColumns, - onSortColumnsChange, - selectCell, - shouldFocusGrid, - direction +const cellDragHandle = "cadd3bp7-0-0-beta-37"; +const cellDragHandleFrozenClassname = "ccmuez27-0-0-beta-37"; +const cellDragHandleClassname = `rdg-cell-drag-handle ${cellDragHandle}`; +function DragHandle({ + gridRowStart, + rows, + columns, + selectedPosition, + latestDraggedOverRowIdx, + isCellEditable, + onRowsChange, + onFill, + setDragging, + setDraggedOverRowIdx }) { - const isRtl = direction === 'rtl'; const { - ref, - tabIndex, - onFocus - } = useRovingCellRef(isCellSelected); - const sortIndex = sortColumns?.findIndex(sort => sort.columnKey === column.key); - const sortColumn = sortIndex !== undefined && sortIndex > -1 ? sortColumns[sortIndex] : undefined; - const sortDirection = sortColumn?.direction; - const priority = sortColumn !== undefined && sortColumns.length > 1 ? sortIndex + 1 : undefined; - const ariaSort = sortDirection && !priority ? sortDirection === 'ASC' ? 'ascending' : 'descending' : undefined; - const className = getCellClassname(column, column.headerCellClass, column.resizable && cellResizableClassname); - const HeaderRenderer$1 = column.headerRenderer ?? HeaderRenderer; - - function onPointerDown(event) { - if (event.pointerType === 'mouse' && event.buttons !== 1) { - return; + idx, + rowIdx + } = selectedPosition; + const column = columns[idx]; + function handleMouseDown(event) { + if (event.buttons !== 1) return; + setDragging(true); + window.addEventListener('mouseover', onMouseOver); + window.addEventListener('mouseup', onMouseUp); + function onMouseOver(event) { + if (event.buttons !== 1) onMouseUp(); } - - const { - currentTarget, + function onMouseUp() { + window.removeEventListener('mouseover', onMouseOver); + window.removeEventListener('mouseup', onMouseUp); + setDragging(false); + handleDragEnd(); + } + } + function handleDragEnd() { + const overRowIdx = latestDraggedOverRowIdx.current; + if (overRowIdx === undefined) return; + const startRowIndex = rowIdx < overRowIdx ? rowIdx + 1 : overRowIdx; + const endRowIndex = rowIdx < overRowIdx ? overRowIdx + 1 : rowIdx; + updateRows(startRowIndex, endRowIndex); + setDraggedOverRowIdx(undefined); + } + function handleDoubleClick(event) { + event.stopPropagation(); + updateRows(rowIdx + 1, rows.length); + } + function updateRows(startRowIdx, endRowIdx) { + const column = columns[idx]; + const sourceRow = rows[rowIdx]; + const updatedRows = [...rows]; + const indexes = []; + for (let i = startRowIdx; i < endRowIdx; i++) { + if (isCellEditable({ + rowIdx: i, + idx + })) { + const updatedRow = onFill({ + columnKey: column.key, + sourceRow, + targetRow: rows[i] + }); + if (updatedRow !== rows[i]) { + updatedRows[i] = updatedRow; + indexes.push(i); + } + } + } + if (indexes.length > 0) { + onRowsChange?.(updatedRows, { + indexes, + column + }); + } + } + const colSpan = column.colSpan?.({ + type: 'ROW', + row: rows[rowIdx] + }) ?? 1; + const style = getCellStyle(column, colSpan); + return /*#__PURE__*/jsxRuntime.jsx("div", { + style: { + ...style, + gridRowStart, + insetInlineStart: style.insetInlineStart && typeof column.width === 'number' ? `calc(${style.insetInlineStart} + ${column.width}px - var(--rdg-drag-handle-size))` : undefined + }, + className: clsx(cellDragHandleClassname, column.frozen && cellDragHandleFrozenClassname), + onMouseDown: handleMouseDown, + onDoubleClick: handleDoubleClick + }); +} + +const cellEditing = "c1tngyp17-0-0-beta-37"; +function EditCell({ + column, + colSpan, + row, + rowIdx, + onRowChange, + closeEditor, + onKeyDown, + navigate +}) { + const frameRequestRef = react.useRef(); + const commitOnOutsideClick = column.editorOptions?.commitOnOutsideClick !== false; + const commitOnOutsideMouseDown = useLatestFunc(() => { + onClose(true, false); + }); + react.useEffect(() => { + if (!commitOnOutsideClick) return; + function onWindowCaptureMouseDown() { + frameRequestRef.current = requestAnimationFrame(commitOnOutsideMouseDown); + } + addEventListener('mousedown', onWindowCaptureMouseDown, { + capture: true + }); + return () => { + removeEventListener('mousedown', onWindowCaptureMouseDown, { + capture: true + }); + cancelFrameRequest(); + }; + }, [commitOnOutsideClick, commitOnOutsideMouseDown]); + function cancelFrameRequest() { + cancelAnimationFrame(frameRequestRef.current); + } + function handleKeyDown(event) { + if (onKeyDown) { + const cellEvent = createCellEvent(event); + onKeyDown({ + mode: 'EDIT', + row, + column, + rowIdx, + navigate() { + navigate(event); + }, + onClose + }, cellEvent); + if (cellEvent.isGridDefaultPrevented()) return; + } + if (event.key === 'Escape') { + onClose(); + } else if (event.key === 'Enter') { + onClose(true); + } else if (onEditorNavigation(event)) { + navigate(event); + } + } + function onClose(commitChanges = false, shouldFocusCell = true) { + if (commitChanges) { + onRowChange(row, true, shouldFocusCell); + } else { + closeEditor(shouldFocusCell); + } + } + function onEditorRowChange(row, commitChangesAndFocus = false) { + onRowChange(row, commitChangesAndFocus, commitChangesAndFocus); + } + const { + cellClass + } = column; + const className = getCellClassname(column, 'rdg-editor-container', typeof cellClass === 'function' ? cellClass(row) : cellClass, !column.editorOptions?.displayCellContent && cellEditing); + return /*#__PURE__*/jsxRuntime.jsx("div", { + role: "gridcell", + "aria-colindex": column.idx + 1, + "aria-colspan": colSpan, + "aria-selected": true, + className: className, + style: getCellStyle(column, colSpan), + onKeyDown: handleKeyDown, + onMouseDownCapture: cancelFrameRequest, + children: column.renderEditCell != null && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, { + children: [column.renderEditCell({ + column, + row, + onRowChange: onEditorRowChange, + onClose + }), column.editorOptions?.displayCellContent && column.renderCell({ + column, + row, + isCellEditable: true, + tabIndex: -1, + onRowChange: onEditorRowChange + })] + }) + }); +} + +function GroupedColumnHeaderCell({ + column, + rowIdx, + isCellSelected, + selectCell +}) { + const { + tabIndex, + onFocus + } = useRovingTabIndex(isCellSelected); + const { + colSpan + } = column; + const rowSpan = getHeaderCellRowSpan(column, rowIdx); + const index = column.idx + 1; + function onClick() { + selectCell({ + idx: column.idx, + rowIdx + }); + } + return /*#__PURE__*/jsxRuntime.jsx("div", { + role: "columnheader", + "aria-colindex": index, + "aria-colspan": colSpan, + "aria-rowspan": rowSpan, + "aria-selected": isCellSelected, + tabIndex: tabIndex, + className: clsx(cellClassname, column.headerCellClass), + style: { + ...getHeaderCellStyle(column, rowIdx, rowSpan), + gridColumnStart: index, + gridColumnEnd: index + colSpan + }, + onFocus: onFocus, + onClick: onClick, + children: column.name + }); +} + +const headerSortCellClassname = "hizp7y17-0-0-beta-37"; +const headerSortName = "h14cojrm7-0-0-beta-37"; +const headerSortNameClassname = `rdg-header-sort-name ${headerSortName}`; +function renderHeaderCell({ + column, + sortDirection, + priority +}) { + if (!column.sortable) return column.name; + return /*#__PURE__*/jsxRuntime.jsx(SortableHeaderCell, { + sortDirection: sortDirection, + priority: priority, + children: column.name + }); +} +function SortableHeaderCell({ + sortDirection, + priority, + children +}) { + const renderSortStatus = useDefaultRenderers().renderSortStatus; + return /*#__PURE__*/jsxRuntime.jsxs("span", { + className: headerSortCellClassname, + children: [/*#__PURE__*/jsxRuntime.jsx("span", { + className: headerSortNameClassname, + children: children + }), /*#__PURE__*/jsxRuntime.jsx("span", { + children: renderSortStatus({ + sortDirection, + priority + }) + })] + }); +} + +const cellSortableClassname = "celq7o97-0-0-beta-37"; +const cellResizable = "ceqw94e7-0-0-beta-37"; +const cellResizableClassname = `rdg-cell-resizable ${cellResizable}`; +const resizeHandleClassname = "r12jy2ca7-0-0-beta-37"; +function HeaderCell({ + column, + colSpan, + rowIdx, + isCellSelected, + onColumnResize, + sortColumns, + onSortColumnsChange, + selectCell, + shouldFocusGrid, + direction +}) { + const isRtl = direction === 'rtl'; + const rowSpan = getHeaderCellRowSpan(column, rowIdx); + const { + tabIndex, + childTabIndex, + onFocus + } = useRovingTabIndex(isCellSelected); + const sortIndex = sortColumns?.findIndex(sort => sort.columnKey === column.key); + const sortColumn = sortIndex !== undefined && sortIndex > -1 ? sortColumns[sortIndex] : undefined; + const sortDirection = sortColumn?.direction; + const priority = sortColumn !== undefined && sortColumns.length > 1 ? sortIndex + 1 : undefined; + const ariaSort = sortDirection && !priority ? sortDirection === 'ASC' ? 'ascending' : 'descending' : undefined; + const className = getCellClassname(column, column.headerCellClass, column.sortable && cellSortableClassname, column.resizable && cellResizableClassname); + const renderHeaderCell$1 = column.renderHeaderCell ?? renderHeaderCell; + function onPointerDown(event) { + if (event.pointerType === 'mouse' && event.buttons !== 1) { + return; + } + const { + currentTarget, pointerId } = event; + const headerCell = currentTarget.parentElement; const { right, left - } = currentTarget.getBoundingClientRect(); + } = headerCell.getBoundingClientRect(); const offset = isRtl ? event.clientX - left : right - event.clientX; - - if (offset > 11) { - return; - } - function onPointerMove(event) { + event.preventDefault(); const { right, left - } = currentTarget.getBoundingClientRect(); + } = headerCell.getBoundingClientRect(); const width = isRtl ? right + offset - event.clientX : event.clientX + offset - left; - if (width > 0) { onColumnResize(column, clampColumnWidth(width, column)); } } - function onLostPointerCapture() { currentTarget.removeEventListener('pointermove', onPointerMove); currentTarget.removeEventListener('lostpointercapture', onLostPointerCapture); } - currentTarget.setPointerCapture(pointerId); currentTarget.addEventListener('pointermove', onPointerMove); currentTarget.addEventListener('lostpointercapture', onLostPointerCapture); } - function onSort(ctrlClick) { if (onSortColumnsChange == null) return; const { sortDescendingFirst } = column; - if (sortColumn === undefined) { const nextSort = { columnKey: column.key, @@ -1255,95 +1478,93 @@ function HeaderCell({ onSortColumnsChange(sortColumns && ctrlClick ? [...sortColumns, nextSort] : [nextSort]); } else { let nextSortColumn; - - if (sortDescendingFirst && sortDirection === 'DESC' || !sortDescendingFirst && sortDirection === 'ASC') { + if (sortDescendingFirst === true && sortDirection === 'DESC' || sortDescendingFirst !== true && sortDirection === 'ASC') { nextSortColumn = { columnKey: column.key, direction: sortDirection === 'ASC' ? 'DESC' : 'ASC' }; } - if (ctrlClick) { const nextSortColumns = [...sortColumns]; - if (nextSortColumn) { nextSortColumns[sortIndex] = nextSortColumn; } else { nextSortColumns.splice(sortIndex, 1); } - onSortColumnsChange(nextSortColumns); } else { onSortColumnsChange(nextSortColumn ? [nextSortColumn] : []); } } } - - function onClick() { - selectCell(column.idx); - } - - function onDoubleClick(event) { - const { - right, - left - } = event.currentTarget.getBoundingClientRect(); - const offset = isRtl ? event.clientX - left : right - event.clientX; - - if (offset > 11) { - return; + function onClick(event) { + selectCell({ + idx: column.idx, + rowIdx + }); + if (column.sortable) { + onSort(event.ctrlKey || event.metaKey); } - - onColumnResize(column, 'auto'); } - + function onDoubleClick() { + onColumnResize(column, 'max-content'); + } function handleFocus(event) { onFocus?.(event); - if (shouldFocusGrid) { - selectCell(0); + selectCell({ + idx: 0, + rowIdx + }); } } - - return /*#__PURE__*/jsxRuntime.jsx("div", { + function onKeyDown(event) { + if (event.key === ' ' || event.key === 'Enter') { + event.preventDefault(); + onSort(event.ctrlKey || event.metaKey); + } + } + return /*#__PURE__*/jsxRuntime.jsxs("div", { role: "columnheader", "aria-colindex": column.idx + 1, + "aria-colspan": colSpan, + "aria-rowspan": rowSpan, "aria-selected": isCellSelected, "aria-sort": ariaSort, - "aria-colspan": colSpan, - ref: ref, tabIndex: shouldFocusGrid ? 0 : tabIndex, className: className, - style: { ...getCellStyle(column, colSpan), - minWidth: column.minWidth, - maxWidth: column.maxWidth ?? undefined + style: { + ...getHeaderCellStyle(column, rowIdx, rowSpan), + ...getCellStyle(column, colSpan) }, onFocus: handleFocus, onClick: onClick, - onDoubleClick: column.resizable ? onDoubleClick : undefined, - onPointerDown: column.resizable ? onPointerDown : undefined, - children: /*#__PURE__*/jsxRuntime.jsx(HeaderRenderer$1, { - column: column, - sortDirection: sortDirection, - priority: priority, - onSort: onSort, - allRowsSelected: allRowsSelected, - onAllRowsSelectionChange: onAllRowsSelectionChange, - isCellSelected: isCellSelected - }) + onKeyDown: column.sortable ? onKeyDown : undefined, + children: [renderHeaderCell$1({ + column, + sortDirection, + priority, + tabIndex: childTabIndex + }), column.resizable && /*#__PURE__*/jsxRuntime.jsx("div", { + className: resizeHandleClassname, + onClick: stopPropagation, + onDoubleClick: onDoubleClick, + onPointerDown: onPointerDown + })] }); } -var css_248z$8 = ".h10tskcx700-beta13{background-color:var(--rdg-header-background-color);display:contents;font-weight:700;line-height:var(--rdg-header-row-height)}.h10tskcx700-beta13>.cj343x0700-beta13{inset-block-start:0;position:sticky;z-index:2}.h10tskcx700-beta13>.ch2wcw8700-beta13{z-index:3}"; -styleInject(css_248z$8,{"insertAt":"top"}); +const row = "r1otpg647-0-0-beta-37"; +const rowClassname = `rdg-row ${row}`; +const rowSelected = "rel5gk27-0-0-beta-37"; +const rowSelectedClassname = 'rdg-row-selected'; +const rowSelectedWithFrozenCell = "r1qymf1z7-0-0-beta-37"; -const headerRow = "h10tskcx700-beta13"; +const headerRow = "h197vzie7-0-0-beta-37"; const headerRowClassname = `rdg-header-row ${headerRow}`; - function HeaderRow({ + rowIdx, columns, - allRowsSelected, - onAllRowsSelectionChange, onColumnResize, sortColumns, onSortColumnsChange, @@ -1354,24 +1575,20 @@ function HeaderRow({ direction }) { const cells = []; - for (let index = 0; index < columns.length; index++) { const column = columns[index]; const colSpan = getColSpan(column, lastFrozenColumnIndex, { type: 'HEADER' }); - if (colSpan !== undefined) { index += colSpan - 1; } - cells.push( /*#__PURE__*/jsxRuntime.jsx(HeaderCell, { column: column, colSpan: colSpan, + rowIdx: rowIdx, isCellSelected: selectedCellIdx === column.idx, onColumnResize: onColumnResize, - allRowsSelected: allRowsSelected, - onAllRowsSelectionChange: onAllRowsSelectionChange, onSortColumnsChange: onSortColumnsChange, sortColumns: sortColumns, selectCell: selectCell, @@ -1379,127 +1596,54 @@ function HeaderRow({ direction: direction }, column.key)); } - return /*#__PURE__*/jsxRuntime.jsx("div", { role: "row", - "aria-rowindex": 1, + "aria-rowindex": rowIdx, className: clsx(headerRowClassname, selectedCellIdx === -1 && rowSelectedClassname), - style: getRowStyle(1), children: cells }); } - const HeaderRow$1 = /*#__PURE__*/react.memo(HeaderRow); -var css_248z$7 = ".c6ra8a3700-beta13,.cq910m0700-beta13{background-color:#ccf}.cq910m0700-beta13.c6ra8a3700-beta13{background-color:#99f}"; -styleInject(css_248z$7,{"insertAt":"top"}); - -const cellCopied = "c6ra8a3700-beta13"; -const cellCopiedClassname = `rdg-cell-copied ${cellCopied}`; -const cellDraggedOver = "cq910m0700-beta13"; -const cellDraggedOverClassname = `rdg-cell-dragged-over ${cellDraggedOver}`; - -function Cell({ - column, - colSpan, - className, - isScrolling, - isCellSelected, - isCopied, - isDraggedOver, - row, - dragHandle, - onRowClick, - onRowDoubleClick, - onRowChange, - selectCell, - onClick, - onDoubleClick, - onContextMenu, - onMouseDown, - onFocus: focusEventHandler, - ...props -}, refComponent) { - const { - ref, - tabIndex, - onFocus - } = useRovingCellRef(isCellSelected); - - function setRef(element) { - ref(element); - - if (typeof refComponent === 'function') { - refComponent(element); - } else if (typeof refComponent === 'object' && refComponent !== null) { - refComponent.current = element; +function GroupedColumnHeaderRow({ + rowIdx, + level, + columns, + selectedCellIdx, + selectCell +}) { + const cells = []; + const renderedParents = new Set(); + for (const column of columns) { + let { + parent + } = column; + if (parent === undefined) continue; + while (parent.level > level) { + if (parent.parent === undefined) break; + parent = parent.parent; + } + if (parent.level === level && !renderedParents.has(parent)) { + renderedParents.add(parent); + const { + idx + } = parent; + cells.push( /*#__PURE__*/jsxRuntime.jsx(GroupedColumnHeaderCell, { + column: parent, + rowIdx: rowIdx, + isCellSelected: selectedCellIdx === idx, + selectCell: selectCell + }, idx)); } } - - const { - cellClass - } = column; - className = getCellClassname(column, typeof cellClass === 'function' ? cellClass(row) : cellClass, className, isCopied && cellCopiedClassname, isDraggedOver && cellDraggedOverClassname); - - function selectCellWrapper(openEditor) { - selectCell(row, column, openEditor); - } - - function handleMouseDown(event) { - selectCellWrapper(column.editorOptions?.editOnClick); - onRowClick?.(row, column); - onMouseDown?.(event); - } - - function handleClick(event) { - onClick?.(event); - } - - function handleContextMenu(event) { - selectCellWrapper(); - onContextMenu?.(event); - } - - function handleDoubleClick(event) { - selectCellWrapper(true); - onRowDoubleClick?.(row, column); - onDoubleClick?.(event); - } - - function handleFocus(event) { - onFocus?.(event); - focusEventHandler?.(event); - } - return /*#__PURE__*/jsxRuntime.jsx("div", { - role: "gridcell", - "aria-colindex": column.idx + 1, - "aria-selected": isCellSelected, - "aria-colspan": colSpan, - "aria-readonly": !isCellEditable(column, row) || undefined, - ref: setRef, - tabIndex: tabIndex, - className: className, - style: getCellStyle(column, colSpan), - onMouseDown: handleMouseDown, - onClick: handleClick, - onDoubleClick: handleDoubleClick, - onContextMenu: handleContextMenu, - onFocus: handleFocus, - ...props, - children: !column.rowGroup && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, { - children: [/*#__PURE__*/jsxRuntime.jsx(column.formatter, { - column: column, - row: row, - isScrolling: isScrolling, - isCellSelected: isCellSelected, - onRowChange: onRowChange - }), dragHandle] - }) + role: "row", + "aria-rowindex": rowIdx, + className: headerRowClassname, + children: cells }); } - -const Cell$1 = /*#__PURE__*/react.memo( /*#__PURE__*/react.forwardRef(Cell)); +const GroupedColumnHeaderRow$1 = /*#__PURE__*/react.memo(GroupedColumnHeaderRow); function Row({ className, @@ -1507,7 +1651,6 @@ function Row({ gridRowStart, height, selectedCellIdx, - isScrolling, isRowSelected, copiedCellIdx, draggedOverCellIdx, @@ -1515,9 +1658,9 @@ function Row({ row, viewportColumns, selectedCellEditor, - selectedCellDragHandle, - onRowClick, - onRowDoubleClick, + onCellClick, + onCellDoubleClick, + onCellContextMenu, rowClass, setDraggedOverRowIdx, onMouseEnter, @@ -1525,20 +1668,17 @@ function Row({ selectCell, ...props }, ref) { - const defaultComponents = useDefaultComponents(); - const CellRenderer = defaultComponents?.cellRenderer ?? Cell$1; - const handleRowChange = useLatestFunc(newRow => { - onRowChange(rowIdx, newRow); + const defaultComponents = useDefaultRenderers(); + const cellRenderer = defaultComponents?.renderCell ?? defaultRenderCell; + const handleRowChange = useLatestFunc((column, newRow) => { + onRowChange(column, rowIdx, newRow); }); - function handleDragEnter(event) { setDraggedOverRowIdx?.(rowIdx); onMouseEnter?.(event); } - - className = clsx(rowClassname, `rdg-row-${rowIdx % 2 === 0 ? 'even' : 'odd'}`, rowClass?.(row), className, selectedCellIdx === -1 && rowSelectedClassname); + className = clsx(rowClassname, `rdg-row-${rowIdx % 2 === 0 ? 'even' : 'odd'}`, rowClass?.(row, rowIdx), className, selectedCellIdx === -1 && rowSelectedClassname); const cells = []; - for (let index = 0; index < viewportColumns.length; index++) { const column = viewportColumns[index]; const { @@ -1548,33 +1688,29 @@ function Row({ type: 'ROW', row }); - if (colSpan !== undefined) { index += colSpan - 1; } - const isCellSelected = selectedCellIdx === idx; - if (isCellSelected && selectedCellEditor) { cells.push(selectedCellEditor); } else { - cells.push( /*#__PURE__*/jsxRuntime.jsx(CellRenderer, { - isScrolling: isScrolling, - column: column, - colSpan: colSpan, - row: row, + cells.push(cellRenderer(column.key, { + column, + colSpan, + row, + rowIdx, isCopied: copiedCellIdx === idx, isDraggedOver: draggedOverCellIdx === idx, - isCellSelected: isCellSelected, - dragHandle: isCellSelected ? selectedCellDragHandle : undefined, - onRowClick: onRowClick, - onRowDoubleClick: onRowDoubleClick, + isCellSelected, + onClick: onCellClick, + onDoubleClick: onCellDoubleClick, + onContextMenu: onCellContextMenu, onRowChange: handleRowChange, - selectCell: selectCell - }, column.key)); + selectCell + })); } } - return /*#__PURE__*/jsxRuntime.jsx(RowSelectionProvider, { value: isRowSelected, children: /*#__PURE__*/jsxRuntime.jsx("div", { @@ -1588,172 +1724,139 @@ function Row({ }) }); } +const RowComponent = /*#__PURE__*/react.memo( /*#__PURE__*/react.forwardRef(Row)); +const RowComponent$1 = RowComponent; +function defaultRenderRow(key, props) { + return /*#__PURE__*/jsxRuntime.jsx(RowComponent, { + ...props + }, key); +} -const Row$1 = /*#__PURE__*/react.memo( /*#__PURE__*/react.forwardRef(Row)); - -function GroupCell({ - id, - groupKey, - childRows, - isScrolling, - isExpanded, - isCellSelected, - column, - row, - groupColumnIndex, - toggleGroup: toggleGroupWrapper +function ScrollToCell({ + scrollToPosition: { + idx, + rowIdx + }, + gridElement, + setScrollToCellPosition }) { - const { - ref, - tabIndex, - onFocus - } = useRovingCellRef(isCellSelected); - - function toggleGroup() { - toggleGroupWrapper(id); - } - - const isLevelMatching = column.rowGroup && groupColumnIndex === column.idx; + const ref = react.useRef(null); + useLayoutEffect(() => { + scrollIntoView(ref.current); + }); + useLayoutEffect(() => { + function removeScrollToCell() { + setScrollToCellPosition(null); + } + const observer = new IntersectionObserver(removeScrollToCell, { + root: gridElement, + threshold: 1.0 + }); + observer.observe(ref.current); + return () => { + observer.disconnect(); + }; + }, [gridElement, setScrollToCellPosition]); return /*#__PURE__*/jsxRuntime.jsx("div", { - role: "gridcell", - "aria-colindex": column.idx + 1, - "aria-selected": isCellSelected, ref: ref, - tabIndex: tabIndex, - className: getCellClassname(column), - style: { ...getCellStyle(column), - cursor: isLevelMatching ? 'pointer' : 'default' - }, - onClick: isLevelMatching ? toggleGroup : undefined, - onFocus: onFocus, - children: (!column.rowGroup || groupColumnIndex === column.idx) && column.groupFormatter && /*#__PURE__*/jsxRuntime.jsx(column.groupFormatter, { - groupKey: groupKey, - childRows: childRows, - column: column, - row: row, - isScrolling: isScrolling, - isExpanded: isExpanded, - isCellSelected: isCellSelected, - toggleGroup: toggleGroup - }) - }, column.key); + style: { + gridColumn: idx === undefined ? '1/-1' : idx + 1, + gridRow: rowIdx === undefined ? '1/-1' : rowIdx + 2 + } + }); } -const GroupCell$1 = /*#__PURE__*/react.memo(GroupCell); - -var css_248z$6 = ".g1yxluv3700-beta13:not([aria-selected=true]){background-color:var(--rdg-header-background-color)}.g1yxluv3700-beta13>.cj343x0700-beta13:not(:last-child):not(.c1wvphzh700-beta13){border-inline-end:none}"; -styleInject(css_248z$6,{"insertAt":"top"}); - -const groupRow = "g1yxluv3700-beta13"; -const groupRowClassname = `rdg-group-row ${groupRow}`; - -function GroupedRow({ - id, - groupKey, - viewportColumns, - childRows, - rowIdx, - row, - gridRowStart, - height, - level, - isScrolling, - isExpanded, - selectedCellIdx, - isRowSelected, - selectGroup, - toggleGroup, - ...props +const arrow = "a1mygwml7-0-0-beta-37"; +const arrowClassname = `rdg-sort-arrow ${arrow}`; +function renderSortStatus({ + sortDirection, + priority }) { - const idx = viewportColumns[0].key === SELECT_COLUMN_KEY ? level + 1 : level; - - function handleSelectGroup() { - selectGroup(rowIdx); - } - - return /*#__PURE__*/jsxRuntime.jsx(RowSelectionProvider, { - value: isRowSelected, - children: /*#__PURE__*/jsxRuntime.jsx("div", { - role: "row", - "aria-level": level, - "aria-expanded": isExpanded, - className: clsx(rowClassname, groupRowClassname, `rdg-row-${rowIdx % 2 === 0 ? 'even' : 'odd'}`, selectedCellIdx === -1 && rowSelectedClassname), - onClick: handleSelectGroup, - style: getRowStyle(gridRowStart, height), - ...props, - children: viewportColumns.map(column => /*#__PURE__*/jsxRuntime.jsx(GroupCell$1, { - id: id, - groupKey: groupKey, - childRows: childRows, - isScrolling: isScrolling, - isExpanded: isExpanded, - isCellSelected: selectedCellIdx === column.idx, - column: column, - row: row, - groupColumnIndex: idx, - toggleGroup: toggleGroup - }, column.key)) + return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, { + children: [renderSortIcon({ + sortDirection + }), renderSortPriority({ + priority + })] + }); +} +function renderSortIcon({ + sortDirection +}) { + if (sortDirection === undefined) return null; + return /*#__PURE__*/jsxRuntime.jsx("svg", { + viewBox: "0 0 12 8", + width: "12", + height: "8", + className: arrowClassname, + "aria-hidden": true, + children: /*#__PURE__*/jsxRuntime.jsx("path", { + d: sortDirection === 'ASC' ? 'M0 8 6 0 12 8' : 'M0 0 6 8 12 0' }) }); } +function renderSortPriority({ + priority +}) { + return priority; +} -const GroupRowRenderer = /*#__PURE__*/react.memo(GroupedRow); - -var css_248z$5 = ".s8wc6fl700-beta13{inset-block-end:var(--rdg-summary-row-bottom);inset-block-start:var(--rdg-summary-row-top)}"; -styleInject(css_248z$5,{"insertAt":"top"}); - -const summaryCellClassname = "s8wc6fl700-beta13"; +const root = "r104f42s7-0-0-beta-37"; +const rootClassname = `rdg ${root}`; +const viewportDragging = "v7ly7s7-0-0-beta-37"; +const viewportDraggingClassname = `rdg-viewport-dragging ${viewportDragging}`; +const focusSinkClassname = "fc4f4zb7-0-0-beta-37"; +const focusSinkHeaderAndSummaryClassname = "fq51q037-0-0-beta-37"; +const summaryCellClassname = "s1n3hxke7-0-0-beta-37"; function SummaryCell({ column, colSpan, row, + rowIdx, isCellSelected, selectCell }) { const { - ref, tabIndex, + childTabIndex, onFocus - } = useRovingCellRef(isCellSelected); + } = useRovingTabIndex(isCellSelected); const { - summaryFormatter: SummaryFormatter, summaryCellClass } = column; const className = getCellClassname(column, summaryCellClassname, typeof summaryCellClass === 'function' ? summaryCellClass(row) : summaryCellClass); - function onClick() { - selectCell(row, column); + selectCell({ + rowIdx, + idx: column.idx + }); } - return /*#__PURE__*/jsxRuntime.jsx("div", { role: "gridcell", "aria-colindex": column.idx + 1, "aria-colspan": colSpan, "aria-selected": isCellSelected, - ref: ref, tabIndex: tabIndex, className: className, style: getCellStyle(column, colSpan), onClick: onClick, onFocus: onFocus, - children: SummaryFormatter && /*#__PURE__*/jsxRuntime.jsx(SummaryFormatter, { - column: column, - row: row, - isCellSelected: isCellSelected + children: column.renderSummaryCell?.({ + column, + row, + tabIndex: childTabIndex }) }); } - const SummaryCell$1 = /*#__PURE__*/react.memo(SummaryCell); -var css_248z$4 = ".skuhp55700-beta13.r1upfr80700-beta13{line-height:var(--rdg-summary-row-height)}.skuhp55700-beta13.r1upfr80700-beta13>.cj343x0700-beta13{position:sticky}.sf8l5ub700-beta13>.cj343x0700-beta13{border-block-start:2px solid var(--rdg-summary-border-color)}"; -styleInject(css_248z$4,{"insertAt":"top"}); - -const summaryRow = "skuhp55700-beta13"; -const summaryRowBorderClassname = "sf8l5ub700-beta13"; +const summaryRow = "snfqesz7-0-0-beta-37"; +const topSummaryRow = "t1jijrjz7-0-0-beta-37"; +const topSummaryRowBorderClassname = "t14bmecc7-0-0-beta-37"; +const bottomSummaryRowBorderClassname = "b1odhhml7-0-0-beta-37"; const summaryRowClassname = `rdg-summary-row ${summaryRow}`; - +const topSummaryRowClassname = `rdg-top-summary-row ${topSummaryRow}`; function SummaryRow({ rowIdx, gridRowStart, @@ -1763,381 +1866,174 @@ function SummaryRow({ bottom, lastFrozenColumnIndex, selectedCellIdx, + isTop, + showBorder, selectCell, 'aria-rowindex': ariaRowIndex }) { const cells = []; - for (let index = 0; index < viewportColumns.length; index++) { const column = viewportColumns[index]; const colSpan = getColSpan(column, lastFrozenColumnIndex, { type: 'SUMMARY', row }); - if (colSpan !== undefined) { index += colSpan - 1; } - const isCellSelected = selectedCellIdx === column.idx; cells.push( /*#__PURE__*/jsxRuntime.jsx(SummaryCell$1, { column: column, colSpan: colSpan, row: row, + rowIdx: rowIdx, isCellSelected: isCellSelected, selectCell: selectCell }, column.key)); } - return /*#__PURE__*/jsxRuntime.jsx("div", { role: "row", "aria-rowindex": ariaRowIndex, - className: clsx(rowClassname, `rdg-row-${rowIdx % 2 === 0 ? 'even' : 'odd'}`, summaryRowClassname, rowIdx === 0 && summaryRowBorderClassname, selectedCellIdx === -1 && rowSelectedClassname), - style: { ...getRowStyle(gridRowStart), + className: clsx(rowClassname, `rdg-row-${rowIdx % 2 === 0 ? 'even' : 'odd'}`, summaryRowClassname, isTop ? [topSummaryRowClassname, showBorder && topSummaryRowBorderClassname] : ['rdg-bottom-summary-row', showBorder && bottomSummaryRowBorderClassname], selectedCellIdx === -1 && rowSelectedClassname), + style: { + ...getRowStyle(gridRowStart), '--rdg-summary-row-top': top !== undefined ? `${top}px` : undefined, '--rdg-summary-row-bottom': bottom !== undefined ? `${bottom}px` : undefined }, children: cells }); } - const SummaryRow$1 = /*#__PURE__*/react.memo(SummaryRow); -var css_248z$3 = ".cis5rrm700-beta13.rdg-cell{padding:0}"; -styleInject(css_248z$3,{"insertAt":"top"}); - -const cellEditing = "cis5rrm700-beta13"; -function EditCell({ - column, - colSpan, - row, - isScrolling, - onRowChange, - closeEditor -}) { - const frameRequestRef = react.useRef(); - const commitOnOutsideClick = column.editorOptions?.commitOnOutsideClick !== false; - const commitOnOutsideMouseDown = useLatestFunc(() => { - onClose(true); +function DataGrid(props, ref) { + const { + columns: rawColumns, + rows, + topSummaryRows, + bottomSummaryRows, + rowKeyGetter, + onRowsChange, + rowHeight: rawRowHeight, + headerRowHeight: rawHeaderRowHeight, + summaryRowHeight: rawSummaryRowHeight, + selectedRows, + onSelectedCellChange, + onSelectedRowsChange, + sortColumns, + onSortColumnsChange, + defaultColumnOptions, + onCellClick, + onCellDoubleClick, + onCellContextMenu, + onCellKeyDown, + onScroll, + onColumnResize, + onFill, + onCopy, + onPaste, + enableVirtualization: rawEnableVirtualization, + renderers, + className, + style, + rowClass, + direction: rawDirection, + role: rawRole, + 'aria-label': ariaLabel, + 'aria-labelledby': ariaLabelledBy, + 'aria-describedby': ariaDescribedBy, + 'aria-rowcount': rawAriaRowCount, + 'data-testid': testId + } = props; + const defaultRenderers = useDefaultRenderers(); + const role = rawRole ?? 'grid'; + const rowHeight = rawRowHeight ?? 35; + const headerRowHeight = rawHeaderRowHeight ?? (typeof rowHeight === 'number' ? rowHeight : 35); + const summaryRowHeight = rawSummaryRowHeight ?? (typeof rowHeight === 'number' ? rowHeight : 35); + const renderRow = renderers?.renderRow ?? defaultRenderers?.renderRow ?? defaultRenderRow; + const renderCell = renderers?.renderCell ?? defaultRenderers?.renderCell ?? defaultRenderCell; + const renderSortStatus$1 = renderers?.renderSortStatus ?? defaultRenderers?.renderSortStatus ?? renderSortStatus; + const renderCheckbox$1 = renderers?.renderCheckbox ?? defaultRenderers?.renderCheckbox ?? renderCheckbox; + const noRowsFallback = renderers?.noRowsFallback ?? defaultRenderers?.noRowsFallback; + const enableVirtualization = rawEnableVirtualization ?? true; + const direction = rawDirection ?? 'ltr'; + const [scrollTop, setScrollTop] = react.useState(0); + const [scrollLeft, setScrollLeft] = react.useState(0); + const [resizedColumnWidths, setResizedColumnWidths] = react.useState(() => new Map()); + const [measuredColumnWidths, setMeasuredColumnWidths] = react.useState(() => new Map()); + const [copiedCell, setCopiedCell] = react.useState(null); + const [isDragging, setDragging] = react.useState(false); + const [draggedOverRowIdx, setOverRowIdx] = react.useState(undefined); + const [scrollToPosition, setScrollToPosition] = react.useState(null); + const [gridRef, gridWidth, gridHeight] = useGridDimensions(); + const { + columns, + colSpanColumns, + lastFrozenColumnIndex, + headerRowsCount, + colOverscanStartIdx, + colOverscanEndIdx, + templateColumns, + layoutCssVars, + totalFrozenColumnWidth + } = useCalculatedColumns({ + rawColumns, + defaultColumnOptions, + measuredColumnWidths, + resizedColumnWidths, + scrollLeft, + viewportWidth: gridWidth, + enableVirtualization }); - react.useEffect(() => { - if (!commitOnOutsideClick) return; - - function onWindowCaptureMouseDown() { - frameRequestRef.current = requestAnimationFrame(commitOnOutsideMouseDown); - } - - addEventListener('mousedown', onWindowCaptureMouseDown, { - capture: true - }); - return () => { - removeEventListener('mousedown', onWindowCaptureMouseDown, { - capture: true - }); - cancelFrameRequest(); - }; - }, [commitOnOutsideClick, commitOnOutsideMouseDown]); - - function cancelFrameRequest() { - cancelAnimationFrame(frameRequestRef.current); - } - - function onKeyDown(event) { - if (event.key === 'Escape') { - event.stopPropagation(); - onClose(); - } else if (event.key === 'Enter') { - event.stopPropagation(); - onClose(true); - } else { - const onNavigation = column.editorOptions?.onNavigation ?? onEditorNavigation; - - if (!onNavigation(event)) { - event.stopPropagation(); - } - } - } - - function onClose(commitChanges) { - if (commitChanges) { - onRowChange(row, true); - } else { - closeEditor(); - } - } - - const { - cellClass - } = column; - const className = getCellClassname(column, 'rdg-editor-container', typeof cellClass === 'function' ? cellClass(row) : cellClass, !column.editorOptions?.renderFormatter && cellEditing); - return /*#__PURE__*/jsxRuntime.jsx("div", { - role: "gridcell", - "aria-colindex": column.idx + 1, - "aria-colspan": colSpan, - "aria-selected": true, - className: className, - style: getCellStyle(column, colSpan), - onKeyDown: onKeyDown, - onMouseDownCapture: commitOnOutsideClick ? cancelFrameRequest : undefined, - children: column.editor != null && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, { - children: [/*#__PURE__*/jsxRuntime.jsx(column.editor, { - column: column, - row: row, - onRowChange: onRowChange, - onClose: onClose - }), column.editorOptions?.renderFormatter && /*#__PURE__*/jsxRuntime.jsx(column.formatter, { - column: column, - row: row, - isScrolling: isScrolling, - isCellSelected: true, - onRowChange: onRowChange - })] - }) - }); -} - -var css_248z$2 = ".c1w9bbhr700-beta13{background-color:var(--rdg-selection-color);block-size:8px;cursor:move;inline-size:8px;inset-block-end:0;inset-inline-end:0;position:absolute}.c1w9bbhr700-beta13:hover{background-color:var(--rdg-background-color);block-size:16px;border:2px solid var(--rdg-selection-color);inline-size:16px}"; -styleInject(css_248z$2,{"insertAt":"top"}); - -const cellDragHandle = "c1w9bbhr700-beta13"; -const cellDragHandleClassname = `rdg-cell-drag-handle ${cellDragHandle}`; -function DragHandle({ - rows, - columns, - selectedPosition, - latestDraggedOverRowIdx, - isCellEditable, - onRowsChange, - onFill, - setDragging, - setDraggedOverRowIdx -}) { - function handleMouseDown(event) { - if (event.buttons !== 1) return; - setDragging(true); - window.addEventListener('mouseover', onMouseOver); - window.addEventListener('mouseup', onMouseUp); - - function onMouseOver(event) { - if (event.buttons !== 1) onMouseUp(); - } - - function onMouseUp() { - window.removeEventListener('mouseover', onMouseOver); - window.removeEventListener('mouseup', onMouseUp); - setDragging(false); - handleDragEnd(); - } - } - - function handleDragEnd() { - const overRowIdx = latestDraggedOverRowIdx.current; - if (overRowIdx === undefined) return; - const { - rowIdx - } = selectedPosition; - const startRowIndex = rowIdx < overRowIdx ? rowIdx + 1 : overRowIdx; - const endRowIndex = rowIdx < overRowIdx ? overRowIdx + 1 : rowIdx; - updateRows(startRowIndex, endRowIndex); - setDraggedOverRowIdx(undefined); - } - - function handleDoubleClick(event) { - event.stopPropagation(); - updateRows(selectedPosition.rowIdx + 1, rows.length); - } - - function updateRows(startRowIdx, endRowIdx) { - const { - idx, - rowIdx - } = selectedPosition; - const column = columns[idx]; - const sourceRow = rows[rowIdx]; - const updatedRows = [...rows]; - const indexes = []; - - for (let i = startRowIdx; i < endRowIdx; i++) { - if (isCellEditable({ - rowIdx: i, - idx - })) { - const updatedRow = onFill({ - columnKey: column.key, - sourceRow, - targetRow: rows[i] - }); - - if (updatedRow !== rows[i]) { - updatedRows[i] = updatedRow; - indexes.push(i); - } - } - } - - if (indexes.length > 0) { - onRowsChange?.(updatedRows, { - indexes, - column - }); - } - } - - return /*#__PURE__*/jsxRuntime.jsx("div", { - className: cellDragHandleClassname, - onMouseDown: handleMouseDown, - onDoubleClick: handleDoubleClick - }); -} - -var css_248z$1 = ".a3cv93f700-beta13{fill:currentColor}.a3cv93f700-beta13>path{transition:d .1s}"; -styleInject(css_248z$1,{"insertAt":"top"}); - -const arrow = "a3cv93f700-beta13"; -const arrowClassname = `rdg-sort-arrow ${arrow}`; -function SortIcon({ - sortDirection -}) { - return sortDirection !== undefined ? /*#__PURE__*/jsxRuntime.jsx("svg", { - viewBox: "0 0 12 8", - width: "12", - height: "8", - className: arrowClassname, - "aria-hidden": true, - children: /*#__PURE__*/jsxRuntime.jsx("path", { - d: sortDirection === 'ASC' ? 'M0 8 6 0 12 8' : 'M0 0 6 8 12 0' - }) - }) : null; -} - -const initialPosition = { - idx: -1, - rowIdx: -2, - mode: 'SELECT' -}; - -function DataGrid({ - columns: rawColumns, - rows: rawRows, - summaryRows, - rowKeyGetter, - onRowsChange, - rowHeight, - headerRowHeight: rawHeaderRowHeight, - summaryRowHeight: rawSummaryRowHeight, - selectedRows, - onSelectedCellChange, - onSelectedRowsChange, - sortColumns, - onSortColumnsChange, - defaultColumnOptions, - groupBy: rawGroupBy, - rowGrouper, - expandedGroupIds, - onExpandedGroupIdsChange, - onRowClick, - onRowDoubleClick, - onScroll, - onColumnResize, - onFill, - onCopy, - onPaste, - cellNavigationMode: rawCellNavigationMode, - enableVirtualization, - components, - className, - style, - rowClass, - direction, - 'aria-label': ariaLabel, - 'aria-labelledby': ariaLabelledBy, - 'aria-describedby': ariaDescribedBy, - 'data-testid': testId -}, ref) { - const defaultComponents = useDefaultComponents(); - rowHeight ?? (rowHeight = 35); - const headerRowHeight = rawHeaderRowHeight ?? (typeof rowHeight === 'number' ? rowHeight : 35); - const summaryRowHeight = rawSummaryRowHeight ?? (typeof rowHeight === 'number' ? rowHeight : 35); - const CellRenderer = components?.cellRenderer ?? defaultComponents?.cellRenderer ?? Cell$1; - const RowRenderer = components?.rowRenderer ?? defaultComponents?.rowRenderer ?? Row$1; - const sortIcon = components?.sortIcon ?? defaultComponents?.sortIcon ?? SortIcon; - const checkboxFormatter = components?.checkboxFormatter ?? defaultComponents?.checkboxFormatter ?? CheckboxFormatter; - const noRowsFallback = components?.noRowsFallback ?? defaultComponents?.noRowsFallback; - const cellNavigationMode = rawCellNavigationMode ?? 'NONE'; - enableVirtualization ?? (enableVirtualization = true); - direction ?? (direction = 'ltr'); - const scrollingResetRef = react.useRef(-1); - const [isScrolling, setScrolling] = react.useState(false); - const [scrollTop, setScrollTop] = react.useState(0); - const [scrollLeft, setScrollLeft] = react.useState(0); - const [columnWidths, setColumnWidths] = react.useState(() => new Map()); - const [selectedPosition, setSelectedPosition] = react.useState(initialPosition); - const [copiedCell, setCopiedCell] = react.useState(null); - const [isDragging, setDragging] = react.useState(false); - const [draggedOverRowIdx, setOverRowIdx] = react.useState(undefined); - const [autoResizeColumn, setAutoResizeColumn] = react.useState(null); + const topSummaryRowsCount = topSummaryRows?.length ?? 0; + const bottomSummaryRowsCount = bottomSummaryRows?.length ?? 0; + const summaryRowsCount = topSummaryRowsCount + bottomSummaryRowsCount; + const headerAndTopSummaryRowsCount = headerRowsCount + topSummaryRowsCount; + const groupedColumnHeaderRowsCount = headerRowsCount - 1; + const minRowIdx = -headerAndTopSummaryRowsCount; + const mainHeaderRowIdx = minRowIdx + groupedColumnHeaderRowsCount; + const maxRowIdx = rows.length + bottomSummaryRowsCount - 1; + const [selectedPosition, setSelectedPosition] = react.useState(() => ({ + idx: -1, + rowIdx: minRowIdx - 1, + mode: 'SELECT' + })); const prevSelectedPosition = react.useRef(selectedPosition); const latestDraggedOverRowIdx = react.useRef(draggedOverRowIdx); const lastSelectedRowIdx = react.useRef(-1); - const rowRef = react.useRef(null); - const [gridRef, gridWidth, gridHeight] = useGridDimensions(); - const headerRowsCount = 1; - const summaryRowsCount = summaryRows?.length ?? 0; - const clientHeight = gridHeight - headerRowHeight - summaryRowsCount * summaryRowHeight; + const focusSinkRef = react.useRef(null); + const shouldFocusCellRef = react.useRef(false); + const isTreeGrid = role === 'treegrid'; + const headerRowsHeight = headerRowsCount * headerRowHeight; + const clientHeight = gridHeight - headerRowsHeight - summaryRowsCount * summaryRowHeight; const isSelectable = selectedRows != null && onSelectedRowsChange != null; - const isHeaderRowSelected = selectedPosition.rowIdx === -1; const isRtl = direction === 'rtl'; const leftKey = isRtl ? 'ArrowRight' : 'ArrowLeft'; const rightKey = isRtl ? 'ArrowLeft' : 'ArrowRight'; + const ariaRowCount = rawAriaRowCount ?? headerRowsCount + rows.length + summaryRowsCount; const defaultGridComponents = react.useMemo(() => ({ - sortIcon, - checkboxFormatter, - cellRenderer: CellRenderer - }), [sortIcon, checkboxFormatter, CellRenderer]); + renderCheckbox: renderCheckbox$1, + renderSortStatus: renderSortStatus$1, + renderCell + }), [renderCheckbox$1, renderSortStatus$1, renderCell]); const allRowsSelected = react.useMemo(() => { const { length - } = rawRows; - return length !== 0 && selectedRows != null && rowKeyGetter != null && selectedRows.size >= length && rawRows.every(row => selectedRows.has(rowKeyGetter(row))); - }, [rawRows, selectedRows, rowKeyGetter]); - const { - columns, - colSpanColumns, - colOverscanStartIdx, - colOverscanEndIdx, - layoutCssVars, - columnMetrics, - lastFrozenColumnIndex, - totalFrozenColumnWidth, - groupBy - } = useCalculatedColumns({ - rawColumns, - columnWidths, - scrollLeft, - viewportWidth: gridWidth, - defaultColumnOptions, - rawGroupBy: rowGrouper ? rawGroupBy : undefined, - enableVirtualization - }); + } = rows; + return length !== 0 && selectedRows != null && rowKeyGetter != null && selectedRows.size >= length && rows.every(row => selectedRows.has(rowKeyGetter(row))); + }, [rows, selectedRows, rowKeyGetter]); const { rowOverscanStartIdx, rowOverscanEndIdx, - rows, - rowsCount, totalRowHeight, gridTemplateRows, - isGroupRow, getRowTop, getRowHeight, findRowIdx } = useViewportRows({ - rawRows, - groupBy, - rowGrouper, + rows, rowHeight, clientHeight, scrollTop, - expandedGroupIds, enableVirtualization }); const viewportColumns = useViewportColumns({ @@ -2149,149 +2045,112 @@ function DataGrid({ rowOverscanStartIdx, rowOverscanEndIdx, rows, - summaryRows, - isGroupRow + topSummaryRows, + bottomSummaryRows }); - const hasGroups = groupBy.length > 0 && typeof rowGrouper === 'function'; - const minColIdx = hasGroups ? -1 : 0; + const { + gridTemplateColumns, + handleColumnResize + } = useColumnWidths(columns, viewportColumns, templateColumns, gridRef, gridWidth, resizedColumnWidths, measuredColumnWidths, setResizedColumnWidths, setMeasuredColumnWidths, onColumnResize); + const minColIdx = isTreeGrid ? -1 : 0; const maxColIdx = columns.length - 1; - const minRowIdx = -1; - const maxRowIdx = headerRowsCount + rows.length + summaryRowsCount - 2; const selectedCellIsWithinSelectionBounds = isCellWithinSelectionBounds(selectedPosition); const selectedCellIsWithinViewportBounds = isCellWithinViewportBounds(selectedPosition); + const handleColumnResizeLatest = useLatestFunc(handleColumnResize); + const onSortColumnsChangeLatest = useLatestFunc(onSortColumnsChange); + const onCellClickLatest = useLatestFunc(onCellClick); + const onCellDoubleClickLatest = useLatestFunc(onCellDoubleClick); + const onCellContextMenuLatest = useLatestFunc(onCellContextMenu); const selectRowLatest = useLatestFunc(selectRow); - const selectAllRowsLatest = useLatestFunc(selectAllRows); const handleFormatterRowChangeLatest = useLatestFunc(updateRow); - const selectViewportCellLatest = useLatestFunc((row, column, enableEditor) => { - const rowIdx = rows.indexOf(row); - selectCell({ - rowIdx, - idx: column.idx - }, enableEditor); - }); - const selectGroupLatest = useLatestFunc(rowIdx => { - selectCell({ - rowIdx, - idx: -1 - }); - }); - const selectHeaderCellLatest = useLatestFunc(idx => { + const selectCellLatest = useLatestFunc(selectCell); + const selectHeaderCellLatest = useLatestFunc(({ + idx, + rowIdx + }) => { selectCell({ - rowIdx: -1, + rowIdx: minRowIdx + rowIdx - 1, idx }); }); - const selectSummaryCellLatest = useLatestFunc((summaryRow, column) => { - const rowIdx = summaryRows.indexOf(summaryRow) + headerRowsCount + rows.length - 1; - selectCell({ - rowIdx, - idx: column.idx - }); - }); - const toggleGroupLatest = useLatestFunc(toggleGroup); useLayoutEffect(() => { if (!selectedCellIsWithinSelectionBounds || isSamePosition(selectedPosition, prevSelectedPosition.current)) { prevSelectedPosition.current = selectedPosition; return; } - prevSelectedPosition.current = selectedPosition; - if (selectedPosition.idx === -1) { - rowRef.current.focus({ + focusSinkRef.current.focus({ preventScroll: true }); - scrollIntoView(rowRef.current); + scrollIntoView(focusSinkRef.current); } }); useLayoutEffect(() => { - if (autoResizeColumn === null) return; - const columnElement = gridRef.current.querySelector(`[aria-colindex="${autoResizeColumn.idx + 1}"]`); - const { - width - } = columnElement.getBoundingClientRect(); - setColumnWidths(columnWidths => { - const newColumnWidths = new Map(columnWidths); - newColumnWidths.set(autoResizeColumn.key, width); - return newColumnWidths; + if (!shouldFocusCellRef.current) return; + shouldFocusCellRef.current = false; + const cell = getCellToScroll(gridRef.current); + if (cell === null) return; + scrollIntoView(cell); + const elementToFocus = cell.querySelector('[tabindex="0"]') ?? cell; + elementToFocus.focus({ + preventScroll: true }); - setAutoResizeColumn(null); - onColumnResize?.(autoResizeColumn.idx, width); - }, [autoResizeColumn, gridRef, onColumnResize]); + }); react.useImperativeHandle(ref, () => ({ element: gridRef.current, selectedCell: selectedPosition, - scrollToColumn, - - scrollToRow(rowIdx) { - const { - current - } = gridRef; - if (!current) return; - current.scrollTo({ - top: getRowTop(rowIdx), - behavior: 'smooth' - }); + scrollToCell({ + idx, + rowIdx + }) { + const scrollToIdx = idx !== undefined && idx > lastFrozenColumnIndex && idx < columns.length ? idx : undefined; + const scrollToRowIdx = rowIdx !== undefined && isRowIdxWithinViewportBounds(rowIdx) ? rowIdx : undefined; + if (scrollToIdx !== undefined || scrollToRowIdx !== undefined) { + setScrollToPosition({ + idx: scrollToIdx, + rowIdx: scrollToRowIdx + }); + } }, - selectCell })); - const handleColumnResize = react.useCallback((column, width) => { - if (width === 'auto') { - setAutoResizeColumn(column); - return; - } - - setColumnWidths(columnWidths => { - const newColumnWidths = new Map(columnWidths); - newColumnWidths.set(column.key, width); - return newColumnWidths; - }); - onColumnResize?.(column.idx, width); - }, [onColumnResize]); const setDraggedOverRowIdx = react.useCallback(rowIdx => { setOverRowIdx(rowIdx); latestDraggedOverRowIdx.current = rowIdx; }, []); - - function selectRow({ - row, - checked, - isShiftClick - }) { + function selectRow(args) { if (!onSelectedRowsChange) return; assertIsValidKeyGetter(rowKeyGetter); - const newSelectedRows = new Set(selectedRows); - - if (isGroupRow(row)) { - for (const childRow of row.childRows) { - const rowKey = rowKeyGetter(childRow); - - if (checked) { + if (args.type === 'HEADER') { + const newSelectedRows = new Set(selectedRows); + for (const row of rows) { + const rowKey = rowKeyGetter(row); + if (args.checked) { newSelectedRows.add(rowKey); } else { newSelectedRows.delete(rowKey); } } - onSelectedRowsChange(newSelectedRows); return; } - + const { + row, + checked, + isShiftClick + } = args; + const newSelectedRows = new Set(selectedRows); const rowKey = rowKeyGetter(row); - if (checked) { newSelectedRows.add(rowKey); const previousRowIdx = lastSelectedRowIdx.current; const rowIdx = rows.indexOf(row); lastSelectedRowIdx.current = rowIdx; - if (isShiftClick && previousRowIdx !== -1 && previousRowIdx !== rowIdx) { const step = sign(rowIdx - previousRowIdx); - for (let i = previousRowIdx + step; i !== rowIdx; i += step) { const row = rows[i]; - if (isGroupRow(row)) continue; newSelectedRows.add(rowKeyGetter(row)); } } @@ -2299,84 +2158,50 @@ function DataGrid({ newSelectedRows.delete(rowKey); lastSelectedRowIdx.current = -1; } - onSelectedRowsChange(newSelectedRows); } - - function selectAllRows(checked) { - if (!onSelectedRowsChange) return; - assertIsValidKeyGetter(rowKeyGetter); - const newSelectedRows = new Set(selectedRows); - - for (const row of rawRows) { - const rowKey = rowKeyGetter(row); - - if (checked) { - newSelectedRows.add(rowKey); - } else { - newSelectedRows.delete(rowKey); - } - } - - onSelectedRowsChange(newSelectedRows); - } - - function toggleGroup(expandedGroupId) { - if (!onExpandedGroupIdsChange) return; - const newExpandedGroupIds = new Set(expandedGroupIds); - - if (newExpandedGroupIds.has(expandedGroupId)) { - newExpandedGroupIds.delete(expandedGroupId); - } else { - newExpandedGroupIds.add(expandedGroupId); - } - - onExpandedGroupIdsChange(newExpandedGroupIds); - } - function handleKeyDown(event) { + const { + idx, + rowIdx, + mode + } = selectedPosition; + if (mode === 'EDIT') return; + if (onCellKeyDown && isRowIdxWithinViewportBounds(rowIdx)) { + const row = rows[rowIdx]; + const cellEvent = createCellEvent(event); + onCellKeyDown({ + mode: 'SELECT', + row, + column: columns[idx], + rowIdx, + selectCell + }, cellEvent); + if (cellEvent.isGridDefaultPrevented()) return; + } if (!(event.target instanceof Element)) return; const isCellEvent = event.target.closest('.rdg-cell') !== null; - const isRowEvent = hasGroups && event.target === rowRef.current; + const isRowEvent = isTreeGrid && event.target === focusSinkRef.current; if (!isCellEvent && !isRowEvent) return; const { - key, keyCode } = event; - const { - rowIdx - } = selectedPosition; - - if (selectedCellIsWithinViewportBounds && (onPaste != null || onCopy != null) && isCtrlKeyHeldDown(event) && !isGroupRow(rows[rowIdx]) && selectedPosition.mode === 'SELECT') { + if (selectedCellIsWithinViewportBounds && (onPaste != null || onCopy != null) && isCtrlKeyHeldDown(event)) { const cKey = 67; const vKey = 86; - if (keyCode === cKey) { handleCopy(); return; } - if (keyCode === vKey) { handlePaste(); return; } } - - if (isRowIdxWithinViewportBounds(rowIdx)) { - const row = rows[rowIdx]; - - if (isGroupRow(row) && selectedPosition.idx === -1 && (key === leftKey && row.isExpanded || key === rightKey && !row.isExpanded)) { - event.preventDefault(); - toggleGroup(row.id); - return; - } - } - switch (event.key) { case 'Escape': setCopiedCell(null); return; - case 'ArrowUp': case 'ArrowDown': case 'ArrowLeft': @@ -2388,53 +2213,42 @@ function DataGrid({ case 'PageDown': navigate(event); break; - default: handleCellInput(event); break; } } - function handleScroll(event) { const { scrollTop, scrollLeft } = event.currentTarget; - setScrollTop(scrollTop); - setScrollLeft(abs(scrollLeft)); - setScrolling(true); + reactDom.flushSync(() => { + setScrollTop(scrollTop); + setScrollLeft(abs(scrollLeft)); + }); onScroll?.(event); - clearTimeout(scrollingResetRef.current); - scrollingResetRef.current = setTimeout(() => setScrolling(false), 16); - } - - function getRawRowIdx(rowIdx) { - return hasGroups ? rawRows.indexOf(rows[rowIdx]) : rowIdx; } - - function updateRow(rowIdx, row) { + function updateRow(column, rowIdx, row) { if (typeof onRowsChange !== 'function') return; - const rawRowIdx = getRawRowIdx(rowIdx); - if (row === rawRows[rawRowIdx]) return; - const updatedRows = [...rawRows]; - updatedRows[rawRowIdx] = row; + if (row === rows[rowIdx]) return; + const updatedRows = [...rows]; + updatedRows[rowIdx] = row; onRowsChange(updatedRows, { - indexes: [rawRowIdx], - column: columns[selectedPosition.idx] + indexes: [rowIdx], + column }); } - function commitEditorChanges() { if (selectedPosition.mode !== 'EDIT') return; - updateRow(selectedPosition.rowIdx, selectedPosition.row); + updateRow(columns[selectedPosition.idx], selectedPosition.rowIdx, selectedPosition.row); } - function handleCopy() { const { idx, rowIdx } = selectedPosition; - const sourceRow = rawRows[getRawRowIdx(rowIdx)]; + const sourceRow = rows[rowIdx]; const sourceColumnKey = columns[idx].key; setCopiedCell({ row: sourceRow, @@ -2445,39 +2259,36 @@ function DataGrid({ sourceColumnKey }); } - function handlePaste() { if (!onPaste || !onRowsChange || copiedCell === null || !isCellEditable(selectedPosition)) { return; } - const { idx, rowIdx } = selectedPosition; - const targetRow = rawRows[getRawRowIdx(rowIdx)]; + const targetColumn = columns[idx]; + const targetRow = rows[rowIdx]; const updatedTargetRow = onPaste({ sourceRow: copiedCell.row, sourceColumnKey: copiedCell.columnKey, targetRow, - targetColumnKey: columns[idx].key + targetColumnKey: targetColumn.key }); - updateRow(rowIdx, updatedTargetRow); + updateRow(targetColumn, rowIdx, updatedTargetRow); } - function handleCellInput(event) { if (!selectedCellIsWithinViewportBounds) return; const row = rows[selectedPosition.rowIdx]; - if (isGroupRow(row)) return; const { key, shiftKey } = event; - if (isSelectable && shiftKey && key === ' ') { assertIsValidKeyGetter(rowKeyGetter); const rowKey = rowKeyGetter(row); selectRow({ + type: 'ROW', row, checked: !selectedRows.has(rowKey), isShiftClick: false @@ -2485,11 +2296,6 @@ function DataGrid({ event.preventDefault(); return; } - - const column = columns[selectedPosition.idx]; - column.editorOptions?.onCellKeyDown?.(event); - if (event.isDefaultPrevented()) return; - if (isCellEditable(selectedPosition) && isDefaultCellInput(event)) { setSelectedPosition(({ idx, @@ -2503,196 +2309,103 @@ function DataGrid({ })); } } - function isColIdxWithinSelectionBounds(idx) { return idx >= minColIdx && idx <= maxColIdx; } - function isRowIdxWithinViewportBounds(rowIdx) { return rowIdx >= 0 && rowIdx < rows.length; } - function isCellWithinSelectionBounds({ idx, rowIdx }) { return rowIdx >= minRowIdx && rowIdx <= maxRowIdx && isColIdxWithinSelectionBounds(idx); } - function isCellWithinViewportBounds({ idx, rowIdx }) { return isRowIdxWithinViewportBounds(rowIdx) && isColIdxWithinSelectionBounds(idx); } - function isCellEditable(position) { return isCellWithinViewportBounds(position) && isSelectedCellEditable({ columns, rows, - selectedPosition: position, - isGroupRow + selectedPosition: position }); } - - function isCellSelectable(position) { - return isCellWithinViewportBounds(position) && isSelectedCellSelectable(columns, position); - } - function selectCell(position, enableEditor) { if (!isCellWithinSelectionBounds(position)) return; commitEditorChanges(); - if (enableEditor && isCellEditable(position)) { const row = rows[position.rowIdx]; - setSelectedPosition({ ...position, + setSelectedPosition({ + ...position, mode: 'EDIT', row, originalRow: row }); } else if (isSamePosition(selectedPosition, position)) { - scrollIntoView(gridRef.current?.querySelector('[tabindex="0"]')); - } - - if (isCellSelectable(position)) { - setSelectedPosition({ ...position, + scrollIntoView(getCellToScroll(gridRef.current)); + } else { + shouldFocusCellRef.current = true; + setSelectedPosition({ + ...position, mode: 'SELECT' }); - onSelectedCellChange?.(position); } + onSelectedCellChange?.(position); } - - function scrollToColumn(idx) { - const { - current - } = gridRef; - if (!current) return; - - if (idx > lastFrozenColumnIndex) { - const { - rowIdx - } = selectedPosition; - if (!isCellWithinSelectionBounds({ - rowIdx, - idx - })) return; - const { - clientWidth - } = current; - const column = columns[idx]; - const { - left, - width - } = columnMetrics.get(column); - let right = left + width; - const colSpan = getSelectedCellColSpan({ - rows, - summaryRows, - rowIdx, - lastFrozenColumnIndex, - column, - isGroupRow - }); - - if (colSpan !== undefined) { - const { - left, - width - } = columnMetrics.get(columns[column.idx + colSpan - 1]); - right = left + width; - } - - const isCellAtLeftBoundary = left < scrollLeft + totalFrozenColumnWidth; - const isCellAtRightBoundary = right > clientWidth + scrollLeft; - const sign = isRtl ? -1 : 1; - - if (isCellAtLeftBoundary) { - current.scrollLeft = (left - totalFrozenColumnWidth) * sign; - } else if (isCellAtRightBoundary) { - current.scrollLeft = (right - clientWidth) * sign; - } - } - } - function getNextPosition(key, ctrlKey, shiftKey) { const { idx, rowIdx } = selectedPosition; - const row = rows[rowIdx]; const isRowSelected = selectedCellIsWithinSelectionBounds && idx === -1; - - if (key === leftKey && isRowSelected && isGroupRow(row) && !row.isExpanded && row.level !== 0) { - let parentRowIdx = -1; - - for (let i = selectedPosition.rowIdx - 1; i >= 0; i--) { - const parentRow = rows[i]; - - if (isGroupRow(parentRow) && parentRow.id === row.parentId) { - parentRowIdx = i; - break; - } - } - - if (parentRowIdx !== -1) { - return { - idx, - rowIdx: parentRowIdx - }; - } - } - switch (key) { case 'ArrowUp': return { idx, rowIdx: rowIdx - 1 }; - case 'ArrowDown': return { idx, rowIdx: rowIdx + 1 }; - case leftKey: return { idx: idx - 1, rowIdx }; - case rightKey: return { idx: idx + 1, rowIdx }; - case 'Tab': return { idx: idx + (shiftKey ? -1 : 1), rowIdx }; - case 'Home': if (isRowSelected) return { idx, - rowIdx: 0 + rowIdx: minRowIdx }; return { idx: 0, rowIdx: ctrlKey ? minRowIdx : rowIdx }; - case 'End': if (isRowSelected) return { idx, - rowIdx: rows.length - 1 + rowIdx: maxRowIdx }; return { idx: maxColIdx, rowIdx: ctrlKey ? maxRowIdx : rowIdx }; - case 'PageUp': { if (selectedPosition.rowIdx === minRowIdx) return selectedPosition; @@ -2702,7 +2415,6 @@ function DataGrid({ rowIdx: nextRowY > 0 ? findRowIdx(nextRowY) : 0 }; } - case 'PageDown': { if (selectedPosition.rowIdx >= rows.length) return selectedPosition; @@ -2712,23 +2424,19 @@ function DataGrid({ rowIdx: nextRowY < totalRowHeight ? findRowIdx(nextRowY) : rows.length - 1 }; } - default: return selectedPosition; } } - function navigate(event) { const { key, shiftKey } = event; - let mode = cellNavigationMode; - + let cellNavigationMode = 'NONE'; if (key === 'Tab') { if (canExitGrid({ shiftKey, - cellNavigationMode, maxColIdx, minRowIdx, maxRowIdx, @@ -2737,31 +2445,31 @@ function DataGrid({ commitEditorChanges(); return; } - - mode = cellNavigationMode === 'NONE' ? 'CHANGE_ROW' : cellNavigationMode; + cellNavigationMode = 'CHANGE_ROW'; } - event.preventDefault(); const ctrlKey = isCtrlKeyHeldDown(event); const nextPosition = getNextPosition(key, ctrlKey, shiftKey); if (isSamePosition(selectedPosition, nextPosition)) return; const nextSelectedCellPosition = getNextSelectedCellPosition({ + moveUp: key === 'ArrowUp', + moveNext: key === rightKey || key === 'Tab' && !shiftKey, columns, colSpanColumns, rows, - summaryRows, + topSummaryRows, + bottomSummaryRows, minRowIdx, + mainHeaderRowIdx, maxRowIdx, lastFrozenColumnIndex, - cellNavigationMode: mode, + cellNavigationMode, currentPosition: selectedPosition, nextPosition, - isCellWithinBounds: isCellWithinSelectionBounds, - isGroupRow + isCellWithinBounds: isCellWithinSelectionBounds }); selectCell(nextSelectedCellPosition); } - function getDraggedOverCellIdx(currentRowIdx) { if (draggedOverRowIdx === undefined) return; const { @@ -2770,26 +2478,13 @@ function DataGrid({ const isDraggedOver = rowIdx < draggedOverRowIdx ? rowIdx < currentRowIdx && currentRowIdx <= draggedOverRowIdx : rowIdx > currentRowIdx && currentRowIdx >= draggedOverRowIdx; return isDraggedOver ? selectedPosition.idx : undefined; } - - function getLayoutCssVars() { - if (autoResizeColumn === null) return layoutCssVars; - const { - gridTemplateColumns - } = layoutCssVars; - const newSizes = gridTemplateColumns.split(' '); - newSizes[autoResizeColumn.idx] = 'max-content'; - return { ...layoutCssVars, - gridTemplateColumns: newSizes.join(' ') - }; - } - - function getDragHandle(rowIdx) { - if (selectedPosition.rowIdx !== rowIdx || selectedPosition.mode === 'EDIT' || hasGroups || onFill == null) { + function renderDragHandle() { + if (onFill == null || selectedPosition.mode === 'EDIT' || !isCellWithinViewportBounds(selectedPosition)) { return; } - return /*#__PURE__*/jsxRuntime.jsx(DragHandle, { - rows: rawRows, + gridRowStart: headerAndTopSummaryRowsCount + selectedPosition.rowIdx + 1, + rows: rows, columns: columns, selectedPosition: selectedPosition, isCellEditable: isCellEditable, @@ -2800,7 +2495,6 @@ function DataGrid({ setDraggedOverRowIdx: setDraggedOverRowIdx }); } - function getCellEditor(rowIdx) { if (selectedPosition.rowIdx !== rowIdx || selectedPosition.mode === 'SELECT') return; const { @@ -2812,8 +2506,8 @@ function DataGrid({ type: 'ROW', row }); - - const closeEditor = () => { + const closeEditor = shouldFocusCell => { + shouldFocusCellRef.current = shouldFocusCell; setSelectedPosition(({ idx, rowIdx @@ -2823,58 +2517,53 @@ function DataGrid({ mode: 'SELECT' })); }; - - const onRowChange = (row, commitChanges) => { + const onRowChange = (row, commitChanges, shouldFocusCell) => { if (commitChanges) { - updateRow(selectedPosition.rowIdx, row); - closeEditor(); + reactDom.flushSync(() => { + updateRow(column, selectedPosition.rowIdx, row); + closeEditor(shouldFocusCell); + }); } else { - setSelectedPosition(position => ({ ...position, + setSelectedPosition(position => ({ + ...position, row })); } }; - if (rows[selectedPosition.rowIdx] !== selectedPosition.originalRow) { - closeEditor(); + closeEditor(false); } - return /*#__PURE__*/jsxRuntime.jsx(EditCell, { column: column, colSpan: colSpan, row: row, - isScrolling: isScrolling, + rowIdx: rowIdx, onRowChange: onRowChange, - closeEditor: closeEditor + closeEditor: closeEditor, + onKeyDown: onCellKeyDown, + navigate: navigate }, column.key); } - function getRowViewportColumns(rowIdx) { - const selectedColumn = columns[selectedPosition.idx]; - + const selectedColumn = selectedPosition.idx === -1 ? undefined : columns[selectedPosition.idx]; if (selectedColumn !== undefined && selectedPosition.rowIdx === rowIdx && !viewportColumns.includes(selectedColumn)) { return selectedPosition.idx > colOverscanEndIdx ? [...viewportColumns, selectedColumn] : [...viewportColumns.slice(0, lastFrozenColumnIndex + 1), selectedColumn, ...viewportColumns.slice(lastFrozenColumnIndex + 1)]; } - return viewportColumns; } - function getViewportRows() { const rowElements = []; - let startRowIndex = 0; const { idx: selectedIdx, rowIdx: selectedRowIdx } = selectedPosition; const startRowIdx = selectedCellIsWithinViewportBounds && selectedRowIdx < rowOverscanStartIdx ? rowOverscanStartIdx - 1 : rowOverscanStartIdx; const endRowIdx = selectedCellIsWithinViewportBounds && selectedRowIdx > rowOverscanEndIdx ? rowOverscanEndIdx + 1 : rowOverscanEndIdx; - for (let viewportRowIdx = startRowIdx; viewportRowIdx <= endRowIdx; viewportRowIdx++) { const isRowOutsideViewport = viewportRowIdx === rowOverscanStartIdx - 1 || viewportRowIdx === rowOverscanEndIdx + 1; const rowIdx = isRowOutsideViewport ? selectedRowIdx : viewportRowIdx; let rowColumns = viewportColumns; - const selectedColumn = columns[selectedIdx]; - + const selectedColumn = selectedIdx === -1 ? undefined : columns[selectedIdx]; if (selectedColumn !== undefined) { if (isRowOutsideViewport) { rowColumns = [selectedColumn]; @@ -2882,186 +2571,617 @@ function DataGrid({ rowColumns = getRowViewportColumns(rowIdx); } } - const row = rows[rowIdx]; - const gridRowStart = headerRowsCount + rowIdx + 1; - - if (isGroupRow(row)) { - ({ - startRowIndex - } = row); - const isGroupRowSelected = isSelectable && row.childRows.every(cr => selectedRows.has(rowKeyGetter(cr))); - rowElements.push( /*#__PURE__*/jsxRuntime.jsx(GroupRowRenderer, { - "aria-level": row.level + 1, - "aria-setsize": row.setSize, - "aria-posinset": row.posInSet + 1, - "aria-rowindex": headerRowsCount + startRowIndex + 1, - "aria-selected": isSelectable ? isGroupRowSelected : undefined, - id: row.id, - groupKey: row.groupKey, - viewportColumns: rowColumns, - childRows: row.childRows, - rowIdx: rowIdx, - row: row, - gridRowStart: gridRowStart, - height: getRowHeight(rowIdx), - level: row.level, - isScrolling: isScrolling, - isExpanded: row.isExpanded, - selectedCellIdx: selectedRowIdx === rowIdx ? selectedIdx : undefined, - isRowSelected: isGroupRowSelected, - selectGroup: selectGroupLatest, - toggleGroup: toggleGroupLatest - }, row.id)); - continue; - } - - startRowIndex++; - let key; + const gridRowStart = headerAndTopSummaryRowsCount + rowIdx + 1; + let key = rowIdx; let isRowSelected = false; - if (typeof rowKeyGetter === 'function') { key = rowKeyGetter(row); isRowSelected = selectedRows?.has(key) ?? false; - } else { - key = hasGroups ? startRowIndex : rowIdx; } - - rowElements.push( /*#__PURE__*/jsxRuntime.jsx(RowRenderer, { - "aria-rowindex": headerRowsCount + (hasGroups ? startRowIndex : rowIdx) + 1, - "aria-selected": isSelectable ? isRowSelected : undefined, - rowIdx: rowIdx, - row: row, - isScrolling: isScrolling, + rowElements.push(renderRow(key, { + 'aria-rowindex': headerAndTopSummaryRowsCount + rowIdx + 1, + 'aria-selected': isSelectable ? isRowSelected : undefined, + rowIdx, + row, viewportColumns: rowColumns, - isRowSelected: isRowSelected, - onRowClick: onRowClick, - onRowDoubleClick: onRowDoubleClick, - rowClass: rowClass, - gridRowStart: gridRowStart, + isRowSelected, + onCellClick: onCellClickLatest, + onCellDoubleClick: onCellDoubleClickLatest, + onCellContextMenu: onCellContextMenuLatest, + rowClass, + gridRowStart, height: getRowHeight(rowIdx), copiedCellIdx: copiedCell !== null && copiedCell.row === row ? columns.findIndex(c => c.key === copiedCell.columnKey) : undefined, selectedCellIdx: selectedRowIdx === rowIdx ? selectedIdx : undefined, draggedOverCellIdx: getDraggedOverCellIdx(rowIdx), setDraggedOverRowIdx: isDragging ? setDraggedOverRowIdx : undefined, - lastFrozenColumnIndex: lastFrozenColumnIndex, + lastFrozenColumnIndex, onRowChange: handleFormatterRowChangeLatest, - selectCell: selectViewportCellLatest, - selectedCellDragHandle: getDragHandle(rowIdx), + selectCell: selectCellLatest, selectedCellEditor: getCellEditor(rowIdx) - }, key)); + })); } - return rowElements; } - if (selectedPosition.idx > maxColIdx || selectedPosition.rowIdx > maxRowIdx) { - setSelectedPosition(initialPosition); + setSelectedPosition({ + idx: -1, + rowIdx: minRowIdx - 1, + mode: 'SELECT' + }); setDraggedOverRowIdx(undefined); } - - let templateRows = `${headerRowHeight}px`; - + let templateRows = `repeat(${headerRowsCount}, ${headerRowHeight}px)`; + if (topSummaryRowsCount > 0) { + templateRows += ` repeat(${topSummaryRowsCount}, ${summaryRowHeight}px)`; + } if (rows.length > 0) { templateRows += gridTemplateRows; } - - if (summaryRowsCount > 0) { - templateRows += ` repeat(${summaryRowsCount}, ${summaryRowHeight}px)`; + if (bottomSummaryRowsCount > 0) { + templateRows += ` repeat(${bottomSummaryRowsCount}, ${summaryRowHeight}px)`; } - - const isGroupRowFocused = selectedPosition.idx === -1 && selectedPosition.rowIdx !== -2; + const isGroupRowFocused = selectedPosition.idx === -1 && selectedPosition.rowIdx !== minRowIdx - 1; return /*#__PURE__*/jsxRuntime.jsxs("div", { - role: hasGroups ? 'treegrid' : 'grid', + role: role, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-multiselectable": isSelectable ? true : undefined, "aria-colcount": columns.length, - "aria-rowcount": headerRowsCount + rowsCount + summaryRowsCount, - className: clsx(rootClassname, className, isDragging && viewportDraggingClassname, autoResizeColumn !== null && cellAutoResizeClassname), - style: { ...style, - scrollPaddingInlineStart: selectedPosition.idx > lastFrozenColumnIndex ? `${totalFrozenColumnWidth}px` : undefined, - scrollPaddingBlock: selectedPosition.rowIdx >= 0 && selectedPosition.rowIdx < rows.length ? `${headerRowHeight}px ${summaryRowsCount * summaryRowHeight}px` : undefined, + "aria-rowcount": ariaRowCount, + className: clsx(rootClassname, className, isDragging && viewportDraggingClassname), + style: { + ...style, + scrollPaddingInlineStart: selectedPosition.idx > lastFrozenColumnIndex || scrollToPosition?.idx !== undefined ? `${totalFrozenColumnWidth}px` : undefined, + scrollPaddingBlock: isRowIdxWithinViewportBounds(selectedPosition.rowIdx) || scrollToPosition?.rowIdx !== undefined ? `${headerRowsHeight + topSummaryRowsCount * summaryRowHeight}px ${bottomSummaryRowsCount * summaryRowHeight}px` : undefined, + gridTemplateColumns, gridTemplateRows: templateRows, '--rdg-header-row-height': `${headerRowHeight}px`, '--rdg-summary-row-height': `${summaryRowHeight}px`, '--rdg-sign': isRtl ? -1 : 1, - ...getLayoutCssVars() + ...layoutCssVars }, dir: direction, ref: gridRef, onScroll: handleScroll, onKeyDown: handleKeyDown, "data-testid": testId, - children: [hasGroups && /*#__PURE__*/jsxRuntime.jsx("div", { - ref: rowRef, - tabIndex: isGroupRowFocused ? 0 : -1, - className: clsx(focusSinkClassname, isGroupRowFocused && [rowSelected, lastFrozenColumnIndex !== -1 && rowSelectedWithFrozenCell]), - style: { - gridRowStart: selectedPosition.rowIdx + 2 - }, - onKeyDown: handleKeyDown - }), /*#__PURE__*/jsxRuntime.jsxs(DataGridDefaultComponentsProvider, { + children: [/*#__PURE__*/jsxRuntime.jsx(DataGridDefaultRenderersProvider, { value: defaultGridComponents, - children: [/*#__PURE__*/jsxRuntime.jsx(HeaderRow$1, { - columns: getRowViewportColumns(-1), - onColumnResize: handleColumnResize, - allRowsSelected: allRowsSelected, - onAllRowsSelectionChange: selectAllRowsLatest, - sortColumns: sortColumns, - onSortColumnsChange: onSortColumnsChange, - lastFrozenColumnIndex: lastFrozenColumnIndex, - selectedCellIdx: isHeaderRowSelected ? selectedPosition.idx : undefined, - selectCell: selectHeaderCellLatest, - shouldFocusGrid: !selectedCellIsWithinSelectionBounds, - direction: direction - }), rows.length === 0 && noRowsFallback ? noRowsFallback : /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, { - children: [/*#__PURE__*/jsxRuntime.jsx(RowSelectionChangeProvider, { - value: selectRowLatest, - children: getViewportRows() - }), summaryRows?.map((row, rowIdx) => { - const gridRowStart = headerRowsCount + rows.length + rowIdx + 1; - const summaryRowIdx = headerRowsCount + rows.length + rowIdx - 1; - const isSummaryRowSelected = selectedPosition.rowIdx === summaryRowIdx; - const top = clientHeight > totalRowHeight ? gridHeight - summaryRowHeight * (summaryRows.length - rowIdx) : undefined; - const bottom = top === undefined ? summaryRowHeight * (summaryRows.length - 1 - rowIdx) : undefined; - return /*#__PURE__*/jsxRuntime.jsx(SummaryRow$1, { - "aria-rowindex": headerRowsCount + rowsCount + rowIdx + 1, - rowIdx: rowIdx, - gridRowStart: gridRowStart, - row: row, - top: top, - bottom: bottom, - viewportColumns: getRowViewportColumns(summaryRowIdx), + children: /*#__PURE__*/jsxRuntime.jsxs(RowSelectionChangeProvider, { + value: selectRowLatest, + children: [/*#__PURE__*/jsxRuntime.jsxs(RowSelectionProvider, { + value: allRowsSelected, + children: [Array.from({ + length: groupedColumnHeaderRowsCount + }, (_, index) => /*#__PURE__*/jsxRuntime.jsx(GroupedColumnHeaderRow$1, { + rowIdx: index + 1, + level: -groupedColumnHeaderRowsCount + index, + columns: getRowViewportColumns(minRowIdx + index), + selectedCellIdx: selectedPosition.rowIdx === minRowIdx + index ? selectedPosition.idx : undefined, + selectCell: selectHeaderCellLatest + }, index)), /*#__PURE__*/jsxRuntime.jsx(HeaderRow$1, { + rowIdx: headerRowsCount, + columns: getRowViewportColumns(mainHeaderRowIdx), + onColumnResize: handleColumnResizeLatest, + sortColumns: sortColumns, + onSortColumnsChange: onSortColumnsChangeLatest, lastFrozenColumnIndex: lastFrozenColumnIndex, - selectedCellIdx: isSummaryRowSelected ? selectedPosition.idx : undefined, - selectCell: selectSummaryCellLatest - }, rowIdx); + selectedCellIdx: selectedPosition.rowIdx === mainHeaderRowIdx ? selectedPosition.idx : undefined, + selectCell: selectHeaderCellLatest, + shouldFocusGrid: !selectedCellIsWithinSelectionBounds, + direction: direction + })] + }), rows.length === 0 && noRowsFallback ? noRowsFallback : /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, { + children: [topSummaryRows?.map((row, rowIdx) => { + const gridRowStart = headerRowsCount + 1 + rowIdx; + const summaryRowIdx = mainHeaderRowIdx + 1 + rowIdx; + const isSummaryRowSelected = selectedPosition.rowIdx === summaryRowIdx; + const top = headerRowsHeight + summaryRowHeight * rowIdx; + return /*#__PURE__*/jsxRuntime.jsx(SummaryRow$1, { + "aria-rowindex": gridRowStart, + rowIdx: summaryRowIdx, + gridRowStart: gridRowStart, + row: row, + top: top, + bottom: undefined, + viewportColumns: getRowViewportColumns(summaryRowIdx), + lastFrozenColumnIndex: lastFrozenColumnIndex, + selectedCellIdx: isSummaryRowSelected ? selectedPosition.idx : undefined, + isTop: true, + showBorder: rowIdx === topSummaryRowsCount - 1, + selectCell: selectCellLatest + }, rowIdx); + }), getViewportRows(), bottomSummaryRows?.map((row, rowIdx) => { + const gridRowStart = headerAndTopSummaryRowsCount + rows.length + rowIdx + 1; + const summaryRowIdx = rows.length + rowIdx; + const isSummaryRowSelected = selectedPosition.rowIdx === summaryRowIdx; + const top = clientHeight > totalRowHeight ? gridHeight - summaryRowHeight * (bottomSummaryRows.length - rowIdx) : undefined; + const bottom = top === undefined ? summaryRowHeight * (bottomSummaryRows.length - 1 - rowIdx) : undefined; + return /*#__PURE__*/jsxRuntime.jsx(SummaryRow$1, { + "aria-rowindex": ariaRowCount - bottomSummaryRowsCount + rowIdx + 1, + rowIdx: summaryRowIdx, + gridRowStart: gridRowStart, + row: row, + top: top, + bottom: bottom, + viewportColumns: getRowViewportColumns(summaryRowIdx), + lastFrozenColumnIndex: lastFrozenColumnIndex, + selectedCellIdx: isSummaryRowSelected ? selectedPosition.idx : undefined, + isTop: false, + showBorder: rowIdx === 0, + selectCell: selectCellLatest + }, rowIdx); + })] })] - })] + }) + }), renderDragHandle(), renderMeasuringCells(viewportColumns), isTreeGrid && /*#__PURE__*/jsxRuntime.jsx("div", { + ref: focusSinkRef, + tabIndex: isGroupRowFocused ? 0 : -1, + className: clsx(focusSinkClassname, isGroupRowFocused && [rowSelected, lastFrozenColumnIndex !== -1 && rowSelectedWithFrozenCell], !isRowIdxWithinViewportBounds(selectedPosition.rowIdx) && focusSinkHeaderAndSummaryClassname), + style: { + gridRowStart: selectedPosition.rowIdx + headerAndTopSummaryRowsCount + 1 + } + }), scrollToPosition !== null && /*#__PURE__*/jsxRuntime.jsx(ScrollToCell, { + scrollToPosition: scrollToPosition, + setScrollToCellPosition: setScrollToPosition, + gridElement: gridRef.current })] }); } - +function getCellToScroll(gridEl) { + return gridEl.querySelector(':scope > [role="row"] > [tabindex="0"]'); +} function isSamePosition(p1, p2) { return p1.idx === p2.idx && p1.rowIdx === p2.rowIdx; } - const DataGrid$1 = /*#__PURE__*/react.forwardRef(DataGrid); -var css_248z = ".t1u15qzo700-beta13{appearance:none;background-color:var(--rdg-background-color);block-size:100%;border:2px solid #ccc;box-sizing:border-box;color:var(--rdg-color);font-family:inherit;font-size:var(--rdg-font-size);inline-size:100%;padding-block:0;padding-inline:6px;vertical-align:top}.t1u15qzo700-beta13:focus{border-color:var(--rdg-selection-color);outline:none}.t1u15qzo700-beta13::placeholder{color:#999;opacity:1}"; -styleInject(css_248z,{"insertAt":"top"}); +function GroupCell({ + id, + groupKey, + childRows, + isExpanded, + isCellSelected, + column, + row, + groupColumnIndex, + isGroupByColumn, + toggleGroup: toggleGroupWrapper +}) { + const { + tabIndex, + childTabIndex, + onFocus + } = useRovingTabIndex(isCellSelected); + function toggleGroup() { + toggleGroupWrapper(id); + } + const isLevelMatching = isGroupByColumn && groupColumnIndex === column.idx; + return /*#__PURE__*/jsxRuntime.jsx("div", { + role: "gridcell", + "aria-colindex": column.idx + 1, + "aria-selected": isCellSelected, + tabIndex: tabIndex, + className: getCellClassname(column), + style: { + ...getCellStyle(column), + cursor: isLevelMatching ? 'pointer' : 'default' + }, + onClick: isLevelMatching ? toggleGroup : undefined, + onFocus: onFocus, + children: (!isGroupByColumn || isLevelMatching) && column.renderGroupCell?.({ + groupKey, + childRows, + column, + row, + isExpanded, + tabIndex: childTabIndex, + toggleGroup + }) + }, column.key); +} +const GroupCell$1 = /*#__PURE__*/react.memo(GroupCell); -const textEditor = "t1u15qzo700-beta13"; -const textEditorClassname = `rdg-text-editor ${textEditor}`; +const groupRow = "gyxx7e97-0-0-beta-37"; +const groupRowClassname = `rdg-group-row ${groupRow}`; +function GroupedRow({ + className, + row, + rowIdx, + viewportColumns, + selectedCellIdx, + isRowSelected, + selectCell, + gridRowStart, + height, + groupBy, + toggleGroup, + ...props +}) { + const idx = viewportColumns[0].key === SELECT_COLUMN_KEY ? row.level + 1 : row.level; + function handleSelectGroup() { + selectCell({ + rowIdx, + idx: -1 + }); + } + return /*#__PURE__*/jsxRuntime.jsx(RowSelectionProvider, { + value: isRowSelected, + children: /*#__PURE__*/jsxRuntime.jsx("div", { + role: "row", + "aria-level": row.level + 1, + "aria-setsize": row.setSize, + "aria-posinset": row.posInSet + 1, + "aria-expanded": row.isExpanded, + className: clsx(rowClassname, groupRowClassname, `rdg-row-${rowIdx % 2 === 0 ? 'even' : 'odd'}`, className, selectedCellIdx === -1 && rowSelectedClassname), + onClick: handleSelectGroup, + style: getRowStyle(gridRowStart, height), + ...props, + children: viewportColumns.map(column => /*#__PURE__*/jsxRuntime.jsx(GroupCell$1, { + id: row.id, + groupKey: row.groupKey, + childRows: row.childRows, + isExpanded: row.isExpanded, + isCellSelected: selectedCellIdx === column.idx, + column: column, + row: row, + groupColumnIndex: idx, + toggleGroup: toggleGroup, + isGroupByColumn: groupBy.includes(column.key) + }, column.key)) + }) + }); +} +const GroupedRow$1 = /*#__PURE__*/react.memo(GroupedRow); +function TreeDataGrid({ + columns: rawColumns, + rows: rawRows, + rowHeight: rawRowHeight, + rowKeyGetter: rawRowKeyGetter, + onCellKeyDown: rawOnCellKeyDown, + onRowsChange, + selectedRows: rawSelectedRows, + onSelectedRowsChange: rawOnSelectedRowsChange, + renderers, + groupBy: rawGroupBy, + rowGrouper, + expandedGroupIds, + onExpandedGroupIdsChange, + ...props +}, ref) { + const defaultRenderers = useDefaultRenderers(); + const rawRenderRow = renderers?.renderRow ?? defaultRenderers?.renderRow ?? defaultRenderRow; + const headerAndTopSummaryRowsCount = 1 + (props.topSummaryRows?.length ?? 0); + const isRtl = props.direction === 'rtl'; + const leftKey = isRtl ? 'ArrowRight' : 'ArrowLeft'; + const rightKey = isRtl ? 'ArrowLeft' : 'ArrowRight'; + const toggleGroupLatest = useLatestFunc(toggleGroup); + const { + columns, + groupBy + } = react.useMemo(() => { + const columns = [...rawColumns].sort(({ + key: aKey + }, { + key: bKey + }) => { + if (aKey === SELECT_COLUMN_KEY) return -1; + if (bKey === SELECT_COLUMN_KEY) return 1; + if (rawGroupBy.includes(aKey)) { + if (rawGroupBy.includes(bKey)) { + return rawGroupBy.indexOf(aKey) - rawGroupBy.indexOf(bKey); + } + return -1; + } + if (rawGroupBy.includes(bKey)) return 1; + return 0; + }); + const groupBy = []; + for (const [index, column] of columns.entries()) { + if (rawGroupBy.includes(column.key)) { + groupBy.push(column.key); + columns[index] = { + ...column, + frozen: true, + renderCell: () => null, + renderGroupCell: column.renderGroupCell ?? renderToggleGroup, + editable: false + }; + } + } + return { + columns, + groupBy + }; + }, [rawColumns, rawGroupBy]); + const [groupedRows, rowsCount] = react.useMemo(() => { + if (groupBy.length === 0) return [undefined, rawRows.length]; + const groupRows = (rows, [groupByKey, ...remainingGroupByKeys], startRowIndex) => { + let groupRowsCount = 0; + const groups = {}; + for (const [key, childRows] of Object.entries(rowGrouper(rows, groupByKey))) { + const [childGroups, childRowsCount] = remainingGroupByKeys.length === 0 ? [childRows, childRows.length] : groupRows(childRows, remainingGroupByKeys, startRowIndex + groupRowsCount + 1); + groups[key] = { + childRows, + childGroups, + startRowIndex: startRowIndex + groupRowsCount + }; + groupRowsCount += childRowsCount + 1; + } + return [groups, groupRowsCount]; + }; + return groupRows(rawRows, groupBy, 0); + }, [groupBy, rowGrouper, rawRows]); + const [rows, isGroupRow] = react.useMemo(() => { + const allGroupRows = new Set(); + if (!groupedRows) return [rawRows, isGroupRow]; + const flattenedRows = []; + const expandGroup = (rows, parentId, level) => { + if (isReadonlyArray(rows)) { + flattenedRows.push(...rows); + return; + } + Object.keys(rows).forEach((groupKey, posInSet, keys) => { + const id = parentId !== undefined ? `${parentId}__${groupKey}` : groupKey; + const isExpanded = expandedGroupIds.has(id); + const { + childRows, + childGroups, + startRowIndex + } = rows[groupKey]; + const groupRow = { + id, + parentId, + groupKey, + isExpanded, + childRows, + level, + posInSet, + startRowIndex, + setSize: keys.length + }; + flattenedRows.push(groupRow); + allGroupRows.add(groupRow); + if (isExpanded) { + expandGroup(childGroups, id, level + 1); + } + }); + }; + expandGroup(groupedRows, undefined, 0); + return [flattenedRows, isGroupRow]; + function isGroupRow(row) { + return allGroupRows.has(row); + } + }, [expandedGroupIds, groupedRows, rawRows]); + const rowHeight = react.useMemo(() => { + if (typeof rawRowHeight === 'function') { + return row => { + if (isGroupRow(row)) { + return rawRowHeight({ + type: 'GROUP', + row + }); + } + return rawRowHeight({ + type: 'ROW', + row + }); + }; + } + return rawRowHeight; + }, [isGroupRow, rawRowHeight]); + const getParentRowAndIndex = react.useCallback(row => { + const rowIdx = rows.indexOf(row); + for (let i = rowIdx - 1; i >= 0; i--) { + const parentRow = rows[i]; + if (isGroupRow(parentRow) && (!isGroupRow(row) || row.parentId === parentRow.id)) { + return [parentRow, i]; + } + } + return undefined; + }, [isGroupRow, rows]); + const rowKeyGetter = react.useCallback(row => { + if (isGroupRow(row)) { + return row.id; + } + if (typeof rawRowKeyGetter === 'function') { + return rawRowKeyGetter(row); + } + const parentRowAndIndex = getParentRowAndIndex(row); + if (parentRowAndIndex !== undefined) { + const { + startRowIndex, + childRows + } = parentRowAndIndex[0]; + const groupIndex = childRows.indexOf(row); + return startRowIndex + groupIndex + 1; + } + return rows.indexOf(row); + }, [getParentRowAndIndex, isGroupRow, rawRowKeyGetter, rows]); + const selectedRows = react.useMemo(() => { + if (rawSelectedRows == null) return null; + assertIsValidKeyGetter(rawRowKeyGetter); + const selectedRows = new Set(rawSelectedRows); + for (const row of rows) { + if (isGroupRow(row)) { + const isGroupRowSelected = row.childRows.every(cr => rawSelectedRows.has(rawRowKeyGetter(cr))); + if (isGroupRowSelected) { + selectedRows.add(row.id); + } + } + } + return selectedRows; + }, [isGroupRow, rawRowKeyGetter, rawSelectedRows, rows]); + function onSelectedRowsChange(newSelectedRows) { + if (!rawOnSelectedRowsChange) return; + assertIsValidKeyGetter(rawRowKeyGetter); + const newRawSelectedRows = new Set(rawSelectedRows); + for (const row of rows) { + const key = rowKeyGetter(row); + if (selectedRows?.has(key) && !newSelectedRows.has(key)) { + if (isGroupRow(row)) { + for (const cr of row.childRows) { + newRawSelectedRows.delete(rawRowKeyGetter(cr)); + } + } else { + newRawSelectedRows.delete(key); + } + } else if (!selectedRows?.has(key) && newSelectedRows.has(key)) { + if (isGroupRow(row)) { + for (const cr of row.childRows) { + newRawSelectedRows.add(rawRowKeyGetter(cr)); + } + } else { + newRawSelectedRows.add(key); + } + } + } + rawOnSelectedRowsChange(newRawSelectedRows); + } + function handleKeyDown(args, event) { + rawOnCellKeyDown?.(args, event); + if (event.isGridDefaultPrevented()) return; + if (args.mode === 'EDIT') return; + const { + column, + rowIdx, + selectCell + } = args; + const idx = column?.idx ?? -1; + const row = rows[rowIdx]; + if (!isGroupRow(row)) return; + if (idx === -1 && (event.key === leftKey && row.isExpanded || event.key === rightKey && !row.isExpanded)) { + event.preventDefault(); + event.preventGridDefault(); + toggleGroup(row.id); + } + if (idx === -1 && event.key === leftKey && !row.isExpanded && row.level !== 0) { + const parentRowAndIndex = getParentRowAndIndex(row); + if (parentRowAndIndex !== undefined) { + event.preventGridDefault(); + selectCell({ + idx, + rowIdx: parentRowAndIndex[1] + }); + } + } + if (isCtrlKeyHeldDown(event) && (event.keyCode === 67 || event.keyCode === 86)) { + event.preventGridDefault(); + } + } + function handleRowsChange(updatedRows, { + indexes, + column + }) { + if (!onRowsChange) return; + const updatedRawRows = [...rawRows]; + const rawIndexes = []; + indexes.forEach(index => { + const rawIndex = rawRows.indexOf(rows[index]); + updatedRawRows[rawIndex] = updatedRows[index]; + rawIndexes.push(rawIndex); + }); + onRowsChange(updatedRawRows, { + indexes: rawIndexes, + column + }); + } + function toggleGroup(groupId) { + const newExpandedGroupIds = new Set(expandedGroupIds); + if (newExpandedGroupIds.has(groupId)) { + newExpandedGroupIds.delete(groupId); + } else { + newExpandedGroupIds.add(groupId); + } + onExpandedGroupIdsChange(newExpandedGroupIds); + } + function renderRow(key, { + row, + rowClass, + onCellClick, + onCellDoubleClick, + onCellContextMenu, + onRowChange, + lastFrozenColumnIndex, + copiedCellIdx, + draggedOverCellIdx, + setDraggedOverRowIdx, + selectedCellEditor, + ...rowProps + }) { + if (isGroupRow(row)) { + const { + startRowIndex + } = row; + return /*#__PURE__*/jsxRuntime.jsx(GroupedRow$1, { + ...rowProps, + "aria-rowindex": headerAndTopSummaryRowsCount + startRowIndex + 1, + row: row, + groupBy: groupBy, + toggleGroup: toggleGroupLatest + }, key); + } + let ariaRowIndex = rowProps['aria-rowindex']; + const parentRowAndIndex = getParentRowAndIndex(row); + if (parentRowAndIndex !== undefined) { + const { + startRowIndex, + childRows + } = parentRowAndIndex[0]; + const groupIndex = childRows.indexOf(row); + ariaRowIndex = startRowIndex + headerAndTopSummaryRowsCount + groupIndex + 2; + } + return rawRenderRow(key, { + ...rowProps, + 'aria-rowindex': ariaRowIndex, + row, + rowClass, + onCellClick, + onCellDoubleClick, + onCellContextMenu, + onRowChange, + lastFrozenColumnIndex, + copiedCellIdx, + draggedOverCellIdx, + setDraggedOverRowIdx, + selectedCellEditor + }); + } + return /*#__PURE__*/jsxRuntime.jsx(DataGrid$1, { + ...props, + role: "treegrid", + "aria-rowcount": rowsCount + 1 + (props.topSummaryRows?.length ?? 0) + (props.bottomSummaryRows?.length ?? 0), + ref: ref, + columns: columns, + rows: rows, + rowHeight: rowHeight, + rowKeyGetter: rowKeyGetter, + onRowsChange: handleRowsChange, + selectedRows: selectedRows, + onSelectedRowsChange: onSelectedRowsChange, + onCellKeyDown: handleKeyDown, + renderers: { + ...renderers, + renderRow + } + }); +} +function isReadonlyArray(arr) { + return Array.isArray(arr); +} +const TreeDataGrid$1 = /*#__PURE__*/react.forwardRef(TreeDataGrid); + +const textEditorInternalClassname = "tlmcuo07-0-0-beta-37"; +const textEditorClassname = `rdg-text-editor ${textEditorInternalClassname}`; function autoFocusAndSelect(input) { input?.focus(); input?.select(); } - -function TextEditor({ +function textEditor({ row, column, onRowChange, @@ -3071,24 +3191,29 @@ function TextEditor({ className: textEditorClassname, ref: autoFocusAndSelect, value: row[column.key], - onChange: event => onRowChange({ ...row, + onChange: event => onRowChange({ + ...row, [column.key]: event.target.value }), - onBlur: () => onClose(true) + onBlur: () => onClose(true, false) }); } -exports.Cell = Cell$1; -exports.CheckboxFormatter = CheckboxFormatter; -exports.DataGridDefaultComponentsProvider = DataGridDefaultComponentsProvider; -exports.HeaderRenderer = HeaderRenderer; -exports.Row = Row$1; +exports.Cell = CellComponent$1; +exports.DataGridDefaultRenderersProvider = DataGridDefaultRenderersProvider; +exports.Row = RowComponent$1; exports.SELECT_COLUMN_KEY = SELECT_COLUMN_KEY; exports.SelectCellFormatter = SelectCellFormatter; exports.SelectColumn = SelectColumn; -exports.TextEditor = TextEditor; -exports.ToggleGroupFormatter = ToggleGroupFormatter; -exports.ValueFormatter = ValueFormatter; +exports.ToggleGroup = ToggleGroup; +exports.TreeDataGrid = TreeDataGrid$1; exports.default = DataGrid$1; +exports.renderCheckbox = renderCheckbox; +exports.renderHeaderCell = renderHeaderCell; +exports.renderSortIcon = renderSortIcon; +exports.renderSortPriority = renderSortPriority; +exports.renderToggleGroup = renderToggleGroup; +exports.renderValue = renderValue; +exports.textEditor = textEditor; exports.useRowSelection = useRowSelection; //# sourceMappingURL=bundle.cjs.map diff --git a/webapp/packages/plugin-react-data-grid/lib/lib/bundle.cjs.map b/webapp/packages/plugin-react-data-grid/lib/lib/bundle.cjs.map index a1f64727b3..7fecc56ba8 100644 --- a/webapp/packages/plugin-react-data-grid/lib/lib/bundle.cjs.map +++ b/webapp/packages/plugin-react-data-grid/lib/lib/bundle.cjs.map @@ -1 +1 @@ -{"version":3,"file":"bundle.cjs","sources":["../node_modules/style-inject/dist/style-inject.es.js","../src/style/cell.ts","../src/style/core.ts","../src/style/row.ts","../src/formatters/CheckboxFormatter.tsx","../src/hooks/useLayoutEffect.ts","../src/hooks/useFocusRef.ts","../src/DataGridDefaultComponentsProvider.ts","../src/formatters/SelectCellFormatter.tsx","../src/formatters/ValueFormatter.tsx","../src/formatters/ToggleGroupFormatter.tsx","../src/hooks/useRowSelection.ts","../src/Columns.tsx","../src/utils/colSpanUtils.ts","../src/utils/domUtils.ts","../src/utils/keyboardUtils.ts","../src/utils/selectedCellUtils.ts","../src/utils/styleUtils.ts","../src/utils/index.ts","../src/hooks/useCalculatedColumns.ts","../src/hooks/useGridDimensions.ts","../src/hooks/useLatestFunc.ts","../src/hooks/useRovingCellRef.ts","../src/hooks/useViewportColumns.ts","../src/hooks/useViewportRows.ts","../src/HeaderRenderer.tsx","../src/HeaderCell.tsx","../src/HeaderRow.tsx","../src/Cell.tsx","../src/Row.tsx","../src/GroupCell.tsx","../src/GroupRow.tsx","../src/SummaryCell.tsx","../src/SummaryRow.tsx","../src/EditCell.tsx","../src/DragHandle.tsx","../src/SortIcon.tsx","../src/DataGrid.tsx","../src/editors/TextEditor.tsx"],"sourcesContent":["function styleInject(css, ref) {\n if ( ref === void 0 ) ref = {};\n var insertAt = ref.insertAt;\n\n if (!css || typeof document === 'undefined') { return; }\n\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n\n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild);\n } else {\n head.appendChild(style);\n }\n } else {\n head.appendChild(style);\n }\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n}\n\nexport default styleInject;\n","import { css } from '@linaria/core';\n\nexport const cell = css`\n /*\n Cannot use these because of a Chromium bug:\n https://bugs.chromium.org/p/chromium/issues/detail?id=1326946\n once this is fixed we can also remove \"position: relative:\"\n contain: strict;\n contain: size layout style paint;\n */\n position: relative; /* needed for absolute positioning to work */\n contain: size style;\n padding-block: 0;\n padding-inline: 8px;\n border-inline-end: 1px solid var(--rdg-border-color);\n border-block-end: 1px solid var(--rdg-border-color);\n grid-row-start: var(--rdg-grid-row-start);\n background-color: inherit;\n\n white-space: nowrap;\n overflow: hidden;\n overflow: clip;\n text-overflow: ellipsis;\n outline: none;\n\n &[aria-selected='true'] {\n outline: 2px solid var(--rdg-selection-color);\n outline-offset: -2px;\n }\n`;\n\nexport const cellClassname = `rdg-cell ${cell}`;\n\n// max-content does not calculate width when contain is set to style or size\nexport const cellAutoResizeClassname = css`\n .${cell} {\n contain: content;\n }\n`;\n\nexport const cellFrozen = css`\n position: sticky;\n /* Should have a higher value than 0 to show up above unfrozen cells */\n z-index: 1;\n`;\n\nexport const cellFrozenClassname = `rdg-cell-frozen ${cellFrozen}`;\n\nexport const cellFrozenLast = css`\n box-shadow: calc(2px * var(--rdg-sign)) 0 5px -2px rgba(136, 136, 136, 0.3);\n`;\n\nexport const cellFrozenLastClassname = `rdg-cell-frozen-last ${cellFrozenLast}`;\n","import { css } from '@linaria/core';\nimport { row } from './row';\n\nconst lightTheme = `\n --rdg-color: #000;\n --rdg-border-color: #ddd;\n --rdg-summary-border-color: #aaa;\n --rdg-background-color: hsl(0deg 0% 100%);\n --rdg-header-background-color: hsl(0deg 0% 97.5%);\n --rdg-row-hover-background-color: hsl(0deg 0% 96%);\n --rdg-row-selected-background-color: hsl(207deg 76% 92%);\n --row-selected-hover-background-color: hsl(207deg 76% 88%);\n\n --rdg-checkbox-color: hsl(207deg 100% 29%);\n --rdg-checkbox-focus-color: hsl(207deg 100% 69%);\n --rdg-checkbox-disabled-border-color: #ccc;\n --rdg-checkbox-disabled-background-color: #ddd;\n`;\n\nconst darkTheme = `\n --rdg-color: #ddd;\n --rdg-border-color: #444;\n --rdg-summary-border-color: #555;\n --rdg-background-color: hsl(0deg 0% 13%);\n --rdg-header-background-color: hsl(0deg 0% 10.5%);\n --rdg-row-hover-background-color: hsl(0deg 0% 9%);\n --rdg-row-selected-background-color: hsl(207deg 76% 42%);\n --row-selected-hover-background-color: hsl(207deg 76% 38%);\n\n --rdg-checkbox-color: hsl(207deg 100% 79%);\n --rdg-checkbox-focus-color: hsl(207deg 100% 89%);\n --rdg-checkbox-disabled-border-color: #000;\n --rdg-checkbox-disabled-background-color: #333;\n`;\n\nconst root = css`\n ${lightTheme}\n --rdg-selection-color: #66afe9;\n --rdg-font-size: 14px;\n\n display: grid;\n\n color-scheme: var(--rdg-color-scheme, light dark);\n\n /* https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context */\n /* We set a stacking context so internal elements don't render on top of external components. */\n contain: strict;\n contain: size layout style paint;\n content-visibility: auto;\n block-size: 350px;\n border: 1px solid var(--rdg-border-color);\n box-sizing: border-box;\n overflow: auto;\n user-select: none;\n background-color: var(--rdg-background-color);\n color: var(--rdg-color);\n font-size: var(--rdg-font-size);\n\n /* set stacking context in safari */\n @supports not (contain: strict) {\n position: relative;\n z-index: 0;\n }\n\n *,\n *::before,\n *::after {\n box-sizing: inherit;\n }\n\n /* needed on Firefox */\n &::before {\n content: '';\n grid-column: 1/-1;\n grid-row: 1/-1;\n }\n\n &.rdg-dark {\n --rdg-color-scheme: dark;\n ${darkTheme}\n }\n\n &.rdg-light {\n --rdg-color-scheme: light;\n }\n\n @media (prefers-color-scheme: dark) {\n &:not(.rdg-light) {\n ${darkTheme}\n }\n }\n`;\n\nexport const rootClassname = `rdg ${root}`;\n\nconst viewportDragging = css`\n &.${row} {\n cursor: move;\n }\n`;\n\nexport const viewportDraggingClassname = `rdg-viewport-dragging ${viewportDragging}`;\n\nexport const focusSinkClassname = css`\n grid-column: 1/-1;\n pointer-events: none;\n /* Should have a higher value than 3 to show up above header row */\n z-index: 4;\n`;\n","import { css } from '@linaria/core';\n\nexport const row = css`\n display: contents;\n line-height: var(--rdg-row-height);\n background-color: var(--rdg-background-color);\n\n &:hover {\n background-color: var(--rdg-row-hover-background-color);\n }\n\n &[aria-selected='true'] {\n background-color: var(--rdg-row-selected-background-color);\n\n &:hover {\n background-color: var(--row-selected-hover-background-color);\n }\n }\n`;\n\nexport const rowClassname = `rdg-row ${row}`;\n\nexport const rowSelected = css`\n outline: 2px solid var(--rdg-selection-color);\n outline-offset: -2px;\n`;\n\nexport const rowSelectedClassname = `rdg-row-selected`;\n\nexport const rowSelectedWithFrozenCell = css`\n &::before {\n content: '';\n display: inline-block;\n height: 100%;\n position: sticky;\n inset-inline-start: 0;\n border-inline-start: 2px solid var(--rdg-selection-color);\n }\n`;\n","import { forwardRef } from 'react';\nimport clsx from 'clsx';\nimport { css } from '@linaria/core';\n\nimport type { CheckboxFormatterProps } from '../types';\n\nconst checkboxLabel = css`\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n inset: 0;\n margin-inline-end: 1px; /* align checkbox in row group cell */\n`;\n\nconst checkboxLabelClassname = `rdg-checkbox-label ${checkboxLabel}`;\n\nconst checkboxInput = css`\n all: unset;\n`;\n\nconst checkboxInputClassname = `rdg-checkbox-input ${checkboxInput}`;\n\nconst checkbox = css`\n content: '';\n inline-size: 20px;\n block-size: 20px;\n border: 2px solid var(--rdg-border-color);\n background-color: var(--rdg-background-color);\n .${checkboxInput}:checked + & {\n background-color: var(--rdg-checkbox-color);\n outline: 4px solid var(--rdg-background-color);\n outline-offset: -6px;\n }\n .${checkboxInput}:focus + & {\n border-color: var(--rdg-checkbox-focus-color);\n }\n`;\n\nconst checkboxClassname = `rdg-checkbox ${checkbox}`;\n\nconst checkboxLabelDisabled = css`\n cursor: default;\n .${checkbox} {\n border-color: var(--rdg-checkbox-disabled-border-color);\n background-color: var(--rdg-checkbox-disabled-background-color);\n }\n`;\n\nconst checkboxLabelDisabledClassname = `rdg-checkbox-label-disabled ${checkboxLabelDisabled}`;\n\nexport const CheckboxFormatter = forwardRef(\n function CheckboxFormatter({ onChange, ...props }: CheckboxFormatterProps, ref) {\n function handleChange(e: React.ChangeEvent) {\n onChange(e.target.checked, (e.nativeEvent as MouseEvent).shiftKey);\n }\n\n return (\n \n \n
\n \n );\n }\n);\n","// eslint-disable-next-line @typescript-eslint/no-restricted-imports\nimport { useEffect, useLayoutEffect as useOriginalLayoutEffect } from 'react';\n\n// Silence silly warning\n// https://reactjs.org/link/uselayouteffect-ssr\nexport const useLayoutEffect = typeof window === 'undefined' ? useEffect : useOriginalLayoutEffect;\n","import { useRef } from 'react';\nimport { useLayoutEffect } from './useLayoutEffect';\n\nexport function useFocusRef(isSelected: boolean) {\n const ref = useRef(null);\n\n useLayoutEffect(() => {\n if (!isSelected) return;\n ref.current?.focus({ preventScroll: true });\n }, [isSelected]);\n\n return {\n ref,\n tabIndex: isSelected ? 0 : -1\n };\n}\n","import { createContext, useContext } from 'react';\n\nimport type { Components, Maybe } from './types';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst DataGridDefaultComponentsContext = createContext>>(undefined);\n\nexport const DataGridDefaultComponentsProvider = DataGridDefaultComponentsContext.Provider;\n\nexport function useDefaultComponents(): Maybe> {\n return useContext(DataGridDefaultComponentsContext);\n}\n","import { useFocusRef } from '../hooks/useFocusRef';\nimport { useDefaultComponents } from '../DataGridDefaultComponentsProvider';\nimport type { CheckboxFormatterProps } from '../types';\n\ntype SharedInputProps = Pick;\n\ninterface SelectCellFormatterProps extends SharedInputProps {\n isCellSelected: boolean;\n value: boolean;\n onChange: (value: boolean, isShiftClick: boolean) => void;\n}\n\nexport function SelectCellFormatter({\n value,\n isCellSelected,\n disabled,\n onChange,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy\n}: SelectCellFormatterProps) {\n const { ref, tabIndex } = useFocusRef(isCellSelected);\n const Formatter = useDefaultComponents()!.checkboxFormatter!;\n\n return (\n \n );\n}\n","import type { FormatterProps } from '../types';\n\nexport function ValueFormatter(props: FormatterProps) {\n try {\n return <>{props.row[props.column.key as keyof R]};\n } catch {\n return null;\n }\n}\n","import { css } from '@linaria/core';\nimport type { GroupFormatterProps } from '../types';\nimport { useFocusRef } from '../hooks/useFocusRef';\n\nconst groupCellContent = css`\n outline: none;\n`;\n\nconst groupCellContentClassname = `rdg-group-cell-content ${groupCellContent}`;\n\nconst caret = css`\n margin-inline-start: 4px;\n stroke: currentColor;\n stroke-width: 1.5px;\n fill: transparent;\n vertical-align: middle;\n\n > path {\n transition: d 0.1s;\n }\n`;\n\nconst caretClassname = `rdg-caret ${caret}`;\n\nexport function ToggleGroupFormatter({\n groupKey,\n isExpanded,\n isCellSelected,\n toggleGroup\n}: GroupFormatterProps) {\n const { ref, tabIndex } = useFocusRef(isCellSelected);\n\n function handleKeyDown({ key }: React.KeyboardEvent) {\n if (key === 'Enter') {\n toggleGroup();\n }\n }\n\n const d = isExpanded ? 'M1 1 L 7 7 L 13 1' : 'M1 7 L 7 1 L 13 7';\n\n return (\n \n {groupKey as string}\n \n \n \n \n );\n}\n","import { createContext, useContext } from 'react';\nimport type { SelectRowEvent } from '../types';\n\nconst RowSelectionContext = createContext(undefined);\n\nexport const RowSelectionProvider = RowSelectionContext.Provider;\n\nconst RowSelectionChangeContext = createContext<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ((selectRowEvent: SelectRowEvent) => void) | undefined\n>(undefined);\n\nexport const RowSelectionChangeProvider = RowSelectionChangeContext.Provider;\n\nexport function useRowSelection(): [boolean, (selectRowEvent: SelectRowEvent) => void] {\n const rowSelectionContext = useContext(RowSelectionContext);\n const rowSelectionChangeContext = useContext(RowSelectionChangeContext);\n\n if (rowSelectionContext === undefined || rowSelectionChangeContext === undefined) {\n throw new Error('useRowSelection must be used within DataGrid cells');\n }\n\n return [rowSelectionContext, rowSelectionChangeContext];\n}\n","import { SelectCellFormatter } from './formatters';\nimport { useRowSelection } from './hooks/useRowSelection';\nimport type { Column, FormatterProps, GroupFormatterProps } from './types';\n\nexport const SELECT_COLUMN_KEY = 'select-row';\n\nfunction SelectFormatter(props: FormatterProps) {\n const [isRowSelected, onRowSelectionChange] = useRowSelection();\n\n return (\n {\n onRowSelectionChange({ row: props.row, checked, isShiftClick });\n }}\n />\n );\n}\n\nfunction SelectGroupFormatter(props: GroupFormatterProps) {\n const [isRowSelected, onRowSelectionChange] = useRowSelection();\n\n return (\n {\n onRowSelectionChange({ row: props.row, checked, isShiftClick: false });\n }}\n />\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const SelectColumn: Column = {\n key: SELECT_COLUMN_KEY,\n name: '',\n width: 35,\n minWidth: 35,\n maxWidth: 35,\n resizable: false,\n sortable: false,\n frozen: true,\n headerRenderer(props) {\n return (\n \n );\n },\n formatter: SelectFormatter,\n groupFormatter: SelectGroupFormatter\n};\n","import type { CalculatedColumn, ColSpanArgs } from '../types';\n\nexport function getColSpan(\n column: CalculatedColumn,\n lastFrozenColumnIndex: number,\n args: ColSpanArgs\n): number | undefined {\n const colSpan = typeof column.colSpan === 'function' ? column.colSpan(args) : 1;\n if (\n Number.isInteger(colSpan) &&\n colSpan! > 1 &&\n // ignore colSpan if it spans over both frozen and regular columns\n (!column.frozen || column.idx + colSpan! - 1 <= lastFrozenColumnIndex)\n ) {\n return colSpan!;\n }\n return undefined;\n}\n","import type { Maybe } from '../types';\n\nexport function stopPropagation(event: React.SyntheticEvent) {\n event.stopPropagation();\n}\n\nexport function scrollIntoView(element: Maybe) {\n element?.scrollIntoView({ inline: 'nearest', block: 'nearest' });\n}\n","// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values\nconst nonInputKeys = new Set([\n // Special keys\n 'Unidentified',\n // Modifier keys\n 'Alt',\n 'AltGraph',\n 'CapsLock',\n 'Control',\n 'Fn',\n 'FnLock',\n 'Meta',\n 'NumLock',\n 'ScrollLock',\n 'Shift',\n // Whitespace keys\n 'Tab',\n // Navigation keys\n 'ArrowDown',\n 'ArrowLeft',\n 'ArrowRight',\n 'ArrowUp',\n 'End',\n 'Home',\n 'PageDown',\n 'PageUp',\n // Editing\n 'Insert',\n // UI keys\n 'ContextMenu',\n 'Escape',\n 'Pause',\n 'Play',\n // Device keys\n 'PrintScreen',\n // Function keys\n 'F1',\n // 'F2', /!\\ specifically allowed, do not edit\n 'F3',\n 'F4',\n 'F5',\n 'F6',\n 'F7',\n 'F8',\n 'F9',\n 'F10',\n 'F11',\n 'F12'\n]);\n\nexport function isCtrlKeyHeldDown(e: React.KeyboardEvent): boolean {\n return (e.ctrlKey || e.metaKey) && e.key !== 'Control';\n}\n\nexport function isDefaultCellInput(event: React.KeyboardEvent): boolean {\n return !nonInputKeys.has(event.key);\n}\n\n/**\n * By default, the following navigation keys are enabled while an editor is open, under specific conditions:\n * - Tab:\n * - The editor must be an , a