From 63efa5b896c85bc7164bc2c1f18f776a62072c71 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Wed, 8 Jun 2022 18:00:39 +0200 Subject: [PATCH] Document and improve editables --- components/contexts/editing.tsx | 4 ---- components/contexts/login.tsx | 4 ++-- components/editable/EditableDateRange.tsx | 2 +- components/editable/EditableMarkdown.tsx | 6 ++++-- components/editable/EditablePostcard.tsx | 7 ++++++- components/editable/EditableText.tsx | 11 +++++++---- components/editable/EditingContext.ts | 9 +++++++++ components/editable/README.md | 7 +++++++ components/tools/ToolToggleEditing.tsx | 2 +- pages/events/[slug].tsx | 2 +- 10 files changed, 38 insertions(+), 16 deletions(-) delete mode 100644 components/contexts/editing.tsx create mode 100644 components/editable/EditingContext.ts create mode 100644 components/editable/README.md diff --git a/components/contexts/editing.tsx b/components/contexts/editing.tsx deleted file mode 100644 index 37ad180..0000000 --- a/components/contexts/editing.tsx +++ /dev/null @@ -1,4 +0,0 @@ -import { createStateContext } from "../../utils/stateContext"; - - -export const EditingContext = createStateContext() diff --git a/components/contexts/login.tsx b/components/contexts/login.tsx index 2be2fe3..eff5c65 100644 --- a/components/contexts/login.tsx +++ b/components/contexts/login.tsx @@ -5,8 +5,8 @@ import { createStateContext } from "../../utils/stateContext"; /** * Context containing data about the user's current login status: * - `null` if the user is not logged in - * - an instance of {@link LoginData} if the user is logged in + * - an instance of {@link FestaLoginData} if the user is logged in * - * Please note that the data containing in this context is not validated, and will need to be validated by the server on every request. + * Please note that the data containing in this context is not validated, and will be validated by the server on every request. */ export const LoginContext = createStateContext() diff --git a/components/editable/EditableDateRange.tsx b/components/editable/EditableDateRange.tsx index eb253ec..0ec2b35 100644 --- a/components/editable/EditableDateRange.tsx +++ b/components/editable/EditableDateRange.tsx @@ -1,6 +1,6 @@ import { faChevronRight, faClock } from "@fortawesome/free-solid-svg-icons" import { HTMLProps } from "react" -import { EditingContext } from "../contexts/editing" +import { EditingContext } from "./EditingContext" import { useDefinedContext } from "../../utils/definedContext" import { FestaIcon } from "../extensions/FestaIcon" import { FormDateRange } from "../form/FormDateRange" diff --git a/components/editable/EditableMarkdown.tsx b/components/editable/EditableMarkdown.tsx index c4d392d..85612d7 100644 --- a/components/editable/EditableMarkdown.tsx +++ b/components/editable/EditableMarkdown.tsx @@ -1,9 +1,11 @@ import { HTMLProps } from "react"; -import { EditingContext } from "../contexts/editing"; +import { EditingContext } from "./EditingContext"; import { useDefinedContext } from "../../utils/definedContext"; import { FestaMarkdown } from "../extensions/FestaMarkdown"; - +/** + * Controlled input component which displays a `textarea` in editing mode, and renders the input in Markdown using {@link FestaMarkdown} in preview mode. + */ export function EditableMarkdown({value, ...props}: HTMLProps) { const [editing,] = useDefinedContext(EditingContext) diff --git a/components/editable/EditablePostcard.tsx b/components/editable/EditablePostcard.tsx index 53fec07..8bcc4e6 100644 --- a/components/editable/EditablePostcard.tsx +++ b/components/editable/EditablePostcard.tsx @@ -1,9 +1,14 @@ import { HTMLProps } from "react"; -import { EditingContext } from "../contexts/editing"; +import { EditingContext } from "./EditingContext"; import { useDefinedContext } from "../../utils/definedContext"; import { Postcard } from "../postcard/Postcard"; +/** + * Controlled input component which displays an `input[type="file"]` in editing mode, and is invisible in preview mode. + * + * As a side effect, it changes the {@link Postcard} to the input file when it's rendered. + */ export function EditablePostcard({value, ...props}: HTMLProps & {value: string | undefined}) { const [editing,] = useDefinedContext(EditingContext) diff --git a/components/editable/EditableText.tsx b/components/editable/EditableText.tsx index c05f7d2..9ae4e25 100644 --- a/components/editable/EditableText.tsx +++ b/components/editable/EditableText.tsx @@ -1,14 +1,17 @@ import { HTMLProps } from "react"; -import { EditingContext } from "../contexts/editing"; +import { EditingContext } from "./EditingContext"; import { useDefinedContext } from "../../utils/definedContext"; -export function EditableText({value, ...props}: HTMLProps) { +/** + * Controlled input component which displays an `input[type="text"]` in editing mode, and a `span` displaying the input in preview mode. + */ +export function EditableText(props: HTMLProps & {value: string}) { const [editing,] = useDefinedContext(EditingContext) return editing ? ( - + ) : ( - {value} + {props.value} ) } \ No newline at end of file diff --git a/components/editable/EditingContext.ts b/components/editable/EditingContext.ts new file mode 100644 index 0000000..2901ba2 --- /dev/null +++ b/components/editable/EditingContext.ts @@ -0,0 +1,9 @@ +import { createStateContext } from "../../utils/stateContext"; + + +/** + * {@link createStateContext State context} representing the editing state of a form. + * + * If `true`, the components should be editable, while if `false`, the components should preview their contents. + */ +export const EditingContext = createStateContext() diff --git a/components/editable/README.md b/components/editable/README.md new file mode 100644 index 0000000..28a3dc5 --- /dev/null +++ b/components/editable/README.md @@ -0,0 +1,7 @@ +# Editables + +This folder contains controlled input components with two modes: a "editing" mode, which displays a box where the user can input data, and a "preview" mode, which renders the value of the data input by the user. + +For example, [`EditableMarkdown`](EditableMarkdown.tsx) displays a `textarea` in editing mode, and renders the Markdown into a `div` in preview mode. + +The mode of the elements is determined by the current value of the [`EditingContext`](EditingContext.ts) they are in. diff --git a/components/tools/ToolToggleEditing.tsx b/components/tools/ToolToggleEditing.tsx index c84b349..4a3a211 100644 --- a/components/tools/ToolToggleEditing.tsx +++ b/components/tools/ToolToggleEditing.tsx @@ -1,6 +1,6 @@ import { faBinoculars, faPencil } from "@fortawesome/free-solid-svg-icons" import { useTranslation } from "next-i18next" -import { EditingContext } from "../contexts/editing" +import { EditingContext } from "../editable/EditingContext" import { useDefinedContext } from "../../utils/definedContext" import { FestaIcon } from "../extensions/FestaIcon" diff --git a/pages/events/[slug].tsx b/pages/events/[slug].tsx index e21396c..5cb4d0c 100644 --- a/pages/events/[slug].tsx +++ b/pages/events/[slug].tsx @@ -8,7 +8,7 @@ import { ToolBar } from "../../components/tools/ToolBar"; import { EditableMarkdown } from "../../components/editable/EditableMarkdown"; import { EditableText } from "../../components/editable/EditableText"; import { ToolToggleEditing } from "../../components/tools/ToolToggleEditing"; -import { EditingContext } from "../../components/contexts/editing"; +import { EditingContext } from "../../components/editable/EditingContext"; import { database } from "../../utils/prismaClient"; import { EditablePostcard } from "../../components/editable/EditablePostcard"; import { ViewEvent } from "../../components/view/ViewEvent";