UNPKG

rhino-editor

Version:

A custom element wrapped rich text editor

761 lines (714 loc) 25.8 kB
import { normalize } from "./chunk-PA75CBW2.js"; import { fileUploadErrorMessage } from "./chunk-MPMUJGV5.js"; import { __export } from "./chunk-54KOYG5C.js"; // src/exports/elements/attachment-editor.ts import { css, html as html2 } from "lit"; // src/internal/icons.ts var icons_exports = {}; __export(icons_exports, { attachFiles: () => attachFiles, blockQuote: () => blockQuote, bold: () => bold, bulletList: () => bulletList, close: () => close, closeSvgPath: () => closeSvgPath, code: () => code, codeBlock: () => codeBlock, decreaseIndentation: () => decreaseIndentation, heading: () => heading, increaseIndentation: () => increaseIndentation, italics: () => italics, link: () => link, orderedList: () => orderedList, redo: () => redo, strike: () => strike, toSvg: () => toSvg, undo: () => undo, warning: () => warning, warningSvgPath: () => warningSvgPath }); import { html, svg } from "lit"; function toSvg(path, size = 24, parts = ["toolbar__icon"]) { return html`<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" viewBox="0 0 ${size} ${size}" width="${size}" height="${size}" part="${parts.join(" ")}" > ${path} </svg>`; } var bold = toSvg( svg`<path fill-rule="evenodd" d="M6 4.75c0-.69.56-1.25 1.25-1.25h5a4.75 4.75 0 013.888 7.479A5 5 0 0114 20.5H7.25c-.69 0-1.25-.56-1.25-1.25V4.75zM8.5 13v5H14a2.5 2.5 0 000-5H8.5zm0-2.5h3.751A2.25 2.25 0 0012.25 6H8.5v4.5z"></path>` ); var italics = toSvg( svg`<path fill-rule="evenodd" d="M10 4.75a.75.75 0 01.75-.75h8.5a.75.75 0 010 1.5h-3.514l-5.828 13h3.342a.75.75 0 010 1.5h-8.5a.75.75 0 010-1.5h3.514l5.828-13H10.75a.75.75 0 01-.75-.75z"></path>` ); var strike = toSvg( svg`<path fill-rule="evenodd" d="M12.36 5C9.37 5 8.105 6.613 8.105 7.848c0 .411.072.744.193 1.02a.75.75 0 01-1.373.603 3.993 3.993 0 01-.32-1.623c0-2.363 2.271-4.348 5.755-4.348 1.931 0 3.722.794 4.814 1.5a.75.75 0 11-.814 1.26c-.94-.607-2.448-1.26-4-1.26zm4.173 7.5h3.717a.75.75 0 000-1.5H3.75a.75.75 0 000 1.5h9.136c1.162.28 2.111.688 2.76 1.211.642.518.979 1.134.979 1.898a2.63 2.63 0 01-.954 2.036c-.703.601-1.934 1.105-3.999 1.105-2.018 0-3.529-.723-4.276-1.445a.75.75 0 10-1.042 1.08c1.066 1.028 2.968 1.865 5.318 1.865 2.295 0 3.916-.56 4.974-1.464a4.131 4.131 0 001.479-3.177c0-1.296-.608-2.316-1.538-3.066a5.77 5.77 0 00-.054-.043z"></path>` ); var link = toSvg( svg`<path d="M14.78 3.653a3.936 3.936 0 115.567 5.567l-3.627 3.627a3.936 3.936 0 01-5.88-.353.75.75 0 00-1.18.928 5.436 5.436 0 008.12.486l3.628-3.628a5.436 5.436 0 10-7.688-7.688l-3 3a.75.75 0 001.06 1.061l3-3z"></path> <path d="M7.28 11.153a3.936 3.936 0 015.88.353.75.75 0 001.18-.928 5.436 5.436 0 00-8.12-.486L2.592 13.72a5.436 5.436 0 107.688 7.688l3-3a.75.75 0 10-1.06-1.06l-3 3a3.936 3.936 0 01-5.567-5.568l3.627-3.627z"></path>` ); var heading = toSvg( svg`<path fill-rule="evenodd" d="M6.25 4a.75.75 0 01.75.75V11h10V4.75a.75.75 0 011.5 0v14.5a.75.75 0 01-1.5 0V12.5H7v6.75a.75.75 0 01-1.5 0V4.75A.75.75 0 016.25 4z"></path>` ); var blockQuote = toSvg( svg`<path d="M2.678 11.894a1 1 0 0 1 .287.801 10.97 10.97 0 0 1-.398 2c1.395-.323 2.247-.697 2.634-.893a1 1 0 0 1 .71-.074A8.06 8.06 0 0 0 8 14c3.996 0 7-2.807 7-6 0-3.192-3.004-6-7-6S1 4.808 1 8c0 1.468.617 2.83 1.678 3.894zm-.493 3.905a21.682 21.682 0 0 1-.713.129c-.2.032-.352-.176-.273-.362a9.68 9.68 0 0 0 .244-.637l.003-.01c.248-.72.45-1.548.524-2.319C.743 11.37 0 9.76 0 8c0-3.866 3.582-7 8-7s8 3.134 8 7-3.582 7-8 7a9.06 9.06 0 0 1-2.347-.306c-.52.263-1.639.742-3.468 1.105z" /> <path d="M7.066 6.76A1.665 1.665 0 0 0 4 7.668a1.667 1.667 0 0 0 2.561 1.406c-.131.389-.375.804-.777 1.22a.417.417 0 0 0 .6.58c1.486-1.54 1.293-3.214.682-4.112zm4 0A1.665 1.665 0 0 0 8 7.668a1.667 1.667 0 0 0 2.561 1.406c-.131.389-.375.804-.777 1.22a.417.417 0 0 0 .6.58c1.486-1.54 1.293-3.214.682-4.112z" />`, 16 ); var code = toSvg( svg` <path d="M10.478 1.647a.5.5 0 1 0-.956-.294l-4 13a.5.5 0 0 0 .956.294zM4.854 4.146a.5.5 0 0 1 0 .708L1.707 8l3.147 3.146a.5.5 0 0 1-.708.708l-3.5-3.5a.5.5 0 0 1 0-.708l3.5-3.5a.5.5 0 0 1 .708 0m6.292 0a.5.5 0 0 0 0 .708L14.293 8l-3.147 3.146a.5.5 0 0 0 .708.708l3.5-3.5a.5.5 0 0 0 0-.708l-3.5-3.5a.5.5 0 0 0-.708 0"/>`, 16 ); var codeBlock = toSvg( svg` <path d="M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z"/> <path d="M6.854 4.646a.5.5 0 0 1 0 .708L4.207 8l2.647 2.646a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 0 1 .708 0m2.292 0a.5.5 0 0 0 0 .708L11.793 8l-2.647 2.646a.5.5 0 0 0 .708.708l3-3a.5.5 0 0 0 0-.708l-3-3a.5.5 0 0 0-.708 0"/> `, 16 ); var bulletList = toSvg( svg`<path fill-rule="evenodd" d="M4 7a1 1 0 100-2 1 1 0 000 2zm4.75-1.5a.75.75 0 000 1.5h11.5a.75.75 0 000-1.5H8.75zm0 6a.75.75 0 000 1.5h11.5a.75.75 0 000-1.5H8.75zm0 6a.75.75 0 000 1.5h11.5a.75.75 0 000-1.5H8.75zM5 12a1 1 0 11-2 0 1 1 0 012 0zm-1 7a1 1 0 100-2 1 1 0 000 2z"></path>` ); var orderedList = toSvg(svg`<path d="M3.604 3.089A.75.75 0 014 3.75V8.5h.75a.75.75 0 010 1.5h-3a.75.75 0 110-1.5h.75V5.151l-.334.223a.75.75 0 01-.832-1.248l1.5-1a.75.75 0 01.77-.037zM8.75 5.5a.75.75 0 000 1.5h11.5a.75.75 0 000-1.5H8.75zm0 6a.75.75 0 000 1.5h11.5a.75.75 0 000-1.5H8.75zm0 6a.75.75 0 000 1.5h11.5a.75.75 0 000-1.5H8.75zM5.5 15.75c0-.704-.271-1.286-.72-1.686a2.302 2.302 0 00-1.53-.564c-.535 0-1.094.178-1.53.565-.449.399-.72.982-.72 1.685a.75.75 0 001.5 0c0-.296.104-.464.217-.564A.805.805 0 013.25 15c.215 0 .406.072.533.185.113.101.217.268.217.565 0 .332-.069.48-.21.657-.092.113-.216.24-.403.419l-.147.14c-.152.144-.33.313-.52.504l-1.5 1.5a.75.75 0 00-.22.53v.25c0 .414.336.75.75.75H5A.75.75 0 005 19H3.31l.47-.47c.176-.176.333-.324.48-.465l.165-.156a5.98 5.98 0 00.536-.566c.358-.447.539-.925.539-1.593z"></path>`); var attachFiles = toSvg( svg`<path d="M4.5 3a2.5 2.5 0 0 1 5 0v9a1.5 1.5 0 0 1-3 0V5a.5.5 0 0 1 1 0v7a.5.5 0 0 0 1 0V3a1.5 1.5 0 1 0-3 0v9a2.5 2.5 0 0 0 5 0V5a.5.5 0 0 1 1 0v7a3.5 3.5 0 1 1-7 0V3z" />`, 16 ); var undo = toSvg( svg`<path fill-rule="evenodd" d="M14.5 1.5a.5.5 0 0 1 .5.5v4.8a2.5 2.5 0 0 1-2.5 2.5H2.707l3.347 3.346a.5.5 0 0 1-.708.708l-4.2-4.2a.5.5 0 0 1 0-.708l4-4a.5.5 0 1 1 .708.708L2.707 8.3H12.5A1.5 1.5 0 0 0 14 6.8V2a.5.5 0 0 1 .5-.5z" />`, 16 ); var redo = toSvg( svg`<path fill-rule="evenodd" d="M1.5 1.5A.5.5 0 0 0 1 2v4.8a2.5 2.5 0 0 0 2.5 2.5h9.793l-3.347 3.346a.5.5 0 0 0 .708.708l4.2-4.2a.5.5 0 0 0 0-.708l-4-4a.5.5 0 0 0-.708.708L13.293 8.3H3.5A1.5 1.5 0 0 1 2 6.8V2a.5.5 0 0 0-.5-.5z" />`, 16 ); var closeSvgPath = svg`<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z" />`; var close = toSvg(closeSvgPath, 16); var increaseIndentation = toSvg( svg`<path d="M2 3.5a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5zm.646 2.146a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1 0 .708l-2 2a.5.5 0 0 1-.708-.708L4.293 8 2.646 6.354a.5.5 0 0 1 0-.708zM7 6.5a.5.5 0 0 1 .5-.5h6a.5.5 0 0 1 0 1h-6a.5.5 0 0 1-.5-.5zm0 3a.5.5 0 0 1 .5-.5h6a.5.5 0 0 1 0 1h-6a.5.5 0 0 1-.5-.5zm-5 3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/>`, 16 ); var decreaseIndentation = toSvg( svg`<path d="M2 3.5a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5zm10.646 2.146a.5.5 0 0 1 .708.708L11.707 8l1.647 1.646a.5.5 0 0 1-.708.708l-2-2a.5.5 0 0 1 0-.708l2-2zM2 6.5a.5.5 0 0 1 .5-.5h6a.5.5 0 0 1 0 1h-6a.5.5 0 0 1-.5-.5zm0 3a.5.5 0 0 1 .5-.5h6a.5.5 0 0 1 0 1h-6a.5.5 0 0 1-.5-.5zm0 3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/>`, 16 ); var warningSvgPath = svg` <path d="M7.938 2.016A.13.13 0 0 1 8.002 2a.13.13 0 0 1 .063.016.15.15 0 0 1 .054.057l6.857 11.667c.036.06.035.124.002.183a.2.2 0 0 1-.054.06.1.1 0 0 1-.066.017H1.146a.1.1 0 0 1-.066-.017.2.2 0 0 1-.054-.06.18.18 0 0 1 .002-.183L7.884 2.073a.15.15 0 0 1 .054-.057m1.044-.45a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767z"/> <path d="M7.002 12a1 1 0 1 1 2 0 1 1 0 0 1-2 0M7.1 5.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0z"/>`; var warning = toSvg(warningSvgPath, 16, []); // src/internal/to-memory-size.ts function toMemorySize(bytes) { const kilobytes = bytes / 1024; if (kilobytes < 1) { return bytes.toString() + "B"; } const megabytes = kilobytes / 1024; if (megabytes < 1) { return kilobytes.toFixed(0).toString() + " KB"; } return megabytes.toFixed(0).toString() + " MB"; } // src/internal/elements/base-element.ts import { LitElement } from "lit"; var BaseElement = class extends LitElement { static define(name, ctor, options) { if (name == null) name = this.baseName; if (ctor == null) ctor = this; if (this.customElementRegistry.get(name)) return; this.customElementRegistry.define(name, toAnonymousClass(ctor), options); } constructor() { super(); try { this.internals = this.attachInternals(); } catch (e) { console.error(e); } } addCustomState(state) { try { this.internals?.states.add(state); } catch (_e) { } } deleteCustomState(state) { try { this.internals?.states.delete(state); } catch (_e) { } } hasCustomState(state) { try { return this.internals?.states.has(state); } catch (_e) { return false; } } toggleCustomState(state, force) { if (force == null) { if (this.hasCustomState(state)) { this.deleteCustomState(state); } else { this.addCustomState(state); } return; } force === true ? this.addCustomState(state) : this.deleteCustomState(state); } }; BaseElement.customElementRegistry = window.customElements; function toAnonymousClass(klass) { return class extends klass { }; } // src/exports/elements/attachment-editor.ts import { when } from "lit/directives/when.js"; var LOADING_STATES = Object.freeze({ notStarted: "not-started", loading: "loading", error: "error", success: "success" }); var AttachmentEditor = class extends BaseElement { constructor() { super(); /** * Whether or not to enable the alt text editor for images on attachments. */ this.altTextEditor = false; this.altTextDialogOpen = false; this.altText = ""; this.imgSrc = ""; this.editorValue = null; this.handleClick = (e) => { if (e.defaultPrevented) { return; } const composedPath = e.composedPath(); const altTextButton = this.shadowRoot?.querySelector( "[part~='alt-text-button']" ); if (altTextButton && composedPath.includes(altTextButton)) { e.preventDefault(); this.setNodeAttributes({ altTextDialogOpen: this.altTextDialogOpen }); this.altTextDialogOpen = true; return; } if (!this.altTextDialogOpen) { return; } if (this.waitForDialogOpen) { return; } const dialog = this.shadowRoot?.querySelector("dialog"); if (!dialog) { return; } if (dialog && !composedPath.includes(dialog)) { this.altTextDialogOpen = false; this.setNodeAttributes({ altTextDialogOpen: this.altTextDialogOpen }); } }; this.handleKeydown = (e) => { if (!this.altTextDialogOpen) { return; } if (e.key === "Escape") { this.altTextDialogOpen = false; this.setNodeAttributes({ altTextDialogOpen: this.altTextDialogOpen }); } }; this.loadingState = "not-started"; this.fileUploadErrorMessage = fileUploadErrorMessage; this.waitForDialogOpen = false; this.altTextMaxLength = 2e3; this.altTextMinLength = 1; this.removeFigure = () => { }; this.setNodeAttributes = (_attrs) => { }; } closeIcon(parts = ["icon", "close-icon"]) { return html2`${toSvg(closeSvgPath, 16, parts)}`; } warningIcon() { return html2`${toSvg(warningSvgPath, 16, ["icon", "warning-icon"])}`; } static get properties() { return { fileName: { attribute: "file-name", type: String }, fileSize: { attribute: "file-size", type: Number }, progress: { type: Number }, class: { attribute: "class", type: String }, loadingState: { attribute: "loading-state" }, fileUploadErrorMessage: { state: true }, // This cannot reflect or ProseMirror overwrites it. altTextDialogOpen: { attribute: "show-alt-text-dialog", type: Boolean }, altTextMaxLength: { type: Number }, imgSrc: { attribute: "img-src" }, showMetadata: { attribute: "show-metadata", reflect: true, type: Boolean }, editorValue: {}, altText: { attribute: "alt-text" }, previewable: { reflect: true, type: Boolean } }; } connectedCallback() { super.connectedCallback(); this.classList.add("rhino-attachment-editor"); document.addEventListener("click", this.handleClick); document.addEventListener("keydown", this.handleKeydown); } firstUpdated(_changedProperties) { this.editorValue = this.altText; } disconnectedCallback() { super.disconnectedCallback(); document.removeEventListener("click", this.handleClick); document.removeEventListener("keydown", this.handleKeydown); } static get styles() { return css` ${normalize} :host { /* Set to none because we need height / width set. */ pointer-events: none; position: absolute; width: 100%; top: 0; left: 0; height: 100%; z-index: 0; --rhino-error-background-color: hsl(0 100% 89%); --rhino-error-text-color: hsl(0 66% 30%); --rhino-error-border-color: hsl(0 66% 30%); } * { pointer-events: initial; } button { background: Canvas; border: 2px solid var(--rhino-button-border-color); display: flex; align-items: center; pointer-events: all; padding: 0.4em 0.6em; } button:is(:focus-within) { border-color: var(--rhino-button-active-border-color); } button[part~="alt-text-save-button"] { display: block; margin: 0 auto; margin-top: 1rem; width: 50%; font-size: 1.15rem; text-align: center; border-radius: 8px; } button[part~="delete-button"] { position: absolute; top: 0; right: 50%; transform: translate(50%, -20px); border-radius: 9999px; padding: 0.15rem; border-color: Highlight; } :host(:not([previewable])) button[part~="alt-text-button"] { display: none; } :host(:state(image-error)) button[part~="alt-text-button"] { display: none; } button[part~="alt-text-button"] { position: absolute; top: 4px; left: 14px; background: rgba(0, 0, 0, 0.8); color: white; border: 2px solid white; border-radius: 4px; display: flex; flex-wrap: wrap; align-items: center; gap: 4px; } button[part~="alt-text-button"]:is(:focus-within, :focus, :hover):not( [aria-disabled="true"], :disabled ) { border-color: var(--rhino-button-active-border-color); background-color: rgba(0, 0, 0, 0.74); } :host(:state(invalid-alt-text)) [part~="alt-text-button"] { color: orange; border-color: orange; } button svg { flex: 1 1 auto; height: 1em; width: 1em; } button:is([part~="delete-button"], [part~="dialog-close-button"]) svg { height: 1.5rem; width: 1.5rem; } button:is(:disabled, [aria-disabled="true"]) { border-color: var(--rhino-button-border-color); color: var(--rhino-button-disabled-text-color); } button[part~="dialog-close-button"] { border-color: transparent; border-radius: 50%; outline-offset: 0 !important; padding: 0.1em; } button:is(:focus, :focus-within):not([aria-disabled="true"], :disabled) { outline: 2px solid var(--rhino-button-active-border-color); outline-offset: 3px; } button:is(:hover):not([aria-disabled="true"], :disabled) { background-color: var(--rhino-button-active-background-color); } .file-metadata { position: absolute; left: 50%; top: 2em; transform: translate(-50%, 0); display: flex; flex-wrap: wrap; align-items: center; justify-content: center; text-align: center; max-width: 90%; padding: 0.4rem 0.6rem; outline: 1px solid white; font-size: 0.8rem; color: #fff; background-color: hsla(0 0% 0% / 70%); border-radius: 3px; } .file-name { display: inline-block; max-width: 100%; vertical-align: bottom; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .file-size { margin-left: 0.2em; white-space: nowrap; } .file-progress-container { top: 50%; transform: translate(0px, -50%); left: 5%; width: 90%; position: absolute; z-index: 1; pointer-events: none; } .file-progress { --border-radius: 8px; --progress-value-color: blue; --progress-background-color: #eee; height: 10px; padding: 0; margin: 0; opacity: 0.9; width: 100%; transition: opacity 200ms ease-out visibility 200ms ease-out; border-radius: var(--border-radius); background-color: var(--progress-background-color); border: 1px solid gray; } progress::-webkit-progress-bar { background-color: var(--progress-background-color); border-radius: var(--border-radius); } progress::-webkit-progress-value { background-color: var(--progress-value-color); border-radius: var(--border-radius); } progress::-moz-progress-bar { /* style rules */ border-radius: var(--border-radius); background-color: var(--progress-value-color); } :host([loading-state="error"]) .file-progress-error { background-color: var(--rhino-error-background-color); color: var(--rhino-error-text-color); border: 1px solid var(--rhino-error-border-color); padding: 0.4em 0.6em; margin-top: 0.25rem; display: inline-block; border-radius: 8px; } :host([loading-state="error"]) .file-progress { background-color: var(--rhino-error-background-color); border-color: var(--rhino-error-border-color); } .file-progress[value="100"] { opacity: 0; visibility: hidden; } dialog::backdrop { background: rgba(0, 0, 0, 0.8); } dialog[open]::backdrop { pointer-events: none; } dialog { border: 1px solid gray; border-radius: 4px; width: clamp(200px, 75vw, 800px); } img { display: block; height: auto; width: 100%; /* Image is scaled to fit within the container. */ /* Aspect ratio IS maintained */ object-fit: contain; aspect-ratio: 16 / 9; background: lightgray; border: 2px solid gray; border-radius: 8px; } textarea { width: 100%; resize: none; height: 100px; font-size: 1.25em; border: 1px solid var(--rhino-border-color); padding: 8px; border-radius: 8px; } label { margin-top: 1rem; display: block; text-align: start; } textarea:focus { border-color: dodgerblue; outline: 2px solid var(--rhino-button-active-border-color); outline-offset: 3px; } [part~="dialog-heading"] { font-size: 1.5rem; margin: 0; } [part~="dialog-heading-wrapper"] { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 8px; } [part~="alt-text-editor-label"] { display: flex; justify-content: space-between; align-items: baseline; } `; } toFileSize() { if (this.fileSize) return toMemorySize(this.fileSize); return ""; } updated(changedProperties) { if (changedProperties.has("altTextDialogOpen")) { const dialog = this.shadowRoot?.querySelector("dialog"); if (dialog) { try { this.altTextDialogOpen ? dialog.showModal() : dialog.close(); } catch (_e) { } } } if (changedProperties.has("altText")) { if (this.altText.length >= this.altTextMinLength && this.altText.length <= this.altTextMaxLength) { this.deleteCustomState("invalid-alt-text"); } else { this.addCustomState("invalid-alt-text"); } } return super.updated(changedProperties); } render() { return html2` <button class="delete-button" part="button delete-button" @pointerdown=${(e) => { e.preventDefault(); this.removeFigure(); }} type="button" > ${this.closeIcon()} </button> ${when( this.altTextEditor, () => html2` ${this.renderAltTextButton()} ${this.renderAltTextDialog()} `, () => html2`` )} <span part="file-metadata" class="file-metadata" ?hidden=${!this.showMetadata || !(this.fileName || this.toFileSize())} > <span class="file-name" part="file-name">${this.fileName}</span> <br /> <span class="file-size" part="file-size">${this.toFileSize()}</span> </span> <div class="file-progress-container" part="file-progress-container"> <progress id="file-progress" class="file-progress" part="file-progress" value=${this.progress || 0} min="0" max="100" ></progress> <label for="file-progress" class="file-progress-error" part="file-progress-error" > ${this.loadingState === "error" ? this.fileUploadErrorMessage : null} </label> </div> `; } renderAltTextButton() { return html2` <button part="button alt-text-button" type="button" @pointerdown=${(e) => { e.preventDefault(); this.setNodeAttributes({ altTextDialogOpen: this.altTextDialogOpen }); this.altTextDialogOpen = true; this.waitForDialogOpen = true; setTimeout(() => { this.waitForDialogOpen = false; }, 200); }} > ${this.altText ? html2`` : this.warningIcon()} <span part="alt-text-button-label">Alt</span> </button> `; } renderAltTextDialog() { return html2` <dialog part="dialog" @close=${(e) => { if (e.target !== e.currentTarget) { return; } }} > <div part="dialog-heading-wrapper"> <h2 part="dialog-heading">Add alt text</h2> <button part="button dialog-close-button" @mousedown=${(e) => e.preventDefault()} @click=${(e) => { e.preventDefault(); this.altTextDialogOpen = false; this.setNodeAttributes({ altTextDialogOpen: this.altTextDialogOpen }); }} > ${this.closeIcon()} </button> </div> <img part="alt-text-image" src="${this.imgSrc}" @load=${() => { this.deleteCustomState("image-error"); }} @error=${() => { this.addCustomState("image-error"); }} /> <label part="alt-text-editor-label" for="alt-text-editor"> <span part="alt-text-editor-label-text"> Descriptive alt text </span> <span part="alt-text-editor-label-counter" >${this.editorValue?.length || 0} / ${this.altTextMaxLength}</span > </label> <textarea part="alt-text-editor" id="alt-text-editor" .value=${this.altText} @input=${(e) => this.editorValue = e.currentTarget.value} maxlength="${this.altTextMaxLength}" minlength="${this.altTextMinLength}" ></textarea> <button part="button alt-text-save-button" type="button" @pointerdown=${(e) => { if (e.currentTarget.ariaDisabled === "true") { return; } e.preventDefault(); }} @click=${(e) => { if (e.currentTarget.ariaDisabled === "true") { return; } e.preventDefault(); const altText = this.shadowRoot?.querySelector("textarea")?.value || ""; this.altText = altText; this.altTextDialogOpen = false; this.setNodeAttributes({ alt: this.altText, altTextDialogOpen: this.altTextDialogOpen }); }} aria-disabled="${(this.editorValue?.length || 0) > this.altTextMaxLength || (this.editorValue?.length || 0) < this.altTextMinLength}}" > Save </button> </dialog> `; } }; AttachmentEditor.baseName = "rhino-attachment-editor"; export { BaseElement, icons_exports, toMemorySize, LOADING_STATES, AttachmentEditor }; //# sourceMappingURL=chunk-KCKEIVYI.js.map