-
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(app): add modal to add question (#390)
* feat(app): add modal to add question * feat(app): add modal provider * feat(app): add AddQuestionModal * refactor(app): remove portal component * feat(app): add select options to story * feat(app): add close button * refactor(app): add if statement * refactor(app): change heading level * feat(app): add appearance none * feat(app): memoize provider value * feat(app): add form for add question * feat(app): add select labels * refactor(app): pass unlockScroll reference to afterLeave * refactor(app): change label to aria-label * refactor(app): move styles into css class * refactor(app): change font size * refactor(app): remove AddQuestionForm component * refactor(app): remove CloseAddQuestionModalButton component * feat(app): add textarea label
- Loading branch information
1 parent
1674fc4
commit 8adc36b
Showing
19 changed files
with
293 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
"use client"; | ||
|
||
import { ComponentProps } from "react"; | ||
import type { FormEvent } from "react"; | ||
import { useModalContext } from "../providers/ModalProvider"; | ||
import { BaseModal } from "./BaseModal"; | ||
import { Button } from "./Button/Button"; | ||
import { Select } from "./Select/Select"; | ||
|
||
export const AddQuestionModal = (props: ComponentProps<typeof BaseModal>) => { | ||
const { closeModal } = useModalContext(); | ||
|
||
const handleFormSubmit = (event: FormEvent<HTMLFormElement>) => { | ||
event.preventDefault(); | ||
}; | ||
|
||
return ( | ||
<BaseModal {...props}> | ||
<h2 className="text-center text-xl font-bold uppercase text-primary">Nowe pytanie</h2> | ||
<form onSubmit={handleFormSubmit}> | ||
<div className="mt-10 flex flex-col gap-y-3 px-5 sm:flex-row sm:justify-evenly sm:gap-x-5"> | ||
<Select className="w-full" aria-label="Wybierz technologię"> | ||
<option>Wybierz Technologię</option> | ||
<option>HTML5</option> | ||
<option>JavaScript</option> | ||
</Select> | ||
<Select className="w-full" aria-label="Wybierz poziom"> | ||
<option>Wybierz Poziom</option> | ||
<option value="junior">junior</option> | ||
<option value="mid">Mid</option> | ||
<option value="senior">Senior</option> | ||
</Select> | ||
</div> | ||
<textarea className="mt-4 h-40 w-full border" aria-label="Wpisz treść pytania"></textarea> | ||
<div className="mt-3 flex flex-col gap-2 sm:flex-row-reverse"> | ||
<Button type="submit" variant="brandingInverse"> | ||
Dodaj pytanie | ||
</Button> | ||
<Button variant="branding" onClick={closeModal}> | ||
Anuluj | ||
</Button> | ||
</div> | ||
</form> | ||
</BaseModal> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
"use client"; | ||
|
||
import type { ComponentProps, ComponentType } from "react"; | ||
import { useModalContext } from "../providers/ModalProvider"; | ||
import type { Modal } from "../providers/ModalProvider"; | ||
import { AddQuestionModal } from "./AddQuestionModal"; | ||
import { BaseModal } from "./BaseModal"; | ||
|
||
const modals: Record<Modal, ComponentType<ComponentProps<typeof BaseModal>>> = { | ||
AddQuestionModal, | ||
}; | ||
|
||
export const AppModals = () => { | ||
const { openedModal, closeModal } = useModalContext(); | ||
|
||
return ( | ||
<> | ||
{Object.entries(modals).map(([type, Modal]) => ( | ||
<Modal key={type} isOpen={type === openedModal} onClose={closeModal} /> | ||
))} | ||
</> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
"use client"; | ||
|
||
import { ReactNode, useEffect } from "react"; | ||
import { Transition } from "@headlessui/react"; | ||
import { lockScroll, unlockScroll } from "../utils/pageScroll"; | ||
import { CloseButton } from "./CloseButton/CloseButton"; | ||
|
||
type BaseModalProps = Readonly<{ | ||
isOpen: boolean; | ||
onClose: () => void; | ||
children?: ReactNode; | ||
}>; | ||
|
||
export const BaseModal = ({ isOpen, onClose, children }: BaseModalProps) => { | ||
useEffect(() => { | ||
if (isOpen) { | ||
lockScroll(); | ||
} | ||
}, [isOpen]); | ||
|
||
return ( | ||
<Transition | ||
className="fixed top-0 left-0 z-[99] flex h-full w-full items-center justify-center overflow-y-auto bg-black/50 sm:px-2" | ||
onClick={onClose} | ||
show={isOpen} | ||
enter="transition-opacity duration-200" | ||
enterFrom="opacity-0" | ||
enterTo="opacity-100" | ||
leave="transition-opacity duration-100" | ||
leaveFrom="opacity-100" | ||
leaveTo="opacity-0" | ||
afterLeave={unlockScroll} | ||
> | ||
<div | ||
className="relative h-full w-full max-w-3xl animate-show rounded-sm bg-white px-3.5 py-9 sm:h-fit sm:px-11 sm:py-20" | ||
onClick={(event) => { | ||
// stop propagation to avoid triggering `onClick` on the backdrop behind the modal | ||
event.stopPropagation(); | ||
}} | ||
> | ||
<CloseButton | ||
type="button" | ||
aria-label="Zamknij modal" | ||
className="absolute right-4 top-4" | ||
onClick={onClose} | ||
/> | ||
{children} | ||
</div> | ||
</Transition> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
apps/app/src/components/CloseButton/CloseButton.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { Meta, StoryObj } from "@storybook/react"; | ||
import { CloseButton } from "./CloseButton"; | ||
|
||
const meta: Meta<typeof CloseButton> = { | ||
title: "CloseButton", | ||
component: CloseButton, | ||
}; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof CloseButton>; | ||
|
||
export const Default: Story = {}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { twMerge } from "tailwind-merge"; | ||
import { ButtonHTMLAttributes } from "react"; | ||
|
||
export const CloseButton = ({ className, ...props }: ButtonHTMLAttributes<HTMLButtonElement>) => ( | ||
<button | ||
className={twMerge( | ||
"h-8 w-8 appearance-none rounded-full p-0 text-4xl leading-7 text-violet-200 transition-colors duration-100 hover:bg-primary focus:shadow-[0_0_10px] focus:shadow-primary focus:outline-none", | ||
className, | ||
)} | ||
{...props} | ||
> | ||
× | ||
</button> | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
"use client"; | ||
|
||
import { useModalContext } from "../../providers/ModalProvider"; | ||
import { Button } from "../Button/Button"; | ||
|
||
export const AddQuestionButton = () => { | ||
const { openModal } = useModalContext(); | ||
|
||
return ( | ||
<> | ||
<Button | ||
variant="brandingInverse" | ||
className="hidden sm:inline-block" | ||
onClick={() => openModal("AddQuestionModal")} | ||
> | ||
Dodaj pytanie | ||
</Button> | ||
</> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { Meta, StoryObj } from "@storybook/react"; | ||
import { Select } from "./Select"; | ||
|
||
const meta: Meta<typeof Select> = { | ||
title: "Select", | ||
component: Select, | ||
args: { | ||
children: ( | ||
<> | ||
<option>lorem</option> | ||
<option>ipsum</option> | ||
<option>dolor</option> | ||
</> | ||
), | ||
}, | ||
}; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof Select>; | ||
|
||
export const Default: Story = {}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { twMerge } from "tailwind-merge"; | ||
import type { SelectHTMLAttributes } from "react"; | ||
|
||
export const Select = ({ className, ...props }: SelectHTMLAttributes<HTMLSelectElement>) => ( | ||
<select | ||
className={twMerge( | ||
"select-purple cursor-pointer appearance-none rounded-none border-b border-primary py-2 pr-6 pl-1 text-base capitalize text-primary transition-shadow duration-100 focus:shadow-[0_0_10px] focus:shadow-primary focus:outline-0", | ||
className, | ||
)} | ||
{...props} | ||
/> | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,13 @@ | ||
import { ReactNode } from "react"; | ||
import { ModalProvider } from "./ModalProvider"; | ||
import { ThemeProvider } from "./ThemeProvider"; | ||
|
||
type AppProvidersProps = Readonly<{ | ||
children: ReactNode; | ||
}>; | ||
|
||
export const AppProviders = ({ children }: AppProvidersProps) => ( | ||
<ThemeProvider>{children}</ThemeProvider> | ||
<ThemeProvider> | ||
<ModalProvider>{children}</ModalProvider> | ||
</ThemeProvider> | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
"use client"; | ||
|
||
import { useCallback, useMemo, useState } from "react"; | ||
import type { ReactNode } from "react"; | ||
import { createSafeContext } from "../lib/createSafeContext"; | ||
|
||
export type Modal = "AddQuestionModal"; | ||
|
||
interface ModalContextValue { | ||
openedModal: Modal | null; | ||
openModal: (modal: Modal) => void; | ||
closeModal: () => void; | ||
} | ||
|
||
const [useModalContext, ModalContextProvider] = createSafeContext<ModalContextValue>(); | ||
|
||
const ModalProvider = ({ children }: { readonly children: ReactNode }) => { | ||
const [openedModal, setOpenedModal] = useState<Modal | null>(null); | ||
|
||
const openModal = useCallback((modal: Modal) => { | ||
setOpenedModal(modal); | ||
}, []); | ||
|
||
const closeModal = useCallback(() => { | ||
setOpenedModal(null); | ||
}, []); | ||
|
||
const value = useMemo( | ||
() => ({ openedModal, openModal, closeModal }), | ||
[openedModal, openModal, closeModal], | ||
); | ||
|
||
return <ModalContextProvider value={value}>{children}</ModalContextProvider>; | ||
}; | ||
|
||
export { useModalContext, ModalProvider }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,12 @@ | ||
@tailwind base; | ||
@tailwind components; | ||
@tailwind utilities; | ||
|
||
@layer components { | ||
.select-purple { | ||
background-image: url("/select-purple.svg"); | ||
background-size: 25px; | ||
background-position: 100% 50%; | ||
background-repeat: no-repeat; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.