### 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;
```