diff --git a/src/components/Draggable.tsx b/src/components/Draggable.tsx
new file mode 100644
index 0000000..d4b6f53
--- /dev/null
+++ b/src/components/Draggable.tsx
@@ -0,0 +1,61 @@
+import React, { useRef } from "react";
+import { useDrag, useDrop } from "react-dnd";
+
+const type = "Draggable";
+
+const Draggable = ({
+ id, index, handleDrag, children,
+}) => {
+ const ref = useRef(null); // Initialize the reference
+
+ // useDrop hook is responsible for handling whether any item gets hovered or dropped on the element
+ const [, drop] = useDrop({
+ // accept receives a definition of what must be the type of the dragged item to be droppable
+ accept: type,
+ // This method is called when we hover over an element while dragging
+ hover(item: { index: number }) { // item is the dragged element
+ if (!ref.current) {
+ return;
+ }
+ const dragIndex = item.index;
+ // current element where the dragged element is hovered on
+ const hoverIndex = index;
+ // If the dragged element is hovered in the same place, then do nothing
+ if (dragIndex === hoverIndex) {
+ return;
+ }
+ // If it is dragged around other elements, then move the image and set the state with position changes
+ handleDrag(dragIndex, hoverIndex);
+ /*
+ Update the index for dragged item directly to avoid flickering
+ when the image was half dragged into the next
+ */
+ // eslint-disable-next-line no-param-reassign
+ item.index = hoverIndex;
+ },
+ });
+
+ // useDrag will be responsible for making an element draggable. It also expose, isDragging method to add any styles while dragging
+ const [{ isDragging }, drag] = useDrag(() => ({
+ // what type of item this to determine if a drop target accepts it
+ type,
+ // data of the item to be available to the drop methods
+ item: { id, index },
+ // method to collect additional data for drop handling like whether is currently being dragged
+ collect: (monitor) => ({
+ isDragging: monitor.isDragging(),
+ }),
+ }));
+
+ /*
+ Initialize drag and drop into the element using its reference.
+ Here we initialize both drag and drop on the same element (i.e., Image component)
+ */
+ drag(drop(ref));
+
+ return (
+
{children}
+ );
+};
+
+export default Draggable;
diff --git a/src/components/Widgets/SignupQuestionsWidget/QuestionList.tsx b/src/components/Widgets/SignupQuestionsWidget/QuestionList.tsx
index 1c19fc6..c61989d 100644
--- a/src/components/Widgets/SignupQuestionsWidget/QuestionList.tsx
+++ b/src/components/Widgets/SignupQuestionsWidget/QuestionList.tsx
@@ -1,6 +1,6 @@
-import React, { useRef } from "react";
-import { useDrag, useDrop } from "react-dnd";
+import React from "react";
import styled from "styled-components";
+import Draggable from "@components/Draggable";
import colors from "@theme/colors";
import { SignupFormQuestion } from "@models/Signup";
import { Lang } from "../../../i18n";
@@ -8,63 +8,6 @@ import OptionsWidget from "./OptionsWidget";
import TypeWidget from "./TypeWidget";
import QuestionElement from "./Question";
-const type = "Draggable";
-
-const Draggable = ({
- id, index, handleDrag, children,
-}) => {
- const ref = useRef(null); // Initialize the reference
-
- // useDrop hook is responsible for handling whether any item gets hovered or dropped on the element
- const [, drop] = useDrop({
- // accept receives a definition of what must be the type of the dragged item to be droppable
- accept: type,
- // This method is called when we hover over an element while dragging
- hover(item: any) { // item is the dragged element
- if (!ref.current) {
- return;
- }
- const dragIndex = item.index;
- // current element where the dragged element is hovered on
- const hoverIndex = index;
- // If the dragged element is hovered in the same place, then do nothing
- if (dragIndex === hoverIndex) {
- return;
- }
- // If it is dragged around other elements, then move the image and set the state with position changes
- handleDrag(dragIndex, hoverIndex);
- /*
- Update the index for dragged item directly to avoid flickering
- when the image was half dragged into the next
- */
- // eslint-disable-next-line no-param-reassign
- item.index = hoverIndex;
- },
- });
-
- // useDrag will be responsible for making an element draggable. It also expose, isDragging method to add any styles while dragging
- const [{ isDragging }, drag] = useDrag(() => ({
- // what type of item this to determine if a drop target accepts it
- type,
- // data of the item to be available to the drop methods
- item: { id, index },
- // method to collect additional data for drop handling like whether is currently being dragged
- collect: (monitor) => ({
- isDragging: monitor.isDragging(),
- }),
- }));
-
- /*
- Initialize drag and drop into the element using its reference.
- Here we initialize both drag and drop on the same element (i.e., Image component)
- */
- drag(drop(ref));
-
- return (
- {children}
- );
-};
-
const WidgetRow = styled(Draggable)`
margin-bottom: 1rem;
display: flex;
diff --git a/src/components/Widgets/SignupQuestionsWidget/SignupQuestionsWidget.tsx b/src/components/Widgets/SignupQuestionsWidget/SignupQuestionsWidget.tsx
index 42b4f79..995ee3e 100644
--- a/src/components/Widgets/SignupQuestionsWidget/SignupQuestionsWidget.tsx
+++ b/src/components/Widgets/SignupQuestionsWidget/SignupQuestionsWidget.tsx
@@ -1,7 +1,4 @@
import React from "react";
-import { DndProvider } from "react-dnd";
-import { HTML5Backend } from "react-dnd-html5-backend";
-import { TouchBackend } from "react-dnd-touch-backend";
import styled from "styled-components";
import shortid from "shortid";
import colors from "@theme/colors";
@@ -63,25 +60,12 @@ const SignupQuestionsWidget: React.FC = ({ value, on
const questions: SignupFormQuestion[] = JSON.parse(value);
- // simple way to check whether the device support touch (it doesn't check all fallback, it supports only modern browsers)
- const isTouchDevice = () => {
- if ("ontouchstart" in window) {
- return true;
- }
- return false;
- };
-
- // Assigning backend based on touch support on the device
- const backendForDND = isTouchDevice() ? TouchBackend : HTML5Backend;
-
return (
-
-
-
+
New Question
diff --git a/src/hooks/useIsTouchDevice.ts b/src/hooks/useIsTouchDevice.ts
new file mode 100644
index 0000000..5879303
--- /dev/null
+++ b/src/hooks/useIsTouchDevice.ts
@@ -0,0 +1,14 @@
+import { useEffect, useState } from "react";
+
+const useIsTouchDevice = () => {
+ const [isTouchDevice, setTouchDevice] = useState(false);
+ useEffect(() => {
+ // simple way to check whether the device support touch (it doesn't check all fallback, it supports only modern browsers)
+ if (window !== undefined && "ontouchstart" in window) {
+ setTouchDevice(true);
+ }
+ }, []);
+ return isTouchDevice;
+};
+
+export default useIsTouchDevice;
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index 2638a73..2ccafd8 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -1,4 +1,7 @@
import React from "react";
+import { DndProvider } from "react-dnd";
+import { HTML5Backend } from "react-dnd-html5-backend";
+import { TouchBackend } from "react-dnd-touch-backend";
import Head from "next/head";
import { AppProps } from "next/app";
import styled, { createGlobalStyle } from "styled-components";
@@ -10,6 +13,7 @@ import "react-mde/lib/styles/css/react-mde-all.css";
import "react-toastify/dist/ReactToastify.css";
import "normalize.css";
+import useIsTouchDevice from "@hooks/useIsTouchDevice";
import LocaleStore from "../i18n";
const fontFamily = "'Montserrat', sans-serif";
@@ -128,27 +132,35 @@ const AppContainer = styled.div`
background-color: ${colors.white};
`;
-const Web20App = ({ Component, pageProps }: AppProps): JSX.Element => (
- <>
-
-
-
-
- Aalto-yliopiston Sähköinsinöörikilta ry
-
-
-
-
-
-
-
-
-
-
- >
-);
+const Web20App = ({ Component, pageProps }: AppProps): JSX.Element => {
+ const isTouchDevice = useIsTouchDevice();
+ // Assigning backend based on touch support on the device
+ const backendForDND = isTouchDevice ? TouchBackend : HTML5Backend;
+
+ return (
+ <>
+
+
+
+
+ Aalto-yliopiston Sähköinsinöörikilta ry
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+};
export default Web20App;