/* eslint-disable sonarjs/no-identical-functions */ import * as React from "react"; import { useState, useCallback, useMemo } from "@storybook/addons"; import { BuilderThemeWrapper } from "../../stories/story-utils.js"; import { CompactSelection, type EditableGridCell, type GridCell, GridCellKind, type GridColumn, type GridSelection, type Item, } from "../../internal/data-grid/data-grid-types.js"; import { DataEditorAll as DataEditor } from "../../data-editor-all.js"; export default { title: "Tests/TestCases", decorators: [ (Story: React.ComponentType) => ( ), ], }; function getDummyData([col, row]: Item): GridCell { if (col === 0) { return { kind: GridCellKind.RowID, data: `RowID ${col}, ${row}`, allowOverlay: false, }; } if (col === 1) { return { kind: GridCellKind.Bubble, data: [ `Bub ${col}`, `Bub ${row}`, `Bub ${col}`, `Bub ${row}`, `Bub ${col}`, `Bub ${row}`, `Bub ${col}`, `Bub ${row}`, `Bub ${col}`, `Bub ${row}`, ], allowOverlay: true, }; } if (col === 2) { return { kind: GridCellKind.Image, data: [ "https://i.imgur.com/5J0BftG.jpg", "https://preview.redd.it/7jlqkp2cyap51.jpg?width=575&auto=webp&s=26fa9ed15b16fb450ee08ed1f2f0ccb5e0223581", ], allowOverlay: true, readonly: false, }; } if (col === 3) { return { kind: GridCellKind.Markdown, data: `## Markdown has titles And supports newline chars and automatic wrapping text that just needs to be long enough to trigger it. [Google](https://google.com) - with - lists - that - can - be - pretty - long `, allowOverlay: true, }; } if (col === 4) { return { kind: GridCellKind.Number, displayData: "$10,352", allowOverlay: true, data: 10_352, readonly: true, }; } if (col === 5) { return { kind: GridCellKind.Uri, data: "https://www.google.com", allowOverlay: true, }; } if (col === 6) { return { kind: GridCellKind.Boolean, data: row % 3 === 0 || row % 5 === 0, readonly: true, allowOverlay: false, }; } if (col === 7) { return { kind: GridCellKind.Text, // RTL test displayData: `הרפתקה חדשה`, data: `הרפתקה חדשה`, allowOverlay: true, readonly: true, }; } if (col === 8) { return { kind: GridCellKind.Drilldown, data: [ { text: "Test", img: "https://allthatsinteresting.com/wordpress/wp-content/uploads/2012/06/iconic-photos-1950-einstein.jpg", }, { text: "No Image" }, ], allowOverlay: true, }; } return { kind: GridCellKind.Text, displayData: `${col}, ${row} 🦝`, data: `${col}, ${row} 🦝`, allowOverlay: true, }; } function getDummyCols() { return [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20].map( i => ({ title: i.toString() + " is the longest header in the world", width: 120 + (i % 4) * 10, icon: "headerString", hasMenu: true, }) as GridColumn ); } export function Simplenotest() { const [cols, setColumns] = useState(getDummyCols); const onColumnResize = useCallback( (col: GridColumn, newSize: number) => { const index = cols.indexOf(col); const newCols = [...cols]; newCols[index] = { ...newCols[index], width: newSize, }; setColumns(newCols); }, [cols] ); return ( ); } function getDummyRelationColumn(): GridColumn[] { return [ { title: "Relation", width: 360, icon: "headerString", hasMenu: true, }, ]; } function getDummyRelationData([col, row]: Item): GridCell { return { kind: GridCellKind.Drilldown, data: [ { text: `Image ${col}-${row}`, img: "https://allthatsinteresting.com/wordpress/wp-content/uploads/2012/06/iconic-photos-1950-einstein.jpg", }, { text: `Text ${col}-${row}` }, { text: `More text ${col}-${row}` }, ], allowOverlay: true, }; } export function RelationColumn() { const [cols, setColumns] = useState(getDummyRelationColumn); const onColumnResize = useCallback( (col: GridColumn, newSize: number) => { const index = cols.indexOf(col); const newCols = [...cols]; newCols[index] = { ...newCols[index], width: newSize, }; setColumns(newCols); }, [cols] ); return ( ); } const columns: GridColumn[] = [ { title: "Number", width: 100, icon: "headerArray", overlayIcon: "rowOwnerOverlay" }, { title: "Square", width: 100 }, ]; function getData([col, row]: Item): GridCell { const n = Math.pow(row, col + 1); return { kind: GridCellKind.Number, data: n, displayData: n.toString(), allowOverlay: false, }; } export function Minimal() { return ; } export function Smooth() { const [cols, setCols] = useState(getDummyCols); const onColumnResize = useCallback( (column: GridColumn, newSize: number) => { const index = cols.indexOf(column); if (index !== -1) { const newCol: GridColumn = { ...column, width: newSize, }; const newCols = [...cols]; newCols.splice(index, 1, newCol); setCols(newCols); } }, [cols] ); return ( ); } export function ManualControl() { const [gridSelection, setGridSelection] = useState(undefined); const cb = (newVal: GridSelection) => { if ((newVal.current?.cell[0] ?? 0) % 2 === 0) { setGridSelection(newVal); } }; return ( ); } export function Draggable() { return ( { args.setData("text", "testing"); }} getCellContent={getData} columns={columns} rows={1000} /> ); } export function IdealSize() { // trying to be 500x500 const cols: GridColumn[] = [ { title: "Number", width: 250 }, { title: "Square", width: 250 }, ]; return (
{ args.setData("text", "testing"); }} getCellContent={getData} columns={cols} smoothScrollX={true} smoothScrollY={true} rowHeight={50} headerHeight={50} rows={9} />
); } export function DynamicAddRemoveColumns({ columnCount }: { columnCount: number }) { // trying to be 500x500 const cols: GridColumn[] = [ { title: "Number", width: 250 }, { title: "Square", width: 250 }, ]; for (let i = 2; i < columnCount; i++) { cols.push({ title: "Foo", width: 250, }); } return ( ); } DynamicAddRemoveColumns.args = { columnCount: 2, }; export function GridSelectionOutOfRangeNoColumns() { const dummyCols = useMemo( () => getDummyCols().map(v => ({ ...v, width: 300, title: "Making column smaller used to crash!" })), [] ); const [selected, setSelected] = useState({ current: { cell: [2, 8], range: { width: 1, height: 1, x: 2, y: 8 }, rangeStack: [] }, columns: CompactSelection.empty(), rows: CompactSelection.empty(), }); const [cols, setCols] = useState(dummyCols); const onSelected = useCallback((newSel?: GridSelection) => { setSelected(newSel); }, []); return ( { if (newSize > 300) { setCols(dummyCols); } else { setCols([]); } }} /> ); } type ResizableColumnsSizeMap = Record; function getResizableColumnsInitSize(): ResizableColumnsSizeMap { return { "resize me 0": 120, "resize me 1": 120, "resize me 2": 120, "resize me 3": 120, "resize me 4": 120, "resize me 5": 120, "resize me 6": 120, "resize me 7": 120, }; } function getResizableColumns(sizeMap: ResizableColumnsSizeMap): GridColumn[] { return Object.entries(sizeMap).map(([title, width]) => ({ title, width, icon: "headerString", hasMenu: true, })); } export function ResizableColumns() { const [colSizes, setColSizes] = useState(getResizableColumnsInitSize); const cols = useMemo(() => { return getResizableColumns(colSizes); }, [colSizes]); const onColumnResize = useCallback((column: GridColumn, newSize: number) => { setColSizes(prevColSizes => { return { ...prevColSizes, [column.title]: newSize, }; }); }, []); return ( ); } export function GridSelectionOutOfRangeLessColumnsThanSelection() { const dummyCols = useMemo( () => getDummyCols().map(v => ({ ...v, width: 300, title: "Making column smaller used to crash!" })), [] ); const [selected, setSelected] = useState({ current: { cell: [2, 8], range: { width: 1, height: 1, x: 2, y: 8 }, rangeStack: [] }, columns: CompactSelection.empty(), rows: CompactSelection.empty(), }); const [cols, setCols] = useState(dummyCols); const onSelected = useCallback((newSel?: GridSelection) => { setSelected(newSel); }, []); return ( { if (newSize > 300) { setCols(dummyCols); } else { setCols([dummyCols[0]]); } }} /> ); } export function GridAddNewRows() { const cols = useMemo(getDummyCols, []); const [rowsCount, setRowsCount] = useState(10); const onRowAppended = useCallback(() => { setRowsCount(r => r + 1); }, []); const [selected, setSelected] = useState(undefined); const onSelected = useCallback((newSel?: GridSelection) => { setSelected(newSel); }, []); return ( ); } export function GridNoTrailingBlankRow() { const cols = useMemo(getDummyCols, []); const [selected, setSelected] = useState(undefined); const onSelected = useCallback((newSel?: GridSelection) => { setSelected(newSel); }, []); return ( ); } export function MarkdownEdits() { const dummyCols: GridColumn[] = useMemo(() => { return [ { title: "MD short", width: 50, }, { title: "MD long", width: 50, }, ]; }, []); const dummyCells = useCallback(([col, _row]: Item) => { if (col === 0) { const editable: EditableGridCell = { data: "text", allowOverlay: true, kind: GridCellKind.Markdown, }; return editable; } else if (col === 1) { const editable: EditableGridCell = { data: `text really really really long ## H1 - this - is - a - longer - example - to - test - scroll - of - preview `, allowOverlay: true, kind: GridCellKind.Markdown, }; return editable; } const editable: EditableGridCell = { data: "text", allowOverlay: true, kind: GridCellKind.Markdown, }; return editable; }, []); const [selected, setSelected] = useState({ current: { cell: [2, 8], range: { width: 1, height: 1, x: 2, y: 8 }, rangeStack: [] }, columns: CompactSelection.empty(), rows: CompactSelection.empty(), }); const onSelected = useCallback((newSel?: GridSelection) => { setSelected(newSel); }, []); return ( ); } export const CanEditBoolean = () => { const [vals, setVals] = useState<[boolean | null | undefined, boolean | null | undefined]>([false, false]); return ( { return { kind: GridCellKind.Boolean, readonly: col !== 0, allowOverlay: false, data: vals[col], }; }} onCellEdited={([col], newVal) => { if (newVal.kind === GridCellKind.Boolean) { setVals(cv => { const f = [...cv]; f.splice(col, 1, newVal.data); return f as [boolean, boolean]; }); } }} /> ); }; export const SimpleEditable = () => { const [vals, setVals] = useState<[string, string][]>(() => { const result: [string, string][] = []; for (let i = 0; i < 2000; i++) { result.push(["Edit", "Me"]); } return result; }); return ( ({ kind: GridCellKind.Text, allowOverlay: true, data: vals[row][col], displayData: vals[row][col], })} onCellEdited={([col, row], newVal) => { const newVals = [...vals]; const newRow: [string, string] = [...newVals[row]]; if (typeof newVal.data === "string") { newRow[col] = newVal.data; } newVals[row] = newRow; setVals(newVals); }} /> ); };