mirror of
https://github.com/Steffo99/festa.git
synced 2024-12-22 22:54:22 +00:00
Nuke editables
This commit is contained in:
parent
ee6a082f66
commit
08ed0f14d3
5 changed files with 0 additions and 162 deletions
|
@ -1,3 +0,0 @@
|
||||||
# Generic editables
|
|
||||||
|
|
||||||
Editables are extended `input` elements which display differently based on the `EditingMode` of the `EditingContext` they are contained in.
|
|
|
@ -1,44 +0,0 @@
|
||||||
import { useDefinedContext } from "../../../utils/definedContext";
|
|
||||||
import { createStateContext } from "../../../utils/stateContext";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The mode the editing context is currently in.
|
|
||||||
*/
|
|
||||||
export enum EditingMode {
|
|
||||||
/**
|
|
||||||
* The page is being (pre)viewed.
|
|
||||||
*/
|
|
||||||
VIEW = "view",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The page is being edited.
|
|
||||||
*/
|
|
||||||
EDIT = "edit",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The context of a previewable `form`.
|
|
||||||
*/
|
|
||||||
export const EditingContext = createStateContext<EditingMode>()
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parameters of {@link EditingModeBranch}.
|
|
||||||
*
|
|
||||||
* @todo Perhaps this should be changed to callbacks, so that elements are _not_ rendered unless they are required.
|
|
||||||
*/
|
|
||||||
export type EditingModeBranchProps = {
|
|
||||||
[Mode in EditingMode]: JSX.Element
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Component branching between its props based on the {@link EditingMode} of its innermost surrounding context.
|
|
||||||
*/
|
|
||||||
export const EditingModeBranch = (props: EditingModeBranchProps) => {
|
|
||||||
const [mode] = useDefinedContext(EditingContext)
|
|
||||||
|
|
||||||
return props[mode]
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
.editableTextView {
|
|
||||||
/* Match the padding of the edit input
|
|
||||||
* 8px padding + 2px border
|
|
||||||
*/
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editableMarkdownEdit {
|
|
||||||
font-family: monospace;
|
|
||||||
}
|
|
|
@ -1,91 +0,0 @@
|
||||||
import { ComponentPropsWithoutRef, ReactNode } from "react"
|
|
||||||
import { FestaMoment } from "../renderers/datetime"
|
|
||||||
import { FestaMarkdownRenderer } from "../renderers/markdown"
|
|
||||||
import { EditingModeBranch } from "./base"
|
|
||||||
import style from "./inputs.module.css"
|
|
||||||
|
|
||||||
|
|
||||||
type TextInputProps = ComponentPropsWithoutRef<"input"> & { value: string }
|
|
||||||
type FileInputProps = ComponentPropsWithoutRef<"input"> & { value?: undefined }
|
|
||||||
type TextAreaProps = ComponentPropsWithoutRef<"textarea"> & { value: string }
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Controlled input component which displays an `input[type="text"]` in edit mode, and a `span` displaying the input in view mode.
|
|
||||||
*/
|
|
||||||
export const EditableText = (props: TextInputProps) => {
|
|
||||||
return (
|
|
||||||
<EditingModeBranch
|
|
||||||
edit={
|
|
||||||
<input type="text" {...props} />
|
|
||||||
}
|
|
||||||
view={
|
|
||||||
<div className={style.editableTextView}>
|
|
||||||
{props.value}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Controlled input component which displays an `input[type="file"]` in edit mode, and is invisible in view mode.
|
|
||||||
*
|
|
||||||
* Has no value due to how file inputs function in JS and React.
|
|
||||||
*/
|
|
||||||
export const EditableFilePicker = (props: FileInputProps) => {
|
|
||||||
return (
|
|
||||||
<EditingModeBranch
|
|
||||||
edit={
|
|
||||||
<input type="file" {...props} />
|
|
||||||
}
|
|
||||||
view={
|
|
||||||
<></>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Controlled input component which displays a `textarea` in edit mode, and renders the input in Markdown using {@link FestaMarkdownRenderer} in view mode.
|
|
||||||
*/
|
|
||||||
export const EditableMarkdown = (props: TextAreaProps) => {
|
|
||||||
return (
|
|
||||||
<EditingModeBranch
|
|
||||||
edit={
|
|
||||||
<textarea
|
|
||||||
className={style.editableMarkdownEdit}
|
|
||||||
rows={12}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
view={
|
|
||||||
<FestaMarkdownRenderer code={props.value} />
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Controlled input component which displays a `input[type="datetime-local"]` in edit mode, and renders the selected datetime using {@link FestaMoment} in view mode.
|
|
||||||
*/
|
|
||||||
export const EditableDateTimeLocal = (props: TextInputProps) => {
|
|
||||||
return (
|
|
||||||
<EditingModeBranch
|
|
||||||
edit={
|
|
||||||
<input
|
|
||||||
type="datetime-local"
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
view={
|
|
||||||
<div>
|
|
||||||
<FestaMoment date={new Date(props.value)} />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
import { ReactNode, useState } from "react"
|
|
||||||
import { EditingContext, EditingMode } from "./base"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Component which stores the current editing mode (by default {@link EditingMode.VIEW}) using {@link useState} and provides it to its children through an {@link EditingContext}.
|
|
||||||
*/
|
|
||||||
export const EditingContextProvider = ({ children }: { children: ReactNode }): JSX.Element => {
|
|
||||||
return (
|
|
||||||
<EditingContext.Provider value={useState<EditingMode>(EditingMode.VIEW)}>
|
|
||||||
{children}
|
|
||||||
</EditingContext.Provider>
|
|
||||||
)
|
|
||||||
}
|
|
Loading…
Reference in a new issue