rhino-editor
Version:
A custom element wrapped rich text editor
761 lines (714 loc) • 25.8 kB
JavaScript
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 ;
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