Skip to content

Commit

Permalink
Add a droppable and improve the styles
Browse files Browse the repository at this point in the history
  • Loading branch information
hadijahkyampeire committed Jul 14, 2023
1 parent 09bf4e7 commit 67a22c9
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 73 deletions.
113 changes: 55 additions & 58 deletions src/components/interactive-builder/draggable-question.component.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React from "react";
import { useDraggable } from "@dnd-kit/core";
import { CSS } from "@dnd-kit/utilities";
import { useTranslation } from "react-i18next";
import { Button } from "@carbon/react";
import { Edit, Replicate, TrashCan } from "@carbon/react/icons";
import { Edit, Replicate, TrashCan, Draggable } from "@carbon/react/icons";

import { Question } from "../../types";
import { CSS } from "@dnd-kit/utilities";
import styles from "./interactive-builder.scss";
import draggableStyles from "./draggable-question.scss";

import styles from "./draggable-question.scss";

type DraggableQuestionProps = {
allQuestions: Array<Question>;
Expand Down Expand Up @@ -34,9 +35,11 @@ export const DraggableQuestion: React.FC<DraggableQuestionProps> = ({
allQuestions,
}) => {
const { t } = useTranslation();
const { attributes, listeners, setNodeRef, transform, isDragging } =
const draggableId = `question-${pageIndex}-${sectionIndex}-${questionIndex}`;

const { attributes, listeners, transform, isDragging, setNodeRef } =
useDraggable({
id: `question-${pageIndex}-${sectionIndex}-${questionIndex}`,
id: draggableId,
disabled: allQuestions.length <= 1,
});

Expand All @@ -45,61 +48,55 @@ export const DraggableQuestion: React.FC<DraggableQuestionProps> = ({
cursor: isDragging ? "grabbing" : "grab",
};

const dragStyles = isDragging ? styles.isDragged : styles.normal;
return (
<div>
<div className={dragStyles} style={style}>
<div
style={{
display: "flex",
alignItems: "center",
}}
className={styles.questionContainer}
ref={setNodeRef}
{...attributes}
{...listeners}
>
<div
className={styles.editorContainer}
ref={setNodeRef}
style={style}
{...attributes}
{...listeners}
draggable={!isDragging}
>
<p className={styles.questionLabel}>{question.label}</p>
</div>
<div className={draggableStyles.buttonsContainer}>
<Button
kind="ghost"
size="sm"
enterDelayMs={200}
iconDescription={t("duplicateQuestion", "Duplicate question")}
onClick={() => {
if (!isDragging) {
duplicateQuestion(question, pageIndex, sectionIndex);
}
}}
renderIcon={(props) => <Replicate size={16} {...props} />}
hasIconOnly
/>
<Button
kind="ghost"
size="sm"
enterDelayMs={200}
iconDescription={t("editQuestion", "Edit question")}
onClick={() => {
if (!isDragging) {
handleEditButtonClick(question);
}
}}
renderIcon={(props) => <Edit size={16} {...props} />}
hasIconOnly
/>
<Button
hasIconOnly
enterDelayMs={200}
iconDescription={t("deleteQuestion", "Delete question")}
kind="ghost"
onClick={handleDeleteButtonClick}
renderIcon={(props) => <TrashCan size={16} {...props} />}
size="sm"
/>
</div>
<Draggable className={styles.draggableIcon} />
<p className={styles.questionLabel}>{question.label}</p>
</div>

<div className={styles.buttonsContainer}>
<Button
kind="ghost"
size="sm"
enterDelayMs={200}
iconDescription={t("duplicateQuestion", "Duplicate question")}
onClick={() => {
if (!isDragging) {
duplicateQuestion(question, pageIndex, sectionIndex);
}
}}
renderIcon={(props) => <Replicate size={16} {...props} />}
hasIconOnly
/>
<Button
kind="ghost"
size="sm"
enterDelayMs={200}
iconDescription={t("editQuestion", "Edit question")}
onClick={() => {
if (!isDragging) {
handleEditButtonClick(question);
}
}}
renderIcon={(props) => <Edit size={16} {...props} />}
hasIconOnly
/>
<Button
hasIconOnly
enterDelayMs={200}
iconDescription={t("deleteQuestion", "Delete question")}
kind="ghost"
onClick={handleDeleteButtonClick}
renderIcon={(props) => <TrashCan size={16} {...props} />}
size="sm"
/>
</div>
</div>
);
Expand Down
27 changes: 27 additions & 0 deletions src/components/interactive-builder/draggable-question.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,34 @@
@use '@carbon/styles/scss/type';
@use '@carbon/styles/scss/spacing';
@import '~@openmrs/esm-styleguide/src/vars';

.buttonsContainer {
display: flex;
align-items: center;
}

.questionContainer {
display: flex;
align-items: center;
}

.isDragged, .normal {
display: flex;
height: 3rem;
justify-content: space-between;
align-items: center;
margin: spacing.$spacing-02 spacing.$spacing-03;
width: 100%;
}

.normal:hover {
background-color: $ui-03;
}
.isDragged {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
background-color: rgba(255, 255, 255, 0.552);
}

.draggableIcon {
margin: spacing.$spacing-05 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from "react";
import { useDroppable } from "@dnd-kit/core";

export function Droppable(props) {
const { isOver, setNodeRef } = useDroppable({
id: props.id,
});

const style = {
border: `1px solid ${isOver ? "#3ddbd9" : "transparent"}`,
};

return (
<div ref={setNodeRef} style={style}>
{props.children}
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import NewFormModal from "./new-form-modal.component";
import PageModal from "./page-modal.component";
import SectionModal from "./section-modal.component";
import { DraggableQuestion } from "./draggable-question.component";
import { Droppable } from "./droppable-container.component";

import styles from "./interactive-builder.scss";

Expand Down Expand Up @@ -278,6 +279,20 @@ const InteractiveBuilder: React.FC<InteractiveBuilderProps> = ({
setQuestionIndex(questionIndex);
setShowDeleteQuestionModal(true);
};

const draggable = (question: Question, section, questionIndex) => (
<DraggableQuestion
key={question.id}
question={question}
pageIndex={pageIndex}
sectionIndex={sectionIndex}
questionIndex={questionIndex}
duplicateQuestion={duplicateQuestion}
handleEditButtonClick={handleEditButtonClick}
handleDeleteButtonClick={handleDeleteButtonClick}
allQuestions={section.questions}
/>
);
return (
<div className={styles.container}>
{isLoading ? (
Expand Down Expand Up @@ -520,21 +535,17 @@ const InteractiveBuilder: React.FC<InteractiveBuilderProps> = ({
{section.questions?.length ? (
section.questions.map(
(question, questionIndex) => (
<DraggableQuestion
key={question.id}
question={question}
pageIndex={pageIndex}
sectionIndex={sectionIndex}
questionIndex={questionIndex}
duplicateQuestion={duplicateQuestion}
handleEditButtonClick={
handleEditButtonClick
}
handleDeleteButtonClick={
handleDeleteButtonClick
}
allQuestions={section.questions}
/>
<>
<Droppable
id={`droppable-question-${pageIndex}-${sectionIndex}-${questionIndex}`}
>
{draggable(
question,
section,
questionIndex
)}
</Droppable>
</>
)
)
) : (
Expand All @@ -545,6 +556,7 @@ const InteractiveBuilder: React.FC<InteractiveBuilderProps> = ({
)}
</p>
)}

<Button
className={styles.addQuestionButton}
kind="primary"
Expand Down

0 comments on commit 67a22c9

Please sign in to comment.