Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion packages/core/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ Most data grids will want to set the majority of these props one way or another.

| Name | Description |
| ---------------------------------- | ------------------------------------------------------ |
| [customRenderers](#customRenderer) | FIXME |
| [customRenderers](#customRenderer) | Custom renderers for `GridCellKind.Custom`. |
| [renderers](#renderers) | Overrides built-in cell renderers. |
| [drawCell](#drawcell) | Callback used to override the rendering of any cell. |
| [drawHeader](#drawheader) | Callback used to override the rendering of any header. |

Expand Down Expand Up @@ -728,6 +729,16 @@ It is possible to return `false` after rendering just a background and the regul

---

## renderers

```ts
readonly renderers?: readonly InternalCellRenderer<InnerGridCell>[];
```

An array of cell renderers used when drawing built-in cell types. Provide this prop to override default cell renderers. If omitted, `AllCellRenderers` is used.

---

## getGroupDetails

```ts
Expand Down
8 changes: 6 additions & 2 deletions packages/core/src/data-editor-all.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { sprites } from "./internal/data-grid/sprites.js";
import ImageWindowLoaderImpl from "./common/image-window-loader.js";
import type { ImageWindowLoader } from "./internal/data-grid/image-window-loader-interface.js";

export interface DataEditorAllProps extends Omit<DataEditorProps, "renderers" | "imageWindowLoader"> {
export interface DataEditorAllProps extends Omit<DataEditorProps, "imageWindowLoader"> {
imageWindowLoader?: ImageWindowLoader;
}

Expand All @@ -14,14 +14,18 @@ const DataEditorAllImpl: React.ForwardRefRenderFunction<DataEditorRef, DataEdito
return { ...sprites, ...p.headerIcons };
}, [p.headerIcons]);

const renderers = React.useMemo(() => {
return p.renderers ?? AllCellRenderers;
}, [p.renderers])

const imageWindowLoader = React.useMemo(() => {
return p.imageWindowLoader ?? new ImageWindowLoaderImpl();
}, [p.imageWindowLoader]);

return (
<DataEditor
{...p}
renderers={AllCellRenderers}
renderers={renderers}
headerIcons={allSprites}
ref={ref}
imageWindowLoader={imageWindowLoader}
Expand Down
67 changes: 67 additions & 0 deletions packages/core/src/docs/examples/custom-renderers.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React from "react";
import { DataEditorAll as DataEditor } from "../../data-editor-all.js";
import {
BeautifulWrapper,
Description,
PropName,
defaultProps,
useMockDataGenerator,
} from "../../data-editor/stories/utils.js";
import { SimpleThemeWrapper } from "../../stories/story-utils.js";
import {
markerCellRenderer,
AllCellRenderers,
type InternalCellRenderer,
type InnerGridCell,
} from "../../index.js";

export default {
title: "Glide-Data-Grid/DataEditor Demos",
decorators: [
(Story: React.ComponentType) => (
<SimpleThemeWrapper>
<BeautifulWrapper
title="Custom renderers"
description={
<Description>
Override internal cell renderers by passing the {" "}
<PropName>renderers</PropName> prop.
</Description>
}
>
<Story />
</BeautifulWrapper>
</SimpleThemeWrapper>
),
],
};

export const OverrideMarkerRenderer: React.VFC = () => {
const { cols, getCellContent } = useMockDataGenerator(100, true, true);

const renderers = React.useMemo<readonly InternalCellRenderer<InnerGridCell>[]>(() => {
return [
...AllCellRenderers,
{
...markerCellRenderer,
draw: args => {
const { ctx, rect } = args;
ctx.fillStyle = "#ffe0e0";
ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
markerCellRenderer.draw(args as any);
},
} as InternalCellRenderer<InnerGridCell>,
];
}, []);

return (
<DataEditor
{...defaultProps}
getCellContent={getCellContent}
columns={cols}
rows={200}
rowMarkers="both"
renderers={renderers}
/>
);
};
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export { markerCellRenderer } from "./cells/marker-cell.js";
export { bubbleCellRenderer } from "./cells/bubble-cell.js";
export { protectedCellRenderer } from "./cells/protected-cell.js";
export { rowIDCellRenderer } from "./cells/row-id-cell.js";
export type { InternalCellRenderer } from "./cells/cell-types.js";
export { AllCellRenderers } from "./cells/index.js";
export { sprites } from "./internal/data-grid/sprites.js";
export { default as ImageWindowLoaderImpl } from "./common/image-window-loader.js";
Expand Down
28 changes: 28 additions & 0 deletions packages/core/test/data-editor.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import {
GridCellKind,
isSizedGridColumn,
type Item,
markerCellRenderer,
type InnerGridCell,
type InternalCellRenderer,
AllCellRenderers,
} from "../src/index.js";
import type { CustomCell } from "../src/internal/data-grid/data-grid-types.js";
import type { DataEditorRef } from "../src/data-editor/data-editor.js";
Expand Down Expand Up @@ -2572,6 +2576,30 @@ describe("data-editor", () => {
expect(onClickSpy).not.toBeCalled();
});

test("renderers can override internal cells", async () => {
const spy = vi.fn();

vi.useFakeTimers();
render(
<DataEditor
{...basicProps}
renderers={[
...AllCellRenderers,
{
...markerCellRenderer,
draw: spy
} as InternalCellRenderer<InnerGridCell>,
]}
rowMarkers="both"
/>,
{
wrapper: Context,
}
);
prep();
expect(spy).toHaveBeenCalledTimes(31); // Math.ceil((height - headerHeight) / rowHeight)
});

test("onCellsEdited blocks onCellEdited", async () => {
const spy = vi.fn();
vi.useFakeTimers();
Expand Down
2 changes: 1 addition & 1 deletion setup-react-18-test.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/bash

npm i -D react@latest react-dom@latest @testing-library/react@latest @testing-library/react-hooks@latest @testing-library/user-event@14.5.1 react-test-renderer@latest
npm i -D react@latest react-dom@latest @testing-library/react@latest @testing-library/react-hooks@latest @testing-library/user-event@14.5.1 react-test-renderer@latest @testing-library/dom