> The code in this repository will be manually copied to the react folder of the [gridstack.js](https://github.com/gridstack/gridstack.js/tree/master/react) main repository.
npm install @iqmo/gridstack-react> The code in this repository will be manually copied to the react folder of the gridstack.js main repository.
A React wrapper component for GridStack that provides better TypeScript support and React integration experience.
Online Preview: https://gridstack-react.pages.dev/
Open in CodeSandbox
- [x] Add Widgets
- [x] Add Sub Grid
- [x] Nested Sub Grid
- [x] Remove Widget
- [x] Copy(Duplicate) Widget
- [x] Drag between two grid stacks
- [x] Custom handle (Experimental)
- [x] Drag in item (Experimental)
- [ ] Save/Load grid stack options from storage
This is not an npm package, it's just a demo project. Please copy the src/lib code to your project to use it.
Simple
Render item with widget id selector.
Code here: src/examples/000-simple/index.tsx
``tsx
function Simple() {
const [uncontrolledInitialOptions] = useState
...defaultGridOptions,
children: [
{ id: "item1", h: 2, w: 2, x: 0, y: 0 },
{ id: "item2", h: 2, w: 2, x: 2, y: 0 },
],
}));
return (
hello
grid
);
}
`
Or split the grid stack container to provide grid stack context and render component for access to grid stack context.
Code here: src/examples/001-simple/index.tsx
`tsx
function Simple() {
const [uncontrolledInitialOptions] = useState
...defaultGridOptions,
children: [
{ id: "item1", h: 2, w: 2, x: 0, y: 0 },
{ id: "item2", h: 2, w: 2, x: 2, y: 0 },
],
}));
return (
{/ Custom toolbar component. Access to grid stack context by useGridStackContext hook. /}
hello
grid
);
}
`
Drag In
Drag items from outside into the grid.
Code here: src/examples/004-drag-in/index.tsx
`tsx
function DragIn() {
const [uncontrolledInitialOptions] = useState
...defaultGridOptions,
children: [
{ id: "004-item1", h: 2, w: 2, x: 0, y: 0 },
{ id: "004-item2", h: 2, w: 2, x: 2, y: 0 },
],
}));
return (
hello
grid
Advanced
Render item with widget map component info.
_ComponentInfoMap is just an example, you can use any way you want to store and retrieve component information._
Code here: src/examples/009-advanced/index.tsx
`tsx
function Advanced() {
// Data about layout by gridstack option
const [uncontrolledInitialOptions] = useState(() => ({
...defaultGridOptions,
children: [
{ id: "item1", h: 2, w: 2, x: 0, y: 0 },
{ id: "item2", h: 2, w: 2, x: 2, y: 0 },
{
id: "sub-grid-1",
h: 5,
sizeToContent: true,
subGridOpts: {
children: [
{
id: "sub-grid-1-title",
locked: true,
noMove: true,
noResize: true,
w: 12,
x: 0,
y: 0,
content: "Sub Grid 1",
},
{ id: "item3", h: 2, w: 2, x: 0, y: 1 },
{ id: "item4", h: 2, w: 2, x: 2, y: 0 },
],
},
w: 4,
x: 0,
y: 2,
},
{ id: "item5", w: 4, h: 4, x: 0, y: 2 },
],
})); // Data about every content
const [initialComponentInfoMap] = useState>(
() => ({
item1: { component: "Text", serializableProps: { content: "Text" } },
item2: { component: "Text", serializableProps: { content: "Text" } },
"sub-grid-1-title": {
component: "Text",
serializableProps: { content: "Sub Grid 1" },
},
item3: { component: "Text", serializableProps: { content: "Text" } },
item4: {
component: "Counter",
serializableProps: { label: "Click me" },
},
item5: {
component: "ComplexCard",
serializableProps: { title: "Complex Card", color: "red" },
},
})
);
return (
);
}
function DynamicGridStackItems() {
const { componentInfoMap } = useComponentInfoMap();
return (
<>
{Array.from(componentInfoMap.entries()).map(
([widgetId, componentInfo]) => {
const Component = COMPONENT_MAP[componentInfo.component];
if (!Component) {
throw new Error(
Component ${componentInfo.component} not found);
} // eslint-disable-next-line @typescript-eslint/no-explicit-any
const props = componentInfo.serializableProps as any;
if (componentInfo.component === "ComplexCard") {
return (
key={
complex-card-editable-wrapper-${widgetId}}
serializableProps={componentInfo.serializableProps}
>
component-${widgetId}} />
);
} // ... more render conditions here
return (
component-${widgetId}} />
);
}
)}
>
);
}
`Experimental
Render item with custom handle.
Code here: src/examples/003-custom-handle/index.tsx
`tsx
function CustomHandle() {
const [uncontrolledInitialOptions] = useState(() => ({
...defaultGridOptions,
children: [{ id: "item1", h: 2, w: 2, x: 0, y: 0 }],
})); return (
Custom Handle
{/ Experimental: Render item with custom handle /}
);
}
`API Reference
$3
#### GridStackContainer
Top-level component that provides GridStack context and GridStack root container. Equivalent to
GridStackProvider and GridStackRender combined.`typescript
type GridStackContainerProps = {
initialOptions: GridStackOptions; // GridStack initialization options
children: React.ReactNode;
};
`#### GridStackProvider
Top-level component that provides GridStack context.
`typescript
type GridStackProviderProps = {
initialOptions: GridStackOptions; // GridStack initialization options
children: React.ReactNode;
};
`#### GridStackRender
Render GridStack root container component.
`typescript
type GridStackRenderProps = {
children: React.ReactNode;
};
`#### GridStackItem
Component representing a single grid item.
`typescript
type GridStackItemProps = {
id: string; // Grid item unique identifier
children: React.ReactNode;
};
`#### GridStackHandleReInitializer
Experimental component for reinitializing the drag handle of a grid item.
`typescript
type GridStackHandleReInitializerProps = {
children: React.ReactNode;
};
`#### GridStackDragInItem
Experimental component for dragging items from outside into the grid.
`typescript
type GridStackDragInItemProps = {
widget: Omit; // Widget configuration without content
dragOptions?: DDDragOpt; // Drag options
content?: ReactNode; // Optional content to render in the dragged clone
children: React.ReactNode;
// Plus other div props
};
`$3
#### GridStackContext
Provide GridStack core functionality context.
`typescript
interface GridStackContextType {
initialOptions: GridStackOptions;
addWidget: (widget: GridStackWidget) => void;
removeWidget: (el: GridStackElement) => void;
saveOptions: () => ReturnType | undefined; _gridStack: {
value: GridStack | null;
set: React.Dispatch>;
};
}
`#### GridStackItemContext
Provide single grid item functionality context.
`typescript
type GridStackItemContextType = {
id: string;
// Native methods
remove: () => void;
update: (opt: GridStackWidget) => void; // Extended methods
getBounds: () => {
current: { x?: number; y?: number; w?: number; h?: number };
original: { x?: number; y?: number; w?: number; h?: number };
} | null;
setSize: (size: { w: number; h: number }) => void;
setPosition: (position: { x: number; y: number }) => void;
};
`#### GridStackRenderContext
Provide rendering related functionality context.
`typescript
type GridStackRenderContextType = {
getContainerByWidgetId: (widgetId: string) => HTMLElement | null;
};
`$3
#### useGridStackContext
Get GridStack context.
`typescript
function useGridStackContext(): GridStackContextType;
`#### useGridStackItemContext
Get grid item context.
`typescript
function useGridStackItemContext(): GridStackItemContextType;
`#### useGridStackRenderContext
Get rendering context.
`typescript
function useGridStackRenderContext(): GridStackRenderContextType;
`$3
`typescript
export type {
GridStackContextType,
GridStackProviderProps,
GridStackRenderContextType,
GridStackRenderProps,
GridStackItemProps,
GridStackItemContextType,
GridStackHandleReInitializerProps,
GridStackDragInItemProps,
};
``