Socket
Book a DemoInstallSign in
Socket

react-native-kanban-board

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-native-kanban-board

Kanban board for React-Native apps. No native code. Can be used with expo.

1.0.1
latest
Source
npmnpm
Version published
Weekly downloads
2
100%
Maintainers
1
Weekly downloads
 
Created
Source

react-native-kanban-board

Kanban board for React-Native apps

A performant and customizable Kanban board component for React Native, enabling drag and drop functionality between stages. Built with React Native Reanimated for smooth animations and gestures.

npm version License: MIT

https://github.com/user-attachments/assets/6b92c787-76c4-4c91-9c8a-947149f457f3


Features

  • Drag and Drop: Smoothly drag and drop items between different stages (columns).
  • Horizontal Stage Scrolling: Easily navigate through multiple stages with horizontal scrolling and snapping.
  • Customizable Stages: Define your own stages with custom headers and data.
  • Customizable Items: Render your items with a custom component.
  • Stage Width Control: Adjust the width of individual stages.
  • Gap Between Stages: Control the spacing between stages.
  • Drag Hover Styling: Style the stage when an item is being dragged over it.
  • onDragEnd Callback: Get notified when an item is dropped into a new stage, providing information about the source and destination.
  • Built with Reanimated: Utilizes React Native Reanimated for fluid and performant animations.

Installation

npm install react-native-kanban-board

or

yarn add react-native-kanban-board

Props

PropTypeDescriptionDefault ValueRequired
stagesStage<T extends ItemType, K>[]An array of stage objects, each containing a header of type K and an array of items of type T.[]Yes
renderItem(props: T, isDragged?: boolean) => JSX.ElementFunction that renders each item within a stage. isDragged is a boolean indicating if the item is being dragged.Yes
renderHeader(props: K) => JSX.ElementFunction that renders the header for each stage.Yes
onDragEnd(params: { fromStageIndex: number; toStageIndex: number; itemId: string }) => voidCallback function called when an item is dropped into a new stage, providing the source and destination stage indices and the item's ID.undefinedYes
containerStyleViewStyleStyle for the outer container of the Kanban board component.{}No
contentContainerStyleViewStyleStyle for the content container of the horizontal FlatList that renders the stages.{}No
stageContainerStyleViewStyleStyle for the container of each individual stage.{}No
stageContainerStyleOnDragHoverViewStyleStyle applied to a stage container when an item is being dragged over it.{ opacity: 0.7 }No
stageWidthnumberThe width of each stage container. Defaults to 80% of the screen's width.SCREEN_WIDTH * 0.8No
gapBetweenStagesnumberThe horizontal gap between the stages. Defaults to 12.12No

Type Definitions:

import type { StyleProp, ViewStyle } from 'react-native';

export type ItemType = {
  id: string | number;
  [key: string]: any;
};

export type Stage<T extends ItemType, K> = {
  header: K;
  items: T[];
};

export type KanbanBoardProps<T extends ItemType, K> = {
  stages: Stage<T, K>[];
  renderItem: (item: T, isDragged?: boolean) => React.ReactNode;
  renderHeader: (header: K) => React.ReactNode;
  stageContainerStyle?: StyleProp<ViewStyle>;
  gapBetweenStages?: number;
  stageWidth?: number;
  stageContainerStyleOnDragHover?: StyleProp<ViewStyle>;
  onDragEnd?: ({ fromStageIndex: number, toStageIndex: number, itemId: string }) => void;
  contentContainerStyle?: StyleProp<ViewStyle>;
  containerStyle?: StyleProp<ViewStyle>;
};

Example Usage (Complete)

import React from 'react';
import { Dimensions, StyleSheet, Button, View, Text } from 'react-native';
import KanbanBoard from 'react-native-kanban-board';
import { type KanbanBoardProps } from 'react-native-kanban-board/shared/types';

const SCREEN_WIDTH = Dimensions.get('screen').width;

type HeaderParams = {
  title: string;
  subtitle?: string;
};

type ItemParams = {
  id: string;
};

const KanbanBoardExample = () => {
  const [stageWidth, setStageWidth] = React.useState(SCREEN_WIDTH * .75);

  const renderItem = (props: ItemParams, isDragged?: boolean) => {
    return (
      <View style={[styles.itemContainer, { backgroundColor: isDragged ? 'rgb(150, 170, 180)' : 'rgb(255,255,255)' }]}>
        <Text>{props.id}</Text>
      </View>
    );
  };

  const renderHeader = (props: HeaderParams) => {
    return (
      <View>
        <Text style={{ fontWeight: 'bold' }}>{props.title}</Text>
        {props.subtitle && <Text>{props.subtitle}</Text>}
      </View>
    );
  };

  const stages: KanbanBoardProps<ItemParams, HeaderParams>['stages'] = [
    {
      header: { title: 'Stage 1' },
      items: [{ id: '1' }, { id: '2' }, { id: '3' }, { id: '4' }, { id: '5' }],
    },
    {
      header: { title: 'Stage 2', subtitle: 'with subtitle 22' },
      items: [{ id: '6' }, { id: '7' }, { id: '8' }, { id: '9' }, { id: '10' }],
    },
    {
      header: { title: 'Stageee 3', subtitle: 'with subtitle 333' },
      items: [{ id: '11' }, { id: '12' }, { id: '13' }, { id: '14' }, { id: '15' }],
    },
    {
      header: { title: 'Stage 4' },
      items: [{ id: '16' }, { id: '17' }, { id: '18' }, { id: '19' }, { id: '20' }],
    },
    {
      header: { title: 'Stage 5', subtitle: 'with subtitle 55555' },
      items: [{ id: '21' }, { id: '22' }, { id: '23' }, { id: '24' }, { id: '25' }, { id: '26' }, { id: '27' }, { id: '28' }, { id: '29' }, { id: '30' }, { id: '31' }, { id: '32' }, { id: '33' }, { id: '34' }, { id: '35' }],
    },
  ];

  const onDragEnd = ({ fromStageIndex, toStageIndex, itemId }: { fromStageIndex: number; toStageIndex: number; itemId: string }) => {
    alert(`from stage: ${fromStageIndex} \n to stage: ${toStageIndex}\n item id: ${itemId}`);
  };

  return (
    <>
      <Button title='switch' onPress={() => setStageWidth(curr => SCREEN_WIDTH * 1.4 - curr)} />
      <KanbanBoard
        stages={stages}
        renderItem={renderItem}
        renderHeader={renderHeader}
        stageContainerStyle={styles.stageContainer}
        gapBetweenStages={10}
        stageWidth={stageWidth}
        stageContainerStyleOnDragHover={styles.stageContainerWhenPotenialDragTo}
        onDragEnd={onDragEnd}
      />
    </>
  );
};

const styles = StyleSheet.create({
  stageContainer: {
    backgroundColor: 'blue',
    borderRadius: 12,
    padding: 10,
  },
  dragItem: {
    backgroundColor: 'yellow',
  },
  stageContainerWhenPotenialDragTo: {
    opacity: .7,
  },
  itemContainer: {
    paddingVertical: 10,
    marginVertical: 10,
    justifyContent: 'center',
    alignItems: 'center'
  }
});

export default KanbanBoardExample;

Contributing

Contributions are welcome! Please open a PR so I'll review before merging.

License

MIT

Keywords

react-native

FAQs

Package last updated on 19 May 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.