Skip to content

Instantly share code, notes, and snippets.

@2n2n
Created February 25, 2020 06:05
Show Gist options
  • Save 2n2n/25a884fc9469a3694159573bd205ae1c to your computer and use it in GitHub Desktop.
Save 2n2n/25a884fc9469a3694159573bd205ae1c to your computer and use it in GitHub Desktop.
Drag and drop sample using wix/react-native-calendars and simpleDnD library.
/**
* Wix/react-native-calendars with drag and drop
* created by: anthony lloveras
* email: anthonylloveras.boxtypd@gmail.com
*/
import React, { useState } from 'react';
import faker from 'faker';
import { Calendar } from 'react-native-calendars';
import {
Animated,
SafeAreaView,
View,
Text,
} from 'react-native';
import { createDndContext } from "react-native-easy-dnd";
export const { Provider, Droppable, Draggable } = createDndContext();
/**
* This function will be responsible for generating random staffs for us.
* I used a faker library to manage all those fake data.
* You may remove this if necessary.
**/
const generateStaffs = () => {
const initialStaffs = [];
for (var i = 1; i < 10; i++) {
let randomColor = '#' + Math.floor(Math.random() * 16777215).toString(16);
initialStaffs.push({ id: i, name: faker.name.findName(), color: randomColor });
}
return initialStaffs;
}
/**
* This is our staff component.
* The staff components are the draggable items that we can drop over to our droppable area.
*/
const Staff = ({ data }) => {
return (
<Draggable
onDragStart={() => {
console.log('Started draggging');
}}
onDragEnd={() => {
console.log('Ended draggging');
}}
payload={data}
>
{({ viewProps }) => {
return (
<Animated.View
{...viewProps}
style={[viewProps.style, {
position: 'relative',
zIndex: 999999,
paddingTop: 30,
paddingBottom: 30,
paddingHorizontal: 10,
backgroundColor: "transparent",
borderColor: 'grey',
borderWidth: 1
}]}
>
<Text style={{ color: data.color, fontWeight: "bold", fontSize: 18 }}>
{data.name}
</Text>
</Animated.View>
);
}}
</Draggable>
);
}
/**
* We needed the days of every date to be droppable.
* This component will do all those work for us.
**/
const DroppableCalendarDay = (props) => {
return (
<Droppable
{...props}
>
{({ active, viewProps }) => {
return (
<View
{...viewProps}
style={[
{
padding: 30,
backgroundColor: active
? "pink"
: "white"
},
viewProps.style,
]}
>
<Text style={{ textAlign: 'center', color: 'gray'}}>
{props.data.day}
</Text>
{props.marking.hasOwnProperty('color') ? (<View style={{ backgroundColor: props.marking.color || 'transparent', height: 10, width: 10, borderRadius: 100 }}></View>): null}
</View>
)
}}
</Droppable>
);
}
/**
* The app is the main app that we will run.
* Inside this component is where we'll render all the staffs and the
* wix/react-native-calendars
*/
const App = () => {
const initialStaffs = generateStaffs();
const [markedDates, updateMarkedDates] = useState({});
const staffs = initialStaffs;
const staffList = staffs.map((data) => <Staff key={data.id} data={data} />)
return (
<Provider>
<SafeAreaView style={{ borderColor: 'grey', borderWidth: 1, display: 'flex', flex: 1, flexDirection: "row" }}>
<View
style={{ overflow: 'visible' }}
contentContainerStyle={{ flex: 1, overflow: 'visible', backgroundColor: "pink" }}
>
{ staffList }
</View>
<View style={{ flex: 1, flexBasis: "30%" }}>
<Calendar
markedDates={markedDates}
markingType={'period'}
dayComponent={({ date, state, marking }) => {
return <DroppableCalendarDay
marking={marking}
data={date}
onDrop={({ payload }) => {
let marked = markedDates;
marked[date.dateString.toString()] = { startingDay: true, endingDay: true, color: payload.color }
updateMarkedDates(JSON.parse(JSON.stringify(markedDates))); // <-- hacked way https://github.com/wix/react-native-calendars/issues/726
}}
/>
}}
/>
</View>
</SafeAreaView>
</Provider>
);
};
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment