### Render ReactGrid Example Source: https://silevis.github.io/reactgrid/docs/5.0/2-implementing-core-features/5-fill-handle This snippet shows the standard method for rendering a ReactGrid example component into the DOM using React's ReactDOM.render function. ```javascript render(, document.getElementById("root")); ``` -------------------------------- ### ReactGrid Live Example with Aggregation Source: https://silevis.github.io/reactgrid/docs/5.0/1-getting-started A React component demonstrating ReactGrid with data aggregation. It includes defining styled ranges, setting up cell data with labels and values, and calculating a summary row automatically. The example utilizes `useState` for managing data and custom cell templates like `NonEditableCell` and `NumberCell`. ```javascript const styledRanges = [ { range: { start: { rowIndex: 0, columnIndex: 1 }, end: { rowIndex: 1, columnIndex: 4 } }, styles: { background: "#55bc71", color: "white" }, }, { range: { start: { rowIndex: 1, columnIndex: 0 }, end: { rowIndex: 4, columnIndex: 1 } }, styles: { background: "#55bc71", color: "white" }, }, { range: { start: { rowIndex: 0, columnIndex: 0 }, end: { rowIndex: 1, columnIndex: 1 } }, styles: { background: "#318146", color: "white" }, }, { range: { start: { rowIndex: 3, columnIndex: 1 }, end: { rowIndex: 4, columnIndex: 4 } }, styles: { background: "#f8f8f8" }, }, { range: { start: { rowIndex: 1, columnIndex: 3 }, end: { rowIndex: 3, columnIndex: 4 } }, styles: { background: "#f8f8f8" }, }, ]; const ReactGridExample = () => { const [yearsData, setYearsData] = useState([ { label: "2023", values: [1, 3] }, { label: "2024", values: [2, 4] }, ]); // [{ label: "2023", values: [1, 3, 4] }, { label: "2024", values: [2, 4, 6] }] const yearsDataWithTotals = yearsData.map((year) => ({ ...year, values: [...year.values, year.values.reduce((sum, value) => sum + value, 0)], })); // { label: "Sum", values: [3, 7, 10] } const summaryRow = { label: "Sum", values: yearsDataWithTotals.reduce( (sum, year) => sum.map((currentSum, index) => currentSum + year.values[index]), [0, 0, 0] ), }; const cells: Cell[] = [ // Header cells { rowIndex: 0, colIndex: 0, Template: NonEditableCell, props: { value: "" } }, { rowIndex: 0, colIndex: 1, Template: NonEditableCell, props: { value: "H1" } }, { rowIndex: 0, colIndex: 2, Template: NonEditableCell, props: { value: "H2" } }, { rowIndex: 0, colIndex: 3, Template: NonEditableCell, props: { value: "Total" } }, // Year data cells ...yearsDataWithTotals .map((year, rowIndex) => [ { rowIndex: rowIndex + 1, colIndex: 0, Template: NonEditableCell, props: { value: year.label } }, ...year.values.map((value, colIndex) => { // Last column is not editable const isEditable = colIndex + 1 !== year.values.length; return { rowIndex: rowIndex + 1, colIndex: colIndex + 1, Template: !isEditable ? NonEditableCell : NumberCell, props: { value, ...(isEditable && { onValueChanged: (newValue) => { setYearsData((prev) => { const updatedYears = [...prev]; updatedYears[rowIndex].values[colIndex] = newValue; return updatedYears; }); }, }), }, }; }), ]) .flat(), // Summary row { rowIndex: yearsDataWithTotals.length + 1, colIndex: 0, Template: NonEditableCell, props: { value: summaryRow.label }, }, ...summaryRow.values.map((value, colIndex) => ({ rowIndex: yearsDataTotals.length + 1, colIndex: colIndex + 1, Template: NonEditableCell, props: { value }, })), ]; return ; }; render(, document.getElementById("root")); ``` -------------------------------- ### Install ReactGrid 5.0 Alpha Source: https://silevis.github.io/reactgrid/docs/5.0/1-getting-started Installs the alpha version of ReactGrid using npm. This command adds the necessary package to your project's dependencies. Unlike previous versions, CSS is automatically handled. ```bash npm i @silevis/reactgrid@alpha ``` -------------------------------- ### ReactGrid Example Component Source: https://silevis.github.io/reactgrid/docs/5.0/2-implementing-core-features/9-column-and-row-reordering The main React component that sets up and renders the ReactGrid. It manages the state for people data and columns, defines the cell generation logic, and configures grid interactions like row/column reordering. ```typescript const ReactGridExample = () => { const [people, setPeople] = useState(peopleData); const updatePerson = (id, key, newValue) => { setPeople((prev) => { return prev.map((p) => (p.id === id ? { ...p, [key]: newValue } : p)); }); }; const rows = getRows(people); const [columns, setColumns] = useState(getColumns()); const cells = generateCells(people, columns, updatePerson); return (
handleRowReorder(people, selectedRowIndexes, destinationRowIdx, updatePerson) } onColumnReorder={(selectedColIndexes, destinationColIdx) => handleColumnReorder(selectedColIndexes, destinationColIdx, setColumns) } />
); }; render(, document.getElementById("root")); ``` -------------------------------- ### ReactGrid Component Setup and State Management (JavaScript) Source: https://silevis.github.io/reactgrid/docs/5.0/4-create-your-own-cell-template This JavaScript code sets up the main React component for the grid example. It uses the `useState` hook to manage the 'people' data and defines the `updatePerson` function to handle modifications to the data. The component then renders the `ReactGrid` with the processed rows, columns, and cells. ```javascript const ReactGridExample = () => { const [people, setPeople] = useState(peopleData); const updatePerson = (id, key, newValue) => { setPeople((prev) => { return prev.map((p) => (p.id === id ? { ...p, [key]: newValue } : p)); }); }; const rows = getRows(people); const columns = getColumns(); const cells = generateCells(people, updatePerson); return (
); }; render(, document.getElementById("root")); ``` -------------------------------- ### ReactGrid 5.0 Data and Cell Generation (JavaScript) Source: https://silevis.github.io/reactgrid/docs/5.0/2-implementing-core-features/8-cell-span This JavaScript code defines the data structure, cell generation logic, and grid configuration for a ReactGrid example. It includes functions for creating rows, columns, and cells, handling data updates, and applying cell styles and spans. Dependencies include React and the ReactGrid library. ```javascript const cellStyles = { header: { backgroundColor: "#55bc71", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: "bold", }, }; const categoryArr = [ { id: 1, range: "1-5", categoryName: "cat1", percentage: 0.5, records: 10 }, { id: 2, range: "6-10", categoryName: "cat2", percentage: 0.1, records: 20 }, { id: 3, range: "11-15", categoryName: "cat2", percentage: 0.1, records: 30 }, { id: 4, range: "16-20", categoryName: "cat3", percentage: 0.4, records: 40 }, { id: 5, range: "21-25", categoryName: "cat3", percentage: 0.4, records: 50 }, { id: 6, range: "26-30", categoryName: "cat3", percentage: 0.4, records: 60 }, ]; const getRows = (people: Category[]): Row[] => [ // header row { rowIndex: 0, height: 40, }, // data rows ...people.map((_, i) => ({ rowIndex: i + 1, height: 40, })), ]; const getColumns = (): Column[] => [ { colIndex: 0, width: 220 }, { colIndex: 1, width: 220 }, { colIndex: 2, width: 220 }, { colIndex: 3, width: 220 }, ]; type UpdateCategoryFn = (id: number, key: string, newValue: T) => void; const generateCells = (categories: Category[], updateCategories: UpdateCategoryFn): Cell[] => { const generateHeaderCells = () => { const titles = ["Range", "Category", "Category %", "Records"]; return titles.map((title, colIndex) => ({ rowIndex: 0, colIndex, Template: NonEditableCell, props: { value: title, style: cellStyles.header, }, })); }; const spannedCellsIdx = [ { rowIndex: 2, colIndex: 1, rowSpan: 2 }, { rowIndex: 2, colIndex: 2, rowSpan: 2 }, { rowIndex: 4, colIndex: 1, rowSpan: 3 }, { rowIndex: 4, colIndex: 2, rowSpan: 3 }, ]; const isCellOverlappingSpan = (rowIndex: number, colIndex: number): boolean => { return spannedCellsIdx.some(({ rowIndex: spanRow, colIndex: spanCol, rowSpan }) => { return colIndex === spanCol && rowIndex > spanRow && rowIndex < spanRow + rowSpan; }); }; const getSpan = (rowIndex: number, colIndex: number) => { const spannedCell = spannedCellsIdx.find((cell) => cell.rowIndex === rowIndex && cell.colIndex === colIndex); if(!spannedCell) return null; return { rowSpan: spannedCell.rowSpan }; }; const generateRowCells = (rowIndex: number, category: Category): Cell[] => { const { id, range, categoryName, percentage, records } = category; return [ { rowIndex, colIndex: 0, Template: TextCell, props: { text: range, onTextChanged: (newText: string) => updateCategories(id, "range", newText), }, }, { rowIndex, colIndex: 1, Template: TextCell, props: { text: categoryName, onTextChanged: (newValue: string) => updateCategories(id, "categoryName", newValue), }, ...getSpan(rowIndex, 1), // Check if this is a spanned cell }, { rowIndex, colIndex: 2, Template: NumberCell, props: { value: percentage, onValueChanged: (newValue: number) => updateCategories(id, "percentage", newValue), format: new Intl.NumberFormat("en-US", { style: "percent", minimumFractionDigits: 0 }), }, ...getSpan(rowIndex, 2), // Check if this is a spanned cell }, { rowIndex, colIndex: 3, Template: NumberCell, props: { value: records, onValueChanged: (newValue: number) => updateCategories(id, "records", newValue), }, }, ].filter((cell) => !isCellOverlappingSpan(cell.rowIndex, cell.colIndex)); // Filter out only overlapping cells }; const headerCells = generateHeaderCells(); const rowCells = categories.flatMap((category, idx) => generateRowCells(idx + 1, category)); return [...headerCells, ...rowCells]; }; const ReactGridExample = () => { const [categories, setCategories] = useState(categoryArr); const updateCategories = (id: number, key: string, newValue) => { setCategories((prevData) => prevData.map((category) => (category.id !== id ? category : { ...category, [key]: newValue })) ); }; const rows = getRows(categories); const columns = getColumns(); const cells = generateCells(categories, updateCategories); return ( ); }; render(, document.getElementById("root")); ``` -------------------------------- ### ReactGrid Data Handling Example with State Management Source: https://silevis.github.io/reactgrid/docs/5.0/2-implementing-core-features/2-handling-changes Illustrates a React component using ReactGrid to display and edit a list of people. It includes sample data, a state management hook (`useState`) to hold the data, and an `updatePerson` function to modify individual records, demonstrating how to integrate data changes back into the grid. ```javascript const peopleData = [ { _id: "66d61077035753f369ddbb16", name: "Jordan Rodriquez", age: 30, email: "jordanrodriquez@cincyr.com", company: "Zaggles", position: 1, }, { _id: "66d61077794e7949ab167fd5", email: "allysonrios@satiance.com", name: "Allyson Rios", age: 30, company: "Zoxy", position: 2, }, { _id: "66d61077dd754e88981ae434", name: "Pickett Lucas", age: 25, email: "pickettlucas@zoxy.com", company: "Techade", position: 3, }, { _id: "66d61077115e2f8748c334d9", name: "Louella David", age: 37, email: "louelladavid@techade.com", company: "Ginkogene", position: 4, }, { _id: "66d61077540d53374b427e4b", name: "Tricia Greene", age: 27, email: "triciagreene@ginkogene.com", company: "Naxdis", position: 5, }, ]; const ReactGridExample = () => { const [people, setPeople] = useState(peopleData); const updatePerson = (id, key, newValue) => { setPeople((prev) => { return prev.map((p) => (p.id === id ? { ...p, [key]: newValue } : p)); }); }; const cells = [ { rowIndex: 0, colIndex: 0, Template: TextCell; props: { text: people[0].name, onTextChanged: (newText) => { updatePerson(people[0]._id, "name", newText); }, } }, //... ]; return ; }; ``` -------------------------------- ### Define Styled Ranges and Cell Data for ReactGrid Source: https://silevis.github.io/reactgrid/docs/5.0/2-implementing-core-features/6-styled-ranges This snippet defines the TypeScript types for `StyledRange` and `Range`, and provides example data for people, cell styles, rows, columns, and cells. It includes functions to generate rows, columns, and cells, along with an example React component `ReactGridExample` that utilizes these definitions and the `styleRanges` prop to render a grid with styled areas. ```typescript type StyledRange = { styles: React.CSSProperties; range: Range; }; type Range = { start: { rowIndex: number; columnIndex: number; }; end: { rowIndex: number; columnIndex: number; }; }; const peopleData = [ { id: "66d61077035753f369ddbb16", name: "Jordan Rodriquez", age: 30, email: "jordanrodriquez@cincyr.com", company: "Zaggles", }, { id: "66d61077794e7949ab167fd5", email: "allysonrios@satiance.com", name: "Allyson Rios", age: 30, company: "Zoxy", }, { id: "66d61077dd754e88981ae434", name: "Pickett Lucas", age: 25, email: "pickettlucas@zoxy.com", company: "Techade", }, { id: "66d61077115e2f8748c334d9", name: "Louella David", age: 37, email: "louelladavid@techade.com", company: "Ginkogene", }, { id: "66d61077540d53374b427e4b", name: "Tricia Greene", age: 27, email: "triciagreene@ginkogene.com", company: "Naxdis", }, ]; const cellStyles = { header: { backgroundColor: "#55bc71", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: "bold", }, }; const getRows = (people: Person[]): Row[] => [ // header row { rowIndex: 0, height: 40, }, // data rows ...people.map((_, i) => ({ rowIndex: i + 1, height: 40, })), ]; const getColumns = (): Column[] => [ { colIndex: 0, width: 220 }, { colIndex: 1, width: 220 }, { colIndex: 2, width: 220 }, { colIndex: 3, width: 220 }, ]; type UpdatePerson = (id: string, key: string, newValue: T) => void; const generateCells = (people: Person[], updatePerson: UpdatePerson): Cell[] => { const generateHeaderCells = () => { const titles = ["Name", "Age", "Email", "Company"]; return titles.map((title, colIndex) => ({ rowIndex: 0, colIndex, Template: NonEditableCell, props: { value: title, style: cellStyles.header, }, })); }; const generateRowCells = (rowIndex: number, person: Person): Cell[] => { const { id, name, age, email, company } = person; return [ { rowIndex, colIndex: 0, Template: TextCell, props: { text: name, onTextChanged: (newText: string) => updatePerson(id, "name", newText), }, }, { rowIndex, colIndex: 1, Template: NumberCell, props: { value: age, onValueChanged: (newValue: number) => updatePerson(id, "age", newValue), }, }, { rowIndex, colIndex: 2, Template: TextCell, props: { text: email, onTextChanged: (newText: string) => updatePerson(id, "email", newText), }, }, { rowIndex, colIndex: 3, Template: TextCell, props: { text: company, onTextChanged: (newText: string) => updatePerson(id, "company", newText), }, }, ]; }; const headerCells = generateHeaderCells(); const rowCells = people.flatMap((person, idx) => generateRowCells(idx + 1, person)); return [...headerCells, ...rowCells]; }; const ReactGridExample = () => { const [people, setPeople] = useState(peopleData); const updatePerson = (id, key, newValue) => { setPeople((prev) => { return prev.map((p) => (p.id === id ? { ...p, [key]: newValue } : p)); }); }; const rows = getRows(people); const [columns, setColumns] = useState(getColumns()); const cells = generateCells(people, updatePerson); return (
); }; const styledRanges = [ { range: { start: { rowIndex: 3, columnIndex: 2 }, end: { rowIndex: 5, columnIndex: 3 } }, styles: { background: "red", color: "white" }, }, ]; render(, document.getElementById("root")); ``` -------------------------------- ### React Grid 5.0: Custom Fill Handle Logic Source: https://silevis.github.io/reactgrid/docs/5.0/2-implementing-core-features/5-fill-handle This JavaScript code defines the data structures and logic for a React Grid example that customizes the fill handle behavior. It includes data for people, cell styling, row and column configurations, and functions to generate cells. The 'handleFill' function is the key part, allowing custom actions when the fill handle is used. ```javascript const peopleData = [ { id: "66d61077035753f369ddbb16", name: "Jordan Rodriquez", age: 30, email: "jordanrodriquez@cincyr.com", company: "Zaggles", }, { id: "66d61077794e7949ab167fd5", email: "allysonrios@satiance.com", name: "Allyson Rios", age: 30, company: "Zoxy", }, { id: "66d61077dd754e88981ae434", name: "Pickett Lucas", age: 25, email: "pickettlucas@zoxy.com", company: "Techade", }, { id: "66d61077115e2f8748c334d9", name: "Louella David", age: 37, email: "louelladavid@techade.com", company: "Ginkogene", }, { id: "66d61077540d53374b427e4b", name: "Tricia Greene", age: 27, email: "triciagreene@ginkogene.com", company: "Naxdis", }, ]; const cellStyles = { header: { backgroundColor: "#55bc71", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: "bold", }, }; const getRows = (people: Person[]): Row[] => [ // header row { rowIndex: 0, height: 40, }, // data rows ...people.map((_, i) => ({ rowIndex: i + 1, height: 40, })), ]; const getColumns = (): Column[] => [ { colIndex: 0, width: 220 }, { colIndex: 1, width: 220 }, { colIndex: 2, width: 220 }, { colIndex: 3, width: 220 }, ]; type UpdatePerson = (id: string, key: string, newValue: T) => void; const generateCells = (people: Person[], updatePerson: UpdatePerson): Cell[] => { const generateHeaderCells = () => { const titles = ["Name", "Age", "Email", "Company"]; return titles.map((title, colIndex) => ({ rowIndex: 0, colIndex, Template: NonEditableCell, props: { value: title, style: cellStyles.header, }, })); }; const generateRowCells = (rowIndex: number, person: Person): Cell[] => { const { id, name, age, email, company } = person; return [ { rowIndex, colIndex: 0, Template: TextCell, props: { text: name, onTextChanged: (newText: string) => updatePerson(id, "name", newText), }, }, { rowIndex, colIndex: 1, Template: NumberCell, props: { value: age, onValueChanged: (newValue: number) => updatePerson(id, "age", newValue), }, }, { rowIndex, colIndex: 2, Template: TextCell, props: { text: email, onTextChanged: (newText: string) => updatePerson(id, "email", newText), }, }, { rowIndex, colIndex: 3, Template: TextCell, props: { text: company, onTextChanged: (newText: string) => updatePerson(id, "company", newText), }, }, ]; }; const headerCells = generateHeaderCells(); const rowCells = people.flatMap((person, idx) => generateRowCells(idx + 1, person)); return [...headerCells, ...rowCells]; }; const ReactGridExample = () => { const [people, setPeople] = useState(peopleData); const updatePerson = (id, key, newValue) => { setPeople((prev) => { return prev.map((p) => (p.id === id ? { ...p, [key]: newValue } : p)); }); }; const rows = getRows(people); const [columns, setColumns] = useState(getColumns()); const cells = generateCells(people, updatePerson); return (
); }; const handleFill = ( selectedArea: NumericalRange, fillRange: NumericalRange, cellsLookup: CellsLookup ): boolean => { // Check if the fill handle is being dragged upwards const isFillingUpwards = fillRange.startRowIdx < selectedArea.startRowIdx; // Calculate the number of rows and columns in the selected area const relativeRowSize = selectedArea.endRowIdx - selectedArea.startRowIdx; const relativeColSize = selectedArea.endColIdx - selectedArea.startColIdx; // Iterate over the rows and columns in the fill range for (let i = fillRange.startRowIdx; i < fillRange.endRowIdx; i++) { for (let j = fillRange.startColIdx; j < fillRange.endColIdx; j++) { const currentCellCallbacks = cellsLookup.get(`${i} ${j}`); if (!currentCellCallbacks) continue; // Skip cells of type 'header' if (i === 0) continue; // Calculate the relative row and column indices within the selected area const relativeRowIdx = isFillingUpwards ? (selectedArea.endRowIdx - i - 1) % relativeRowSize : (i - fillRange.startRowIdx) % relativeRowSize; const relativeColIdx = (j - fillRange.startColIdx) % relativeColSize; // Get the value from the cell in the selected area that corresponds to the relative row and column indices const sourceCellCallbacks = cellsLookup.get( // This part of the code seems incomplete in the provided snippet. // It likely intends to retrieve the corresponding cell from the selected area // based on the calculated relative indices. ); // ... rest of the logic to apply values from sourceCellCallbacks to the current cell } } return true; // Indicate that the fill operation was handled }; ``` -------------------------------- ### Define ReactGrid Theme Interface (TypeScript) Source: https://silevis.github.io/reactgrid/docs/5.0/5-styling This snippet defines the `RGTheme` interface in TypeScript, outlining the structure for applying themes to ReactGrid. It specifies properties for gaps, pane containers, cell containers, areas, focus indicators, fill handles, lines, shadows, resize controls, selection indicators, and the grid wrapper. ```typescript interface RGTheme { gap: { width: React.CSSProperties["width"]; color: React.CSSProperties["color"]; }; paneContainer: { top: { background: React.CSSProperties["backgroundColor"]; boxShadow: React.CSSProperties["boxShadow"]; }; right: { background: React.CSSProperties["backgroundColor"]; boxShadow: React.CSSProperties["boxShadow"]; }; bottom: { background: React.CSSProperties["backgroundColor"]; boxShadow: React.CSSProperties["boxShadow"]; }; left: { background: React.CSSProperties["backgroundColor"]; boxShadow: React.CSSProperties["boxShadow"]; }; }; cellContainer: { padding: Padding; background: React.CSSProperties["backgroundColor"]; }; area: { border: Border; }; focusIndicator: { background: React.CSSProperties["backgroundColor"]; border: Border; }; fillHandle: { background: React.CSSProperties["backgroundColor"]; border: Border; }; line: { backgroundColor: React.CSSProperties["backgroundColor"]; size: number | string }; shadow: { backgroundColor: React.CSSProperties["backgroundColor"] }; resizeColumn: { default: React.CSSProperties; hover: React.CSSProperties; }; selectionIndicator: { background: React.CSSProperties["backgroundColor"]; border: Border; }; gridWrapper: React.CSSProperties; } ``` -------------------------------- ### React Custom Cell Template with CellWrapper Source: https://silevis.github.io/reactgrid/docs/5.0/4-create-your-own-cell-template Example of integrating a custom cell template with ReactGrid's `CellWrapper`. The `CellWrapper` handles communication for cell values using `onStringValueRequested` and `onStringValueReceived` props. It allows rendering custom cell content within the provided children. ```jsx value?.toString() || ""} onStringValueReceived={() => { // Logic to update the cell value during operations like cut, copy, paste or fill }}> {/* Render cell content here */} ``` -------------------------------- ### Implement Sticky Left Columns in ReactGrid Source: https://silevis.github.io/reactgrid/docs/5.0/2-implementing-core-features/4-sticky This example demonstrates how to implement sticky left columns in a ReactGrid component. It utilizes the `stickyLeftColumns` property to fix a specified number of columns to the left side of the grid. This is useful for keeping identifier columns or critical data visible while scrolling horizontally. ```javascript const ReactGridExample = () => { const [people, setPeople] = useState(peopleData); const updatePerson = (id, key, newValue) => { setPeople((prev) => { return prev.map((p) => (p.id === id ? { ...p, [key]: newValue } : p)); }); }; const rows = getRows(people); const [columns, setColumns] = useState(getColumns()); const cells = generateCells(people, updatePerson); return (
); }; render(, document.getElementById("root")); ``` -------------------------------- ### ReactGrid Component Integration (JavaScript) Source: https://silevis.github.io/reactgrid/docs/5.0/5-styling This JavaScript code defines a React functional component that integrates the ReactGrid. It manages the state of the people data, provides an update function, and renders the ReactGrid with defined rows, columns, and cells. It also includes custom styles for the grid's appearance. ```javascript const ReactGridExample = () => { const [people, setPeople] = useState(peopleData); const updatePerson = (id, key, newValue) => { setPeople((prev) => { return prev.map((p) => (p.id === id ? { ...p, [key]: newValue } : p)); }); }; const rows = getRows(people); const columns = getColumns(); const cells = generateCells(people, updatePerson); return (
); }; const rgStyles = { focusIndicator: { border: { color: "#32a852", width: "2px", style: "solid", }, }, selectionIndicator: { background: "rgba(144, 238, 144, 0.1)", border: { color: "#81df9b", style: "solid", }, }, fillHandle: { background: "transparent", border: { color: "#32a852", style: "dashed", }, }, gridWrapper: { fontSize: 16, fontFamily: "Roboto, sans-serif", }, }; render(, document.getElementById("root")); ``` -------------------------------- ### Set Initial Focus Location in ReactGrid Component Source: https://silevis.github.io/reactgrid/docs/5.0/2-implementing-core-features/1-initial-focus-location Configure the initial focus location for the ReactGrid component by setting the `initialFocusLocation` property. This property accepts an object with `rowIndex` and `colIndex` to define the starting focused cell. No external dependencies are required beyond the ReactGrid component itself. ```jsx ``` -------------------------------- ### Interact with ReactGrid using useReactGridAPI Hook (TypeScript) Source: https://silevis.github.io/reactgrid/docs/5.0/6-api/2-hooks/1-usereactgridapi The `useReactGridAPI` hook allows programmatic interaction with the ReactGrid component. It provides methods to set and get grid states such as selected areas, focused cells, and selected rows/columns. This hook is crucial for dynamic grid state management. ```typescript function useReactGridAPI(id: string): ReactGridAPI | undefined { return useReactGridStoreApi(id, (store: ReactGridStore) => { return { // Setters setSelectedArea: (range: NumericalRange) => { return store.setSelectedArea(range); }, setFocusedCell: ({ rowIndex, colIndex }: IndexedLocation) => { const cell = store.getCellByIndexes(rowIndex, colIndex); if (devEnvironment && !cell) { console.warn(`Cell with rowIdx "${rowIndex}" and colIdx "${colIndex}" does not exist.`); } return store.setFocusedLocation(rowIndex, colIndex); }, setSelectedColumns: (startColIdx: number, endColIdx: number) => { return store.setSelectedColumns(startColIdx, endColIdx); }, setSelectedRows: (startRowIdx: number, endRowIdx: number) => { return store.setSelectedRows(startRowIdx, endRowIdx); }, // Getters getFocusedCell: store.getFocusedCell, getCellByIndexes: store.getCellByIndexes, getCellOrSpanMemberByIndexes: store.getCellOrSpanMemberByIndexes, getPaneRanges: store.getPaneRanges, getCellsLookup: store.getCellsLookup, getSelectedArea: store.getSelectedArea, getRows: () => store.rows, getColumns: () => store.columns, }; }); } ``` -------------------------------- ### NumericalRange Type Source: https://silevis.github.io/reactgrid/docs/5.0/6-api/1-types/6-numerical-range Defines a range within the grid using start and end row and column indices. ```APIDOC ## Type: NumericalRange ### Description Defines a rectangular range within the grid by specifying the starting and ending row and column indices. ### Properties #### `startRowIdx` * **Type**: `number` * **Description**: The starting row index of the range. #### `endRowIdx` * **Type**: `number` * **Description**: The ending row index of the range. #### `startColIdx` * **Type**: `number` * **Description**: The starting column index of the range. #### `endColIdx` * **Type**: `number` * **Description**: The ending column index of the range. ### Example ```json { "startRowIdx": 0, "endRowIdx": 5, "startColIdx": 0, "endColIdx": 3 } ``` ``` -------------------------------- ### Fill Handle Configuration Source: https://silevis.github.io/reactgrid/docs/5.0/2-implementing-core-features/5-fill-handle Details on configuring the fill handle, including disabling it and implementing custom behavior. ```APIDOC ## ReactGrid Fill Handle API ### Description The fill handle is a feature in ReactGrid that allows users to easily copy cell values across a range. It is enabled by default but can be customized or disabled. ### Method Configuration via component props. ### Endpoint `ReactGrid` component #### Parameters ##### Component Props - **`disableFillHandle`** (boolean) - Optional - If set to `true`, the fill handle will be disabled. - **`onFillHandle`** (function) - Optional - A callback function to implement custom fill handle logic. It receives `selectedArea`, `fillRange`, and `cellsLookup` as arguments and should return a boolean to control the default behavior. #### `onFillHandle` Parameters - **`selectedArea`** (`NumericalRange`) - Required - The range of cells that were initially selected. - **`fillRange`** (`NumericalRange`) - Required - The range of cells that the fill handle is dragged over. - **`cellsLookup`** (`CellsLookup`) - Required - An object providing callbacks to get and set cell values. It maps cell coordinates (e.g., '0-0') to objects containing `rowIndex`, `colIndex`, `onStringValueRequested`, and `onStringValueReceived`. #### Return Value for `onFillHandle` - **`true`** (`boolean`) - Prevents the default fill handle behavior. - **`false`** (`boolean`) - Allows the default fill handle behavior to proceed, potentially after custom actions. ### Request Example ```javascript { console.log('Custom fill handle logic triggered'); // Implement custom logic here return true; // Prevent default behavior }} /> ``` ### Response #### Success Response (Configuration Applied) - **`disableFillHandle`** (boolean) - Indicates if the fill handle is disabled. - **`onFillHandle`** (function) - The custom handler function, if provided. #### Response Example (No direct response, configuration is applied to the component's behavior) * * * ``` -------------------------------- ### Define StyledRange and Range Types in TypeScript Source: https://silevis.github.io/reactgrid/docs/5.0/6-api/1-types/7-styled-range This snippet defines the TypeScript types for StyledRange and Range. StyledRange includes CSS properties and a Range object, while Range specifies the start and end points of a cell selection. ```typescript type StyledRange = { styles: React.CSSProperties; range: Range; }; type Range = { start: { rowIndex: number; columnIndex: number; }; end: { rowIndex: number; columnIndex: number; }; }; ``` -------------------------------- ### Define NumericalRange Type in TypeScript Source: https://silevis.github.io/reactgrid/docs/5.0/6-api/1-types/6-numerical-range This TypeScript code defines the NumericalRange type, specifying the start and end row and column indices for a grid range. It is a core type for defining selections or areas within the ReactGrid component. ```typescript type NumericalRange = { startRowIdx: number; endRowIdx: number; startColIdx: number; endColIdx: number; }; ``` -------------------------------- ### ReactGrid Callbacks Source: https://silevis.github.io/reactgrid/docs/5.0/6-api/0-interfaces/1-reactgrid-props This section details the available callbacks for the ReactGrid component, which allow you to hook into various user interactions and events. ```APIDOC ## ReactGrid Callbacks This section details the available callbacks for the ReactGrid component, which allow you to hook into various user interactions and events. ### onAreaSelected * **Description**: Callback when an area is selected. * **Type**: `(selectedArea: NumericalRange) => void` ### onCellFocused * **Description**: Callback when a cell is focused. * **Type**: `(cellLocation: IndexedLocation) => void` ### onFocusLocationChanging * **Description**: Callback before focus location changes. Returning `false` will prevent the focus change. * **Type**: `({ location }: { location: IndexedLocation }) => boolean` ### onFocusLocationChanged * **Description**: Callback after focus location changes. * **Type**: `({ location }: { location: IndexedLocation }) => void` ### onFillHandle * **Description**: Callback for fill handle action. Returning `false` will prevent the fill operation. * **Type**: `(selectedArea: NumericalRange, fillRange: NumericalRange, cellsLookup: CellsLookup) => boolean` ### onCut * **Description**: Callback for cut action. Returning `false` will prevent the cut operation. * **Type**: `(event: React.ClipboardEvent, cellsRange: NumericalRange, cellsLookup: CellsLookup) => boolean` ### onCopy * **Description**: Callback for copy action. Returning `false` will prevent the copy operation. * **Type**: `(event: React.ClipboardEvent, cellsRange: NumericalRange, cellsLookup: CellsLookup) => boolean` ### onPaste * **Description**: Callback for paste action. Returning `false` will prevent the paste operation. * **Type**: `(event: React.ClipboardEvent, cellsRange: NumericalRange, cellsLookup: CellsLookup) => boolean` ### onColumnReorder * **Description**: Callback for column reorder action. * **Type**: `(selectedColIndexes: number[], destinationColIdx: number) => void` ### onRowReorder * **Description**: Callback for row reorder action. * **Type**: `(selectedRowIndexes: number[], destinationRowIdx: number) => void` ### onResizeColumn * **Description**: Callback for column resize action. * **Type**: `(width: number, columnIdx: number[]) => void` ``` -------------------------------- ### ReactGrid Component Integration (JavaScript) Source: https://silevis.github.io/reactgrid/docs/5.0/2-implementing-core-features/3-column-resizing This snippet shows the main React component `ReactGridExample` that utilizes the `ReactGrid` component. It manages the state of the people data, handles column resizing, and renders the grid with the generated rows, columns, and cells. ```javascript const ReactGridExample = () => { const [people, setPeople] = useState(peopleData); const updatePerson = (id, key, newValue) => { setPeople((prev) => { return prev.map((p) => (p.id === id ? { ...p, [key]: newValue } : p)); }); }; const rows = getRows(people); const [columns, setColumns] = useState(getColumns()); const cells = generateCells(people, updatePerson); return (
handleResizeColumn(width, columnIdx, setColumns)} cells={cells} />
); }; const handleResizeColumn = ( newWidth: number, columnIndexes: number[], setColumns: Dispatch> ) => { setColumns((prevColumns) => { // If resizing spans multiple columns (e.g., header cells with colSpan > 1), divide the new width by the number of columns const newWidthPerColumn = columnIndexes.length > 1 ? newWidth / columnIndexes.length : newWidth; return prevColumns.map((column, idx) => { if (columnIndexes.includes(idx)) { return { ...column, width: newWidthPerColumn }; } return column; }); }); }; render(, document.getElementById("root")); ``` -------------------------------- ### ReactGrid Fill Handle Configuration Source: https://silevis.github.io/reactgrid/docs/5.0/2-implementing-core-features/5-fill-handle Demonstrates how to configure the fill handle in ReactGrid. The `disableFillHandle` prop can be used to turn off the feature, while the `onFillHandle` prop allows for custom logic implementation. The `onFillHandle` prop accepts parameters for the selected area, fill range, and a cell lookup object, returning a boolean to control default behavior. ```typescript onFillHandle?: (selectedArea: NumericalRange, fillRange: NumericalRange, cellsLookup: CellsLookup) => boolean; ```