UNPKG

@instructure/canvas-rce

Version:

A component wrapping Canvas's usage of Tinymce

138 lines (137 loc) 4.67 kB
/* * Copyright (C) 2019 - present Instructure, Inc. * * This file is part of Canvas. * * Canvas is free software: you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License as published by the Free * Software Foundation, version 3 of the License. * * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. */ import React, { useEffect, useState } from 'react'; import { bool, func, oneOf, string } from 'prop-types'; import { Alert } from '@instructure/ui-alerts'; import { Button, CloseButton } from '@instructure/ui-buttons'; import { Heading } from '@instructure/ui-heading'; import { TextInput } from '@instructure/ui-text-input'; import { Modal } from '@instructure/ui-modal'; import { View } from '@instructure/ui-view'; import formatMessage from '../../../../../format-message'; import validateURL from '../../validateURL'; import { instuiPopupMountNodeFn } from '../../../../../util/fullscreenHelpers'; const CREATE_LINK = 'create'; const EDIT_LINK = 'edit'; export default function LinkOptionsDialog(props) { const [text, setText] = useState(props.text || ''); const [url, setUrl] = useState(props.url || ''); const [err, setErr] = useState(null); const [isValidURL, setIsValidURL] = useState(false); useEffect(() => { try { const v = validateURL(url); setIsValidURL(v); setErr(null); } catch (ex) { setIsValidURL(false); setErr(ex.message); } }, [url]); function handleSave(event) { event.preventDefault(); if (!url) return; const linkText = text.trim() || url; props.onSave({ text: linkText, target: '_blank', href: url, userText: props.showText, class: 'inline_disabled', forceRename: true }); } function handleTextChange(event) { setText(event.target.value); } function handleLinkChange(event) { setUrl(event.target.value); } const label = props.operation === CREATE_LINK ? formatMessage('Insert Link') : formatMessage('Edit Link'); return /*#__PURE__*/React.createElement(Modal, { "data-testid": "RCELinkOptionsDialog", "data-mce-component": true, as: "form", label: label, mountNode: instuiPopupMountNodeFn, onDismiss: props.onRequestClose, onEntered: props.onEntered, onExited: props.onExited, onSubmit: handleSave, open: props.open, shouldCloseOnDocumentClick: false, shouldReturnFocus: false, size: "medium" }, /*#__PURE__*/React.createElement(Modal.Header, null, /*#__PURE__*/React.createElement(CloseButton, { offset: "medium", placement: "end", screenReaderLabel: formatMessage('Close'), onClick: props.onRequestClose }), /*#__PURE__*/React.createElement(Heading, null, label)), /*#__PURE__*/React.createElement(Modal.Body, null, props.showText && /*#__PURE__*/React.createElement(View, { as: "div", margin: "small" }, /*#__PURE__*/React.createElement(TextInput, { renderLabel: formatMessage('Text'), name: "linktext", onChange: handleTextChange, value: text })), /*#__PURE__*/React.createElement(View, { as: "div", margin: "small" }, /*#__PURE__*/React.createElement(TextInput, { renderLabel: formatMessage('Link'), name: "linklink", onChange: handleLinkChange, value: url })), err && /*#__PURE__*/React.createElement(View, { as: "div", margin: "small", "data-testid": "url-error" }, /*#__PURE__*/React.createElement(Alert, { variant: "error" }, err))), /*#__PURE__*/React.createElement(Modal.Footer, null, /*#__PURE__*/React.createElement("input", { type: "submit", style: { display: 'none' } }), /*#__PURE__*/React.createElement(Button, { onClick: props.onRequestClose, margin: "0 small", color: "secondary" }, formatMessage('Close')), /*#__PURE__*/React.createElement(Button, { disabled: !(url && isValidURL), onClick: handleSave, color: "primary" }, formatMessage('Done')))); } LinkOptionsDialog.propTypes = { text: string, url: string, operation: oneOf([CREATE_LINK, EDIT_LINK]), onEntered: func, onExited: func, onRequestClose: func.isRequired, onSave: func.isRequired, open: bool.isRequired, showText: bool }; LinkOptionsDialog.defaultProps = { onEntered: null, onExited: null, showText: true };