UNPKG

@mdxeditor/editor

Version:

React component for rich text markdown editing

108 lines (107 loc) 6.18 kB
import * as Dialog from "@radix-ui/react-dialog"; import classNames from "classnames"; import YamlParser from "js-yaml"; import React__default from "react"; import { useForm, useFieldArray } from "react-hook-form"; import { frontmatterDialogOpen$, removeFrontmatter$ } from "./index.js"; import styles from "../../styles/ui.module.css.js"; import { readOnly$, editorRootElementRef$, iconComponentFor$, useTranslation } from "../core/index.js"; import { useCellValues, usePublisher } from "@mdxeditor/gurx"; const FrontmatterEditor = ({ yaml, onChange }) => { const [readOnly, editorRootElementRef, iconComponentFor, frontmatterDialogOpen] = useCellValues( readOnly$, editorRootElementRef$, iconComponentFor$, frontmatterDialogOpen$ ); const t = useTranslation(); const setFrontmatterDialogOpen = usePublisher(frontmatterDialogOpen$); const removeFrontmatter = usePublisher(removeFrontmatter$); const yamlConfig = React__default.useMemo(() => { if (!yaml) { return []; } return Object.entries(YamlParser.load(yaml)).map(([key, value]) => ({ key, value })); }, [yaml]); const { register, control, handleSubmit } = useForm({ defaultValues: { yamlConfig } }); const { fields, append, remove } = useFieldArray({ control, name: "yamlConfig" }); const onSubmit = React__default.useCallback( ({ yamlConfig: yamlConfig2 }) => { if (yamlConfig2.length === 0) { removeFrontmatter(); setFrontmatterDialogOpen(false); return; } const yaml2 = yamlConfig2.reduce((acc, { key, value }) => { if (key && value) { acc[key] = value; } return acc; }, {}); onChange(YamlParser.dump(yaml2).trim()); setFrontmatterDialogOpen(false); }, [onChange, setFrontmatterDialogOpen, removeFrontmatter] ); return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement( Dialog.Root, { open: frontmatterDialogOpen, onOpenChange: (open) => { setFrontmatterDialogOpen(open); } }, /* @__PURE__ */ React__default.createElement(Dialog.Portal, { container: editorRootElementRef == null ? void 0 : editorRootElementRef.current }, /* @__PURE__ */ React__default.createElement(Dialog.Overlay, { className: styles.dialogOverlay }), /* @__PURE__ */ React__default.createElement(Dialog.Content, { className: styles.largeDialogContent, "data-editor-type": "frontmatter" }, /* @__PURE__ */ React__default.createElement(Dialog.Title, { className: styles.dialogTitle }, t("frontmatterEditor.title", "Edit document frontmatter")), /* @__PURE__ */ React__default.createElement( "form", { onSubmit: (e) => { void handleSubmit(onSubmit)(e); e.stopPropagation(); }, onReset: (e) => { e.stopPropagation(); setFrontmatterDialogOpen(false); } }, /* @__PURE__ */ React__default.createElement("table", { className: styles.propertyEditorTable }, /* @__PURE__ */ React__default.createElement("colgroup", null, /* @__PURE__ */ React__default.createElement("col", null), /* @__PURE__ */ React__default.createElement("col", null), /* @__PURE__ */ React__default.createElement("col", null)), /* @__PURE__ */ React__default.createElement("thead", null, /* @__PURE__ */ React__default.createElement("tr", null, /* @__PURE__ */ React__default.createElement("th", null, t("frontmatterEditor.key", "Key")), /* @__PURE__ */ React__default.createElement("th", null, t("frontmatterEditor.value", "Value")), /* @__PURE__ */ React__default.createElement("th", null))), /* @__PURE__ */ React__default.createElement("tbody", null, fields.map((item, index) => { return /* @__PURE__ */ React__default.createElement("tr", { key: item.id }, /* @__PURE__ */ React__default.createElement("td", null, /* @__PURE__ */ React__default.createElement(TableInput, { ...register(`yamlConfig.${index}.key`, { required: true }), autofocusIfEmpty: true, readOnly })), /* @__PURE__ */ React__default.createElement("td", null, /* @__PURE__ */ React__default.createElement(TableInput, { ...register(`yamlConfig.${index}.value`, { required: true }), readOnly })), /* @__PURE__ */ React__default.createElement("td", null, /* @__PURE__ */ React__default.createElement( "button", { type: "button", onClick: () => { remove(index); }, className: styles.iconButton, disabled: readOnly }, iconComponentFor("delete_big") ))); })), /* @__PURE__ */ React__default.createElement("tfoot", null, /* @__PURE__ */ React__default.createElement("tr", null, /* @__PURE__ */ React__default.createElement("td", null, /* @__PURE__ */ React__default.createElement( "button", { disabled: readOnly, className: classNames(styles.primaryButton, styles.smallButton), type: "button", onClick: () => { append({ key: "", value: "" }); } }, t("frontmatterEditor.addEntry", "Add entry") ))))), /* @__PURE__ */ React__default.createElement("div", { style: { display: "flex", justifyContent: "flex-end", gap: "var(--spacing-2)" } }, /* @__PURE__ */ React__default.createElement("button", { type: "submit", className: styles.primaryButton }, t("dialogControls.save", "Save")), /* @__PURE__ */ React__default.createElement("button", { type: "reset", className: styles.secondaryButton }, t("dialogControls.cancel", "Cancel"))) ), /* @__PURE__ */ React__default.createElement(Dialog.Close, { asChild: true }, /* @__PURE__ */ React__default.createElement("button", { className: styles.dialogCloseButton, "aria-label": t("dialogControls.cancel", "Cancel") }, iconComponentFor("close"))))) )); }; const TableInput = React__default.forwardRef(({ className, autofocusIfEmpty: _, ...props }, ref) => { return /* @__PURE__ */ React__default.createElement("input", { className: classNames(styles.propertyEditorInput, className), ...props, ref }); }); export { FrontmatterEditor };