1
Fork 0
mirror of https://github.com/Steffo99/festa.git synced 2024-12-23 15:14:23 +00:00
festa/components/generic/editable/inputs.tsx

91 lines
2.6 KiB
TypeScript
Raw Normal View History

import { ComponentPropsWithoutRef, ReactNode } from "react"
2022-06-11 03:08:49 +00:00
import { FestaMoment } from "../renderers/datetime"
import { FestaMarkdownRenderer } from "../renderers/markdown"
import { EditingModeBranch } from "./base"
import style from "./inputs.module.css"
2022-06-11 03:08:49 +00:00
type TextInputProps = ComponentPropsWithoutRef<"input"> & { value: string, viewPrefix?: ReactNode, viewSuffix?: ReactNode }
2022-06-11 03:08:49 +00:00
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.viewPrefix}{props.value}{props.viewSuffix}
</div>
2022-06-11 03:08:49 +00:00
}
/>
)
}
/**
* 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={
2022-07-17 04:19:23 +00:00
<textarea
className={style.editableMarkdownEdit}
rows={12}
2022-07-17 04:19:23 +00:00
{...props}
/>
2022-06-11 03:08:49 +00:00
}
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={
2022-07-16 15:43:45 +00:00
<div>
<FestaMoment date={new Date(props.value)} />
</div>
2022-06-11 03:08:49 +00:00
}
/>
)
}