rhino-editor
Version:
A custom element wrapped rich text editor
1,594 lines (1,572 loc) • 150 kB
JavaScript
import {
TipTapEditorBase
} from "./chunk-ZJHDHSSD.js";
import {
toolbarButtonStyles
} from "./chunk-6LK3B3JM.js";
import {
findNodeViewAnchor
} from "./chunk-V5KR23GU.js";
import {
e,
i,
o,
t
} from "./chunk-SDYFI7HW.js";
import {
getNodeType,
isNodeSelection,
objectIncludes,
posToDOMRect
} from "./chunk-4CJ3F2XK.js";
import {
icons_exports
} from "./chunk-IXVACZYD.js";
import {
isiOS,
translations
} from "./chunk-K6EXO3UJ.js";
import {
E,
T,
Z,
i as i2,
i2 as i3,
x
} from "./chunk-6JX5B4GC.js";
import {
__publicField
} from "./chunk-UM27USL5.js";
// node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/directive-helpers.js
var { I: t2 } = Z;
var f = (o4) => void 0 === o4.strings;
// node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/async-directive.js
var s = (i4, t3) => {
const e4 = i4._$AN;
if (void 0 === e4) return false;
for (const i5 of e4) i5._$AO?.(t3, false), s(i5, t3);
return true;
};
var o2 = (i4) => {
let t3, e4;
do {
if (void 0 === (t3 = i4._$AM)) break;
e4 = t3._$AN, e4.delete(i4), i4 = t3;
} while (0 === e4?.size);
};
var r = (i4) => {
for (let t3; t3 = i4._$AM; i4 = t3) {
let e4 = t3._$AN;
if (void 0 === e4) t3._$AN = e4 = /* @__PURE__ */ new Set();
else if (e4.has(i4)) break;
e4.add(i4), c(t3);
}
};
function h(i4) {
void 0 !== this._$AN ? (o2(this), this._$AM = i4, r(this)) : this._$AM = i4;
}
function n(i4, t3 = false, e4 = 0) {
const r2 = this._$AH, h3 = this._$AN;
if (void 0 !== h3 && 0 !== h3.size) if (t3) if (Array.isArray(r2)) for (let i5 = e4; i5 < r2.length; i5++) s(r2[i5], false), o2(r2[i5]);
else null != r2 && (s(r2, false), o2(r2));
else s(this, i4);
}
var c = (i4) => {
i4.type == t.CHILD && (i4._$AP ?? (i4._$AP = n), i4._$AQ ?? (i4._$AQ = h));
};
var f2 = class extends i {
constructor() {
super(...arguments), this._$AN = void 0;
}
_$AT(i4, t3, e4) {
super._$AT(i4, t3, e4), r(this), this.isConnected = i4._$AU;
}
_$AO(i4, t3 = true) {
i4 !== this.isConnected && (this.isConnected = i4, i4 ? this.reconnected?.() : this.disconnected?.()), t3 && (s(this, i4), o2(this));
}
setValue(t3) {
if (f(this._$Ct)) this._$Ct._$AI(t3, this);
else {
const i4 = [...this._$Ct._$AH];
i4[this._$Ci] = t3, this._$Ct._$AI(i4, this, 0);
}
}
disconnected() {
}
reconnected() {
}
};
// node_modules/.pnpm/lit-html@3.3.1/node_modules/lit-html/directives/ref.js
var e2 = () => new h2();
var h2 = class {
};
var o3 = /* @__PURE__ */ new WeakMap();
var n2 = e(class extends f2 {
render(i4) {
return E;
}
update(i4, [s2]) {
const e4 = s2 !== this.G;
return e4 && void 0 !== this.G && this.rt(void 0), (e4 || this.lt !== this.ct) && (this.G = s2, this.ht = i4.options?.host, this.rt(this.ct = i4.element)), E;
}
rt(t3) {
if (this.isConnected || (t3 = void 0), "function" == typeof this.G) {
const i4 = this.ht ?? globalThis;
let s2 = o3.get(i4);
void 0 === s2 && (s2 = /* @__PURE__ */ new WeakMap(), o3.set(i4, s2)), void 0 !== s2.get(this.G) && this.G.call(this.ht, void 0), s2.set(this.G, t3), void 0 !== t3 && this.G.call(this.ht, t3);
} else this.G.value = t3;
}
get lt() {
return "function" == typeof this.G ? o3.get(this.ht ?? globalThis)?.get(this.G) : this.G?.value;
}
disconnected() {
this.lt === this.ct && this.rt(void 0);
}
reconnected() {
this.rt(this.ct);
}
});
// node_modules/.pnpm/web-component-define@2.0.11/node_modules/web-component-define/src/internal/defineable-mixin.js
function DefineableMixin(superclass) {
var _a;
return _a = class extends superclass {
/**
* @param {null | undefined | string} [name=this.baseName]
* @param {null | undefined | CustomElementConstructor} [ctor=this]
* @param {ElementDefinitionOptions | undefined} [options]
*/
static define(name, ctor, options) {
if (!name) name = this.baseName;
if (!ctor) ctor = this;
let registry = window.customElements;
if (this.__registry instanceof CustomElementRegistry) {
registry = this.__registry;
}
const alreadyExists = Boolean(registry.get(name));
if (alreadyExists && this.warnOnExistingElement) {
console.warn(`${name} has already been registered.`);
}
if (!alreadyExists && ctor) {
registry.define(name, class extends ctor {
}, options);
}
}
}, /**
* The tag name to register your custom element under.
* @type {string}
*/
__publicField(_a, "baseName", ""), /**
* Emits a console warning if the name for an element is already taken.
* @type {boolean}
*/
__publicField(_a, "warnOnExistingElement", false), _a;
}
var DefineableElement = class extends DefineableMixin(HTMLElement) {
};
// node_modules/.pnpm/@open-wc+dedupe-mixin@1.4.0/node_modules/@open-wc/dedupe-mixin/src/dedupeMixin.js
var appliedClassMixins = /* @__PURE__ */ new WeakMap();
function wasMixinPreviouslyApplied(mixin, superClass) {
let klass = superClass;
while (klass) {
if (appliedClassMixins.get(klass) === mixin) {
return true;
}
klass = Object.getPrototypeOf(klass);
}
return false;
}
function dedupeMixin(mixin) {
return (superClass) => {
if (wasMixinPreviouslyApplied(mixin, superClass)) {
return superClass;
}
const mixedClass = mixin(superClass);
appliedClassMixins.set(mixedClass, mixin);
return mixedClass;
};
}
// node_modules/.pnpm/web-component-define@2.0.11/node_modules/web-component-define/src/internal/scoped-elements-mixin.js
var supportsScopedRegistry = !!ShadowRoot.prototype.createElement;
var ScopedElementsMixinImplementation = (superclass) => {
var _a;
return _a = class extends superclass {
/**
* Obtains the scoped elements definitions map if specified.
*
* @returns {ScopedElementsMap}
*/
static get scopedElements() {
return {};
}
/**
* Obtains the ShadowRoot options.
*
* @type {ShadowRootInit}
*/
static get shadowRootOptions() {
return this.__shadowRootOptions || { mode: "open" };
}
/**
* Set the shadowRoot options.
*
* @param {ShadowRootInit} value
*/
static set shadowRootOptions(value) {
this.__shadowRootOptions = value;
}
/**
* @param {any[]} args
*/
constructor(...args) {
super(...args);
this.renderOptions = this.renderOptions || void 0;
}
/**
* Obtains the CustomElementRegistry associated to the ShadowRoot.
*
* @returns {CustomElementRegistry}
*/
get registry() {
const constructor = this.constructor;
return constructor.__registry;
}
/**
* Set the CustomElementRegistry associated to the ShadowRoot
*
* @param {CustomElementRegistry} registry
*/
set registry(registry) {
const constructor = this.constructor;
constructor.__registry = registry;
}
createRenderRoot() {
const constructor = this.constructor;
const { scopedElements, shadowRootOptions } = constructor;
const shouldCreateRegistry = !this.registry || this.registry === constructor.__registry && !Object.prototype.hasOwnProperty.call(this.constructor, "__registry");
if (shouldCreateRegistry) {
this.registry = supportsScopedRegistry ? new CustomElementRegistry() : customElements;
for (const [tagName, klass] of Object.entries(scopedElements)) {
this.defineScopedElement(tagName, klass);
}
}
const options = {
// @ts-expect-error multiple assignment. Sue me.
mode: "open",
...shadowRootOptions,
customElements: this.registry
};
const createdRoot = this.attachShadow(options);
if (supportsScopedRegistry) {
this.renderOptions.creationScope = createdRoot;
}
if (createdRoot instanceof ShadowRoot) {
this.adoptStyles(createdRoot);
}
return createdRoot;
}
/**
* @param {string} tagName
*/
createScopedElement(tagName) {
const root = supportsScopedRegistry ? this.shadowRoot : document;
return root.createElement(tagName);
}
/**
* Hook for attaching constructable stylesheets to a render root.
* Used in the {LitScopedElementsMixin} .
* @param {ShadowRoot} _shadowRoot
* @returns {void}
*/
adoptStyles(_shadowRoot) {
}
/**
* Defines a scoped element.
*
* @param {string} tagName
* @param {typeof HTMLElement} klass
*/
defineScopedElement(tagName, klass) {
const registeredClass = this.registry.get(tagName);
if (registeredClass && supportsScopedRegistry === false && registeredClass !== klass) {
console.error(
[
`You are trying to re-register the "${tagName}" custom element with a different class via ScopedElementsMixin.`,
"This is only possible with a CustomElementRegistry.",
"Your browser does not support this feature so you will need to load a polyfill for it.",
'Load "@webcomponents/scoped-custom-element-registry" before you register ANY web component to the global customElements registry.',
'e.g. add "<script src="/node_modules/@webcomponents/scoped-custom-element-registry/scoped-custom-element-registry.min.js"><\/script>" as your first script tag.',
"For more details you can visit https://open-wc.org/docs/development/scoped-elements/"
].join("\n")
);
}
if (!registeredClass) {
return this.registry.define(tagName, klass);
}
return this.registry.get(tagName);
}
}, /**
* @protected
* @type {CustomElementRegistry}
*/
__publicField(_a, "__registry", window.customElements), _a;
};
var ScopedElementsMixin = dedupeMixin(ScopedElementsMixinImplementation);
// node_modules/.pnpm/web-component-define@2.0.11/node_modules/web-component-define/src/internal/create-render-root-mixin.js
var CreateRenderRootMixinImplementation = (superclass) => {
return class CreateRenderRootHost extends superclass {
/**
* Obtains the ShadowRoot options.
*
* @type {ShadowRootInit}
*/
static get shadowRootOptions() {
return this.__shadowRootOptions || { mode: "open" };
}
/**
* Set the shadowRoot options.
*
* @param {ShadowRootInit} value
*/
static set shadowRootOptions(value) {
this.__shadowRootOptions = value;
}
/** @type {ShadowRootInit} */
get shadowRootOptions() {
return this.constructor.shadowRootOptions;
}
createRenderRoot() {
const renderRoot = this.shadowRoot ?? this.attachShadow(this.shadowRootOptions || { mode: "open" });
return renderRoot;
}
connectedCallback() {
if (typeof super.connectedCallback === "function") {
super.connectedCallback();
}
if (this.renderRoot == null) {
this.renderRoot = this.createRenderRoot();
}
}
};
};
var CreateRenderRootMixin = dedupeMixin(CreateRenderRootMixinImplementation);
// node_modules/.pnpm/role-components@3.1.0/node_modules/role-components/internal/uuid.js
function uuidv4() {
const crypto = window.crypto || window.msCrypto;
return ("10000000-1000-4000-8000" + -1e11).replace(
/[018]/g,
(c2) => (c2 ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c2 / 4).toString(16)
);
}
// node_modules/.pnpm/role-components@3.1.0/node_modules/role-components/internal/language-observer.js
var _LanguageObserver = class _LanguageObserver {
/**
* @param {HTMLElement} element
*/
constructor(element) {
this.element = element;
this.handleLangChange = () => {
};
this.handleDirChange = () => {
};
this.__handleLangChange = () => this.handleLangChange();
this.__handleDirChange = () => this.handleDirChange();
this.constructor.eventTarget.addEventListener("lang-change", this.__handleLangChange);
this.constructor.eventTarget.addEventListener("dir-change", this.__handleDirChange);
}
start() {
const ctor = (
/** @type {typeof LanguageObserver} */
this.constructor
);
ctor.observer.observe(document.documentElement, ctor.options);
const host = this.element.getRootNode().host;
if (host) {
ctor.observer.observe(host, ctor.options);
}
return this;
}
stop() {
;
this.constructor.observer.disconnect();
return this;
}
};
/**
* @type {MutationObserverInit}
*/
__publicField(_LanguageObserver, "options", {
subtree: true,
attributes: true,
childList: true,
attributeFilter: ["lang", "dir"],
attributeOldValue: true
});
/**
* @type {null | ReturnType<typeof setTimeout>}
*/
__publicField(_LanguageObserver, "langTimeout", null);
/**
* @type {null | ReturnType<typeof setTimeout>}
*/
__publicField(_LanguageObserver, "dirTimeout", null);
__publicField(_LanguageObserver, "eventTarget", new EventTarget());
__publicField(_LanguageObserver, "observer", new MutationObserver((mutationList) => {
for (const mutation of mutationList) {
if (mutation.type === "attributes") {
if (mutation.attributeName === "lang") {
if (_LanguageObserver.langTimeout) {
clearTimeout(_LanguageObserver.langTimeout);
}
_LanguageObserver.langTimeout = setTimeout(() => {
_LanguageObserver.eventTarget.dispatchEvent(new Event("lang-change"));
}, 20);
}
if (mutation.attributeName === "dir") {
if (_LanguageObserver.dirTimeout) {
clearTimeout(_LanguageObserver.dirTimeout);
}
_LanguageObserver.dirTimeout = setTimeout(() => {
_LanguageObserver.eventTarget.dispatchEvent(new Event("dir-change"));
}, 20);
}
}
}
}));
var LanguageObserver = _LanguageObserver;
// node_modules/.pnpm/role-components@3.1.0/node_modules/role-components/internal/base-element.js
var EventHandler = class {
/**
* @param {T} element
*/
constructor(element) {
this.element = element;
this.events = /* @__PURE__ */ new WeakMap();
}
/**
* @param {EventHandlerFunction} fn
*/
get(fn) {
let handler = this.events.get(fn);
if (!handler) {
handler = (...args) => fn.apply(this.element, args);
this.events.set(fn, handler);
}
return handler;
}
};
var BaseElement = class extends DefineableMixin(i3) {
/**
* @type {Record<string, typeof HTMLElement>}
*/
static get dependencies() {
return {};
}
/**
* @param {...any[]} args
*/
constructor(...args) {
super(...args);
Object.entries(
/** @type {typeof BaseElement} */
this.constructor.dependencies
).forEach(([key, ctor]) => {
if (!customElements.get(key)) {
customElements.define(key, ctor);
}
});
this.textDirection = "ltr";
this.eventHandler = new EventHandler(this);
this.languageObserver = new LanguageObserver(this).start();
this.languageObserver.handleLangChange = () => {
const oldDirection = this.textDirection;
this.textDirection = this.getTextDirection();
this.requestUpdate("textDirection", oldDirection);
};
this.languageObserver.handleDirChange = () => {
const oldDirection = this.textDirection;
this.textDirection = this.getTextDirection();
this.requestUpdate("textDirection", oldDirection);
};
this.__debounceMap__ = null;
if (!this.internals) {
this.internals = this.attachInternals();
}
}
/**
* Assign a random UUID with a prefix if no id is found. Will return the "id" of the element if its already assigned.
* @param {string} [prefix=""] - Prefix to add to the uuid
* @param {boolean} [force=false] - If true, will not check if `this.id` already exists.
* @returns {string}
*/
getOrAssignId(prefix = "", force = false) {
let str = this.id;
if (!str || force) {
str = prefix + "-" + uuidv4();
this.id = str;
}
return str;
}
/**
* @returns {"ltr" | "rtl"}
*/
getTextDirection() {
return this.matches(":dir(rtl)") ? "rtl" : "ltr";
}
disconnectedCallback() {
super.disconnectedCallback();
this.__debounceMap__ = null;
}
/**
* @param {(...args: any[]) => any} callback
* @param {{ key: any, wait: number }} options
* @return {ReturnType<typeof setTimeout>}
*/
debounce(callback, options) {
if (this.__debounceMap__ == null) {
this.__debounceMap__ = /* @__PURE__ */ new Map();
}
let timeout = this.__debounceMap__.get(options.key);
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
callback();
}, options.wait);
this.__debounceMap__.set(options.key, timeout);
return timeout;
}
/**
* @template {keyof ARIAMixin} T
* @param {T} key
* @param {ARIAMixin[T]} value
*/
setAria(key, value) {
this.internals[key] = value;
this[key] = value;
}
};
// node_modules/.pnpm/role-components@3.1.0/node_modules/role-components/exports/styles/host-styles.js
var visuallyHiddenStr = i2`
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
`;
var hostStyles = i2`
:host {
--role-background-hover-color: #005a9c;
--role-border-focus-color: #005a9c;
display: block;
box-sizing: border-box;
}
*,
*:after,
*:before {
box-sizing: border-box;
}
[hidden] {
display: none !important;
}
[invisible] {
visibility: hidden !important;
}
[popover]:not(:popover-open):not(dialog[open]) {
display: none;
}
.visually-hidden:not(:focus-within):not(:active) {
${visuallyHiddenStr}
}
.always-visually-hidden {
${visuallyHiddenStr}
}
`;
// node_modules/.pnpm/role-components@3.1.0/node_modules/role-components/exports/components/toolbar/toolbar.js
var RoleToolbar = class extends BaseElement {
constructor() {
super();
this._currentFocusIndex = 0;
this.orientation = "horizontal";
this._toolbarItems = [];
this.orientation = "horizontal";
this.ignoreQuery = "textarea, select, input, [contenteditable='true'], [data-toolbar-ignore]";
this.addEventListener("click", this.eventHandler.get(this.handleClick));
this.addEventListener("keydown", this.eventHandler.get(this.handleKeyDown));
this.addEventListener("focus", this.eventHandler.get(this.handleClick));
}
/**
* @param {import("lit").PropertyValues<this>} changedProperties
*/
willUpdate(changedProperties) {
if (changedProperties.has("_toolbarItems")) {
this.updateToolbarItems();
}
if (changedProperties.has("orientation")) {
this.ariaOrientation = this.orientation;
}
super.willUpdate(changedProperties);
}
/** @returns {string} */
static get baseName() {
return "role-toolbar";
}
static get styles() {
return [
hostStyles,
i2`
.base {
display: flex;
max-width: 100%;
padding: 0.4rem 0.6rem;
border-radius: 4px;
border: 2px solid transparent;
gap: 4px;
overflow: auto;
}
:host([orientation="vertical"]) .base {
flex-direction: column;
}
:host(:focus-within) .base {
border-color: var(--role-border-focus-color);
}
`
];
}
/**
* @return {Record<string, (event: Event) => void>}
*/
get keydownHandlers() {
if (this._keydownHandlers) return this._keydownHandlers;
this._keydownHandlers = {
arrowleft: this.focusPrevious,
arrowup: this.focusPrevious,
arrowright: this.focusNext,
arrowdown: this.focusNext,
home: this.focusFirst,
end: this.focusLast
};
return this._keydownHandlers;
}
render() {
return x`
<div role="toolbar" class="base" part="base">
<slot @slotchange=${this.updateToolbarItems}></slot>
</div>
`;
}
/** @param {Event} event */
handleClick(event) {
let cancelEvent = false;
const focusedElement = event.composedPath().find((el) => {
if (el?.matches?.(this.ignoreQuery)) {
cancelEvent = true;
return;
}
const role = el?.getAttribute?.("data-role") || "";
return role.includes("toolbar-item");
});
if (cancelEvent) {
return;
}
if (focusedElement) {
this._toolbarItems.forEach((el, index) => {
if (el === focusedElement) {
this._currentFocusIndex = index;
return;
}
el.setAttribute("tabindex", "-1");
});
this.setTabIndex({ focus: false });
} else {
this.setTabIndex({ focus: true });
}
}
/** @param {KeyboardEvent} event */
handleKeyDown(event) {
const key = event.key?.toLowerCase();
if (this.orientation === "vertical" && (key === "arrowleft" || key === "arrowright"))
return;
if (this.orientation === "horizontal" && (key === "arrowdown" || key === "arrowup"))
return;
if (event.composedPath().find((el) => {
return el.matches?.(this.ignoreQuery);
})) {
return;
}
if (Object.keys(this.keydownHandlers).includes(key)) {
event.preventDefault();
this.keydownHandlers[key].call(this, event);
}
}
/** @param {Event} _event */
focusNext(_event) {
this.currentFocusElement?.setAttribute("tabindex", "-1");
this._currentFocusIndex += 1;
if (this._currentFocusIndex >= this._toolbarItems.length) {
this.focusFirst();
return;
}
this.setTabIndex();
}
/** @param {Event} _event */
focusPrevious(_event) {
this.currentFocusElement?.setAttribute("tabindex", "-1");
this._currentFocusIndex -= 1;
if (this._currentFocusIndex < 0) {
this.focusLast();
return;
}
this.setTabIndex();
}
focusFirst() {
this._currentFocusIndex = 0;
this.setTabIndex();
}
focusLast() {
if (this._toolbarItems == null) return;
this._currentFocusIndex = this._toolbarItems.length - 1;
this.setTabIndex();
}
setTabIndex({ focus = true } = {}) {
this.currentFocusElement?.setAttribute("tabindex", "0");
if (focus) {
this.currentFocusElement?.focus?.();
}
}
get currentFocusElement() {
if (this._toolbarItems == null) return;
return this._toolbarItems[this._currentFocusIndex];
}
/**
* @param {undefined | null | Event} [evt] - triggered by a slot change event.
*/
updateToolbarItems(evt) {
const slot = evt?.target || this.shadowRoot.querySelector("slot");
if (slot == null) return;
const items = slot.assignedElements({ flatten: true }).filter((el) => {
return el instanceof HTMLElement && el.dataset.role?.match(/toolbar-item/);
});
this._toolbarItems = items;
this._currentFocusIndex = this._toolbarItems.findIndex(
(el) => el.getAttribute("tabindex") === "0"
);
this._toolbarItems.forEach((el) => {
if (this._toolbarItems[this._currentFocusIndex] === el) return;
el.setAttribute("tabindex", "-1");
});
if (this._currentFocusIndex === -1) {
this._currentFocusIndex = 0;
this.currentFocusElement?.setAttribute("tabindex", "0");
}
}
};
__publicField(RoleToolbar, "properties", {
orientation: { reflect: true },
ariaOrientation: { reflect: true },
_currentFocusIndex: { state: true },
_toolbarItems: { state: true }
});
// node_modules/.pnpm/@floating-ui+utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs
var min = Math.min;
var max = Math.max;
var round = Math.round;
var floor = Math.floor;
var createCoords = (v) => ({
x: v,
y: v
});
var oppositeSideMap = {
left: "right",
right: "left",
bottom: "top",
top: "bottom"
};
var oppositeAlignmentMap = {
start: "end",
end: "start"
};
function clamp(start, value, end) {
return max(start, min(value, end));
}
function evaluate(value, param) {
return typeof value === "function" ? value(param) : value;
}
function getSide(placement) {
return placement.split("-")[0];
}
function getAlignment(placement) {
return placement.split("-")[1];
}
function getOppositeAxis(axis) {
return axis === "x" ? "y" : "x";
}
function getAxisLength(axis) {
return axis === "y" ? "height" : "width";
}
var yAxisSides = /* @__PURE__ */ new Set(["top", "bottom"]);
function getSideAxis(placement) {
return yAxisSides.has(getSide(placement)) ? "y" : "x";
}
function getAlignmentAxis(placement) {
return getOppositeAxis(getSideAxis(placement));
}
function getAlignmentSides(placement, rects, rtl) {
if (rtl === void 0) {
rtl = false;
}
const alignment = getAlignment(placement);
const alignmentAxis = getAlignmentAxis(placement);
const length = getAxisLength(alignmentAxis);
let mainAlignmentSide = alignmentAxis === "x" ? alignment === (rtl ? "end" : "start") ? "right" : "left" : alignment === "start" ? "bottom" : "top";
if (rects.reference[length] > rects.floating[length]) {
mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
}
return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];
}
function getExpandedPlacements(placement) {
const oppositePlacement = getOppositePlacement(placement);
return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
}
function getOppositeAlignmentPlacement(placement) {
return placement.replace(/start|end/g, (alignment) => oppositeAlignmentMap[alignment]);
}
var lrPlacement = ["left", "right"];
var rlPlacement = ["right", "left"];
var tbPlacement = ["top", "bottom"];
var btPlacement = ["bottom", "top"];
function getSideList(side, isStart, rtl) {
switch (side) {
case "top":
case "bottom":
if (rtl) return isStart ? rlPlacement : lrPlacement;
return isStart ? lrPlacement : rlPlacement;
case "left":
case "right":
return isStart ? tbPlacement : btPlacement;
default:
return [];
}
}
function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
const alignment = getAlignment(placement);
let list = getSideList(getSide(placement), direction === "start", rtl);
if (alignment) {
list = list.map((side) => side + "-" + alignment);
if (flipAlignment) {
list = list.concat(list.map(getOppositeAlignmentPlacement));
}
}
return list;
}
function getOppositePlacement(placement) {
return placement.replace(/left|right|bottom|top/g, (side) => oppositeSideMap[side]);
}
function expandPaddingObject(padding) {
return {
top: 0,
right: 0,
bottom: 0,
left: 0,
...padding
};
}
function getPaddingObject(padding) {
return typeof padding !== "number" ? expandPaddingObject(padding) : {
top: padding,
right: padding,
bottom: padding,
left: padding
};
}
function rectToClientRect(rect) {
const {
x: x2,
y,
width,
height
} = rect;
return {
width,
height,
top: y,
left: x2,
right: x2 + width,
bottom: y + height,
x: x2,
y
};
}
// node_modules/.pnpm/@floating-ui+core@1.7.3/node_modules/@floating-ui/core/dist/floating-ui.core.mjs
function computeCoordsFromPlacement(_ref, placement, rtl) {
let {
reference,
floating
} = _ref;
const sideAxis = getSideAxis(placement);
const alignmentAxis = getAlignmentAxis(placement);
const alignLength = getAxisLength(alignmentAxis);
const side = getSide(placement);
const isVertical = sideAxis === "y";
const commonX = reference.x + reference.width / 2 - floating.width / 2;
const commonY = reference.y + reference.height / 2 - floating.height / 2;
const commonAlign = reference[alignLength] / 2 - floating[alignLength] / 2;
let coords;
switch (side) {
case "top":
coords = {
x: commonX,
y: reference.y - floating.height
};
break;
case "bottom":
coords = {
x: commonX,
y: reference.y + reference.height
};
break;
case "right":
coords = {
x: reference.x + reference.width,
y: commonY
};
break;
case "left":
coords = {
x: reference.x - floating.width,
y: commonY
};
break;
default:
coords = {
x: reference.x,
y: reference.y
};
}
switch (getAlignment(placement)) {
case "start":
coords[alignmentAxis] -= commonAlign * (rtl && isVertical ? -1 : 1);
break;
case "end":
coords[alignmentAxis] += commonAlign * (rtl && isVertical ? -1 : 1);
break;
}
return coords;
}
var computePosition = async (reference, floating, config) => {
const {
placement = "bottom",
strategy = "absolute",
middleware = [],
platform: platform2
} = config;
const validMiddleware = middleware.filter(Boolean);
const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(floating));
let rects = await platform2.getElementRects({
reference,
floating,
strategy
});
let {
x: x2,
y
} = computeCoordsFromPlacement(rects, placement, rtl);
let statefulPlacement = placement;
let middlewareData = {};
let resetCount = 0;
for (let i4 = 0; i4 < validMiddleware.length; i4++) {
const {
name,
fn
} = validMiddleware[i4];
const {
x: nextX,
y: nextY,
data,
reset
} = await fn({
x: x2,
y,
initialPlacement: placement,
placement: statefulPlacement,
strategy,
middlewareData,
rects,
platform: platform2,
elements: {
reference,
floating
}
});
x2 = nextX != null ? nextX : x2;
y = nextY != null ? nextY : y;
middlewareData = {
...middlewareData,
[name]: {
...middlewareData[name],
...data
}
};
if (reset && resetCount <= 50) {
resetCount++;
if (typeof reset === "object") {
if (reset.placement) {
statefulPlacement = reset.placement;
}
if (reset.rects) {
rects = reset.rects === true ? await platform2.getElementRects({
reference,
floating,
strategy
}) : reset.rects;
}
({
x: x2,
y
} = computeCoordsFromPlacement(rects, statefulPlacement, rtl));
}
i4 = -1;
}
}
return {
x: x2,
y,
placement: statefulPlacement,
strategy,
middlewareData
};
};
async function detectOverflow(state, options) {
var _await$platform$isEle;
if (options === void 0) {
options = {};
}
const {
x: x2,
y,
platform: platform2,
rects,
elements,
strategy
} = state;
const {
boundary = "clippingAncestors",
rootBoundary = "viewport",
elementContext = "floating",
altBoundary = false,
padding = 0
} = evaluate(options, state);
const paddingObject = getPaddingObject(padding);
const altContext = elementContext === "floating" ? "reference" : "floating";
const element = elements[altBoundary ? altContext : elementContext];
const clippingClientRect = rectToClientRect(await platform2.getClippingRect({
element: ((_await$platform$isEle = await (platform2.isElement == null ? void 0 : platform2.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || await (platform2.getDocumentElement == null ? void 0 : platform2.getDocumentElement(elements.floating)),
boundary,
rootBoundary,
strategy
}));
const rect = elementContext === "floating" ? {
x: x2,
y,
width: rects.floating.width,
height: rects.floating.height
} : rects.reference;
const offsetParent = await (platform2.getOffsetParent == null ? void 0 : platform2.getOffsetParent(elements.floating));
const offsetScale = await (platform2.isElement == null ? void 0 : platform2.isElement(offsetParent)) ? await (platform2.getScale == null ? void 0 : platform2.getScale(offsetParent)) || {
x: 1,
y: 1
} : {
x: 1,
y: 1
};
const elementClientRect = rectToClientRect(platform2.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform2.convertOffsetParentRelativeRectToViewportRelativeRect({
elements,
rect,
offsetParent,
strategy
}) : rect);
return {
top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,
bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,
left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,
right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
};
}
var arrow = (options) => ({
name: "arrow",
options,
async fn(state) {
const {
x: x2,
y,
placement,
rects,
platform: platform2,
elements,
middlewareData
} = state;
const {
element,
padding = 0
} = evaluate(options, state) || {};
if (element == null) {
return {};
}
const paddingObject = getPaddingObject(padding);
const coords = {
x: x2,
y
};
const axis = getAlignmentAxis(placement);
const length = getAxisLength(axis);
const arrowDimensions = await platform2.getDimensions(element);
const isYAxis = axis === "y";
const minProp = isYAxis ? "top" : "left";
const maxProp = isYAxis ? "bottom" : "right";
const clientProp = isYAxis ? "clientHeight" : "clientWidth";
const endDiff = rects.reference[length] + rects.reference[axis] - coords[axis] - rects.floating[length];
const startDiff = coords[axis] - rects.reference[axis];
const arrowOffsetParent = await (platform2.getOffsetParent == null ? void 0 : platform2.getOffsetParent(element));
let clientSize = arrowOffsetParent ? arrowOffsetParent[clientProp] : 0;
if (!clientSize || !await (platform2.isElement == null ? void 0 : platform2.isElement(arrowOffsetParent))) {
clientSize = elements.floating[clientProp] || rects.floating[length];
}
const centerToReference = endDiff / 2 - startDiff / 2;
const largestPossiblePadding = clientSize / 2 - arrowDimensions[length] / 2 - 1;
const minPadding = min(paddingObject[minProp], largestPossiblePadding);
const maxPadding = min(paddingObject[maxProp], largestPossiblePadding);
const min$1 = minPadding;
const max2 = clientSize - arrowDimensions[length] - maxPadding;
const center = clientSize / 2 - arrowDimensions[length] / 2 + centerToReference;
const offset3 = clamp(min$1, center, max2);
const shouldAddOffset = !middlewareData.arrow && getAlignment(placement) != null && center !== offset3 && rects.reference[length] / 2 - (center < min$1 ? minPadding : maxPadding) - arrowDimensions[length] / 2 < 0;
const alignmentOffset = shouldAddOffset ? center < min$1 ? center - min$1 : center - max2 : 0;
return {
[axis]: coords[axis] + alignmentOffset,
data: {
[axis]: offset3,
centerOffset: center - offset3 - alignmentOffset,
...shouldAddOffset && {
alignmentOffset
}
},
reset: shouldAddOffset
};
}
});
var flip = function(options) {
if (options === void 0) {
options = {};
}
return {
name: "flip",
options,
async fn(state) {
var _middlewareData$arrow, _middlewareData$flip;
const {
placement,
middlewareData,
rects,
initialPlacement,
platform: platform2,
elements
} = state;
const {
mainAxis: checkMainAxis = true,
crossAxis: checkCrossAxis = true,
fallbackPlacements: specifiedFallbackPlacements,
fallbackStrategy = "bestFit",
fallbackAxisSideDirection = "none",
flipAlignment = true,
...detectOverflowOptions
} = evaluate(options, state);
if ((_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
return {};
}
const side = getSide(placement);
const initialSideAxis = getSideAxis(initialPlacement);
const isBasePlacement = getSide(initialPlacement) === initialPlacement;
const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating));
const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement));
const hasFallbackAxisSideDirection = fallbackAxisSideDirection !== "none";
if (!specifiedFallbackPlacements && hasFallbackAxisSideDirection) {
fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl));
}
const placements2 = [initialPlacement, ...fallbackPlacements];
const overflow = await detectOverflow(state, detectOverflowOptions);
const overflows = [];
let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];
if (checkMainAxis) {
overflows.push(overflow[side]);
}
if (checkCrossAxis) {
const sides2 = getAlignmentSides(placement, rects, rtl);
overflows.push(overflow[sides2[0]], overflow[sides2[1]]);
}
overflowsData = [...overflowsData, {
placement,
overflows
}];
if (!overflows.every((side2) => side2 <= 0)) {
var _middlewareData$flip2, _overflowsData$filter;
const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1;
const nextPlacement = placements2[nextIndex];
if (nextPlacement) {
const ignoreCrossAxisOverflow = checkCrossAxis === "alignment" ? initialSideAxis !== getSideAxis(nextPlacement) : false;
if (!ignoreCrossAxisOverflow || // We leave the current main axis only if every placement on that axis
// overflows the main axis.
overflowsData.every((d) => getSideAxis(d.placement) === initialSideAxis ? d.overflows[0] > 0 : true)) {
return {
data: {
index: nextIndex,
overflows: overflowsData
},
reset: {
placement: nextPlacement
}
};
}
}
let resetPlacement = (_overflowsData$filter = overflowsData.filter((d) => d.overflows[0] <= 0).sort((a, b) => a.overflows[1] - b.overflows[1])[0]) == null ? void 0 : _overflowsData$filter.placement;
if (!resetPlacement) {
switch (fallbackStrategy) {
case "bestFit": {
var _overflowsData$filter2;
const placement2 = (_overflowsData$filter2 = overflowsData.filter((d) => {
if (hasFallbackAxisSideDirection) {
const currentSideAxis = getSideAxis(d.placement);
return currentSideAxis === initialSideAxis || // Create a bias to the `y` side axis due to horizontal
// reading directions favoring greater width.
currentSideAxis === "y";
}
return true;
}).map((d) => [d.placement, d.overflows.filter((overflow2) => overflow2 > 0).reduce((acc, overflow2) => acc + overflow2, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$filter2[0];
if (placement2) {
resetPlacement = placement2;
}
break;
}
case "initialPlacement":
resetPlacement = initialPlacement;
break;
}
}
if (placement !== resetPlacement) {
return {
reset: {
placement: resetPlacement
}
};
}
}
return {};
}
};
};
var originSides = /* @__PURE__ */ new Set(["left", "top"]);
async function convertValueToCoords(state, options) {
const {
placement,
platform: platform2,
elements
} = state;
const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating));
const side = getSide(placement);
const alignment = getAlignment(placement);
const isVertical = getSideAxis(placement) === "y";
const mainAxisMulti = originSides.has(side) ? -1 : 1;
const crossAxisMulti = rtl && isVertical ? -1 : 1;
const rawValue = evaluate(options, state);
let {
mainAxis,
crossAxis,
alignmentAxis
} = typeof rawValue === "number" ? {
mainAxis: rawValue,
crossAxis: 0,
alignmentAxis: null
} : {
mainAxis: rawValue.mainAxis || 0,
crossAxis: rawValue.crossAxis || 0,
alignmentAxis: rawValue.alignmentAxis
};
if (alignment && typeof alignmentAxis === "number") {
crossAxis = alignment === "end" ? alignmentAxis * -1 : alignmentAxis;
}
return isVertical ? {
x: crossAxis * crossAxisMulti,
y: mainAxis * mainAxisMulti
} : {
x: mainAxis * mainAxisMulti,
y: crossAxis * crossAxisMulti
};
}
var offset = function(options) {
if (options === void 0) {
options = 0;
}
return {
name: "offset",
options,
async fn(state) {
var _middlewareData$offse, _middlewareData$arrow;
const {
x: x2,
y,
placement,
middlewareData
} = state;
const diffCoords = await convertValueToCoords(state, options);
if (placement === ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse.placement) && (_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
return {};
}
return {
x: x2 + diffCoords.x,
y: y + diffCoords.y,
data: {
...diffCoords,
placement
}
};
}
};
};
var shift = function(options) {
if (options === void 0) {
options = {};
}
return {
name: "shift",
options,
async fn(state) {
const {
x: x2,
y,
placement
} = state;
const {
mainAxis: checkMainAxis = true,
crossAxis: checkCrossAxis = false,
limiter = {
fn: (_ref) => {
let {
x: x3,
y: y2
} = _ref;
return {
x: x3,
y: y2
};
}
},
...detectOverflowOptions
} = evaluate(options, state);
const coords = {
x: x2,
y
};
const overflow = await detectOverflow(state, detectOverflowOptions);
const crossAxis = getSideAxis(getSide(placement));
const mainAxis = getOppositeAxis(crossAxis);
let mainAxisCoord = coords[mainAxis];
let crossAxisCoord = coords[crossAxis];
if (checkMainAxis) {
const minSide = mainAxis === "y" ? "top" : "left";
const maxSide = mainAxis === "y" ? "bottom" : "right";
const min2 = mainAxisCoord + overflow[minSide];
const max2 = mainAxisCoord - overflow[maxSide];
mainAxisCoord = clamp(min2, mainAxisCoord, max2);
}
if (checkCrossAxis) {
const minSide = crossAxis === "y" ? "top" : "left";
const maxSide = crossAxis === "y" ? "bottom" : "right";
const min2 = crossAxisCoord + overflow[minSide];
const max2 = crossAxisCoord - overflow[maxSide];
crossAxisCoord = clamp(min2, crossAxisCoord, max2);
}
const limitedCoords = limiter.fn({
...state,
[mainAxis]: mainAxisCoord,
[crossAxis]: crossAxisCoord
});
return {
...limitedCoords,
data: {
x: limitedCoords.x - x2,
y: limitedCoords.y - y,
enabled: {
[mainAxis]: checkMainAxis,
[crossAxis]: checkCrossAxis
}
}
};
}
};
};
var size = function(options) {
if (options === void 0) {
options = {};
}
return {
name: "size",
options,
async fn(state) {
var _state$middlewareData, _state$middlewareData2;
const {
placement,
rects,
platform: platform2,
elements
} = state;
const {
apply = () => {
},
...detectOverflowOptions
} = evaluate(options, state);
const overflow = await detectOverflow(state, detectOverflowOptions);
const side = getSide(placement);
const alignment = getAlignment(placement);
const isYAxis = getSideAxis(placement) === "y";
const {
width,
height
} = rects.floating;
let heightSide;
let widthSide;
if (side === "top" || side === "bottom") {
heightSide = side;
widthSide = alignment === (await (platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating)) ? "start" : "end") ? "left" : "right";
} else {
widthSide = side;
heightSide = alignment === "end" ? "top" : "bottom";
}
const maximumClippingHeight = height - overflow.top - overflow.bottom;
const maximumClippingWidth = width - overflow.left - overflow.right;
const overflowAvailableHeight = min(height - overflow[heightSide], maximumClippingHeight);
const overflowAvailableWidth = min(width - overflow[widthSide], maximumClippingWidth);
const noShift = !state.middlewareData.shift;
let availableHeight = overflowAvailableHeight;
let availableWidth = overflowAvailableWidth;
if ((_state$middlewareData = state.middlewareData.shift) != null && _state$middlewareData.enabled.x) {
availableWidth = maximumClippingWidth;
}
if ((_state$middlewareData2 = state.middlewareData.shift) != null && _state$middlewareData2.enabled.y) {
availableHeight = maximumClippingHeight;
}
if (noShift && !alignment) {
const xMin = max(overflow.left, 0);
const xMax = max(overflow.right, 0);
const yMin = max(overflow.top, 0);
const yMax = max(overflow.bottom, 0);
if (isYAxis) {
availableWidth = width - 2 * (xMin !== 0 || xMax !== 0 ? xMin + xMax : max(overflow.left, overflow.right));
} else {
availableHeight = height - 2 * (yMin !== 0 || yMax !== 0 ? yMin + yMax : max(overflow.top, overflow.bottom));
}
}
await apply({
...state,
availableWidth,
availableHeight
});
const nextDimensions = await platform2.getDimensions(elements.floating);
if (width !== nextDimensions.width || height !== nextDimensions.height) {
return {
reset: {
rects: true
}
};
}
return {};
}
};
};
// node_modules/.pnpm/@floating-ui+utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs
function hasWindow() {
return typeof window !== "undefined";
}
function getNodeName(node) {
if (isNode(node)) {
return (node.nodeName || "").toLowerCase();
}
return "#document";
}
function getWindow(node) {
var _node$ownerDocument;
return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
}
function getDocumentElement(node) {
var _ref;
return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
}
function isNode(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Node || value instanceof getWindow(value).Node;
}
function isElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Element || value instanceof getWindow(value).Element;
}
function isHTMLElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
}
function isShadowRoot(value) {
if (!hasWindow() || typeof ShadowRoot === "undefined") {
return false;
}
return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
}
var invalidOverflowDisplayValues = /* @__PURE__ */ new Set(["inline", "contents"]);
function isOverflowElement(element) {
const {
overflow,
overflowX,
overflowY,
display
} = getComputedStyle2(element);
return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !invalidOverflowDisplayValues.has(display);
}
var tableElements = /* @__PURE__ */ new Set(["table", "td", "th"]);
function isTableElement(element) {
return tableElements.has(getNodeName(element));
}
var topLayerSelectors = [":popover-open", ":modal"];
function isTopLayer(element) {
return topLayerSelectors.some((selector) => {
try {
return element.matches(selector);
} catch (_e) {
return false;
}
});
}
var transformProperties = ["transform", "translate", "scale", "rotate", "perspective"];
var willChangeValues = ["transform", "translate", "scale", "rotate", "perspective", "filter"];
var containValues = ["paint", "layout", "strict", "content"];
function isContainingBlock(elementOrCss) {
const webkit = isWebKit();
const css = isElement(elementOrCss) ? getComputedStyle2(elementOrCss) : elementOrCss;
return transformProperties.some((value) => css[value] ? css[value] !== "none" : false) || (css.containerType ? css.containerType !== "normal" : false) || !webkit && (css.backdropFilter ? css.backdropFilter !== "none" : false) || !webkit && (css.filter ? css.filter !== "none" : false) || willChangeValues.some((value) => (css.willChange || "").includes(value)) || containValues.some((value) => (css.contain || "").includes(value));
}
function getContainingBlock(element) {
let currentNode = getParentNode(element);
while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
if (isContainingBlock(currentNode)) {
return currentNode;
} else if (isTopLayer(currentNode)) {
return null;
}
currentNode = getParentNode(currentNode);
}
return null;
}
function isWebKit() {
if (typeof CSS === "undefined" || !CSS.supp