/** * Copyright (c) 2019-present, NDLA. * * This source code is licensed under the GPLv3 license found in the * LICENSE file in the root directory of this source tree. * */ import { ChangeEvent, createRef, useCallback, useState } from "react"; import { useTranslation } from "react-i18next"; import Editor from "react-simple-code-editor"; // @ts-ignore import styled from "@emotion/styled"; import { ButtonV2 } from "@ndla/button"; import { colors, fonts, spacing } from "@ndla/core"; import { Code } from "@ndla/icons/editor"; import { Wrapper, FlexContainer, FlexElement } from "./style"; import { languageOptions, ICodeLangugeOption } from "../languageOptions"; type Props = { onSave: Function; onAbort: Function; highlight: (code: string, language: string) => string; content: { code: string; title: string; format: string; } | null; }; const StyledInput = styled.input` ${fonts.sizes(18, 1.15)}; border: 1px solid ${colors.brand.greyDark}; font-family: ${fonts.sans}; font-weight: ${fonts.weight.normal}; min-height: 1.5em; padding: 0.4em 1.4em 0.4em 1em; `; const StyledSelect = styled.select` appearance: none; background: ${colors.white}; background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%20fill%3D%22%23555555%22%20%0A%09%20width%3D%2224px%22%20height%3D%2224px%22%20viewBox%3D%22-261%20145.2%2024%2024%22%20style%3D%22enable-background%3Anew%20-261%20145.2%2024%2024%3B%22%20xml%3Aspace%3D%22preserve%22%3E%0A%3Cpath%20d%3D%22M-245.3%2C156.1l-3.6-6.5l-3.7%2C6.5%20M-252.7%2C159l3.7%2C6.5l3.6-6.5%22%2F%3E%0A%3C%2Fsvg%3E"); background-repeat: no-repeat; background-position: 100%; border: 1px solid ${colors.brand.greyDark}; color: ${colors.brand.greyDark}; line-height: 1.15; min-height: 1.5em; padding: 0.4em 1.4em 0.4em 1em; `; interface CodeContentState { code: string; title: string; format: string; } const CodeBlockEditor = ({ onSave, onAbort, highlight, content = null }: Props) => { const { t } = useTranslation(); const [defaultLang] = languageOptions; const [codeContent, setCodeContent] = useState({ code: content ? content.code : "", title: content ? content.title : defaultLang.title, format: content ? content.format : defaultLang.format, }); const highlightWithLineNumbers = useCallback( (input: string, language: string) => highlight(input, language) .split("\n") .map((line: string, i: number) => `${i + 1}${line}`) .join("\n"), [highlight], ); const titleRef = createRef(); const handleChangeLanguage = (event: ChangeEvent) => { const { value } = event.target; const selectedLanguage = languageOptions.find((item: ICodeLangugeOption) => item.format === value); if (selectedLanguage) { const { format } = selectedLanguage; setCodeContent((prev: CodeContentState) => { return { ...prev, title: value, format }; }); } }; const abort = () => { onAbort(); }; const save = () => { const selectedLanguage = languageOptions.find((item: ICodeLangugeOption) => item.format === codeContent.format); if (selectedLanguage) { const titleValue = titleRef.current && titleRef.current.value; const { title, format } = selectedLanguage; onSave({ ...codeContent, title: titleValue || title, format }); } }; return ( {t("codeEditor.title")}