Convert the bundled backend/internal/plugins/smartblock package into a standalone reactor-mode wasm plugin: - package smartblock -> package main; add wasip1 main.go with wasmguest.Serve(Registration). - Add go.mod (module git.dev.alexdunmow.com/block/smartblock) pinning block/core v0.18.2; no replace directives. - Flesh out plugin.mod (scope=ninja, kind=plugin, categories, tags, display_name, description). - Point web/eslint.config.js at ../../../cms/web/eslint.config.js and switch @block-ninja/ui from workspace:* to the ^0.1.0 registry version; rebuild web/dist. - Add .gitignore (*.bnp, *.wasm, web/node_modules). Behavior unchanged: registers the "smart" block; assets served from web/dist. Builds to smartblock-1.0.0.bnp; check-safety passes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
14323 lines
456 KiB
JavaScript
14323 lines
456 KiB
JavaScript
import { importShared } from "./__federation_fn_import-hlt2XzeI.js";
|
|
import {
|
|
aa as a,
|
|
ab as f$1,
|
|
ac as ySyncPluginKey,
|
|
ad as getRelativeSelection,
|
|
ae as b,
|
|
af as f$2,
|
|
ag as isShadowRoot,
|
|
ah as isHTMLElement$1,
|
|
ai as useFloating$1,
|
|
aj as isElement,
|
|
ak as getOverflowAncestors,
|
|
al as isWebKit,
|
|
am as isLastTraversableNode,
|
|
an as getParentNode,
|
|
ao as getComputedStyle$1,
|
|
ap as getNodeName,
|
|
aq as $e$1,
|
|
ar as offset,
|
|
as as shift,
|
|
at as flip,
|
|
au as To$1,
|
|
av as m,
|
|
aw as Ao$1,
|
|
ax as D,
|
|
ay as b$1,
|
|
az as Yo,
|
|
aA as L$1,
|
|
aB as S$1,
|
|
aC as Bo$1,
|
|
aD as autoUpdate,
|
|
aE as No$1,
|
|
aF as Vn,
|
|
aG as _o$1,
|
|
aH as H$1,
|
|
aI as fo$1,
|
|
aJ as Ro$1,
|
|
aK as Vo$1,
|
|
aL as No$2,
|
|
aM as autoPlacement,
|
|
aN as size,
|
|
aO as Bt$2,
|
|
aP as Ao$2,
|
|
aQ as zo$1,
|
|
aR as A$1,
|
|
aS as D$1,
|
|
aT as Oe$1,
|
|
aU as Lo$1,
|
|
aV as R$1,
|
|
aW as h,
|
|
aX as $n,
|
|
aY as Cn,
|
|
$ as __vitePreload,
|
|
e as useCallbackRef,
|
|
f as useLayoutEffect2,
|
|
P as Primitive,
|
|
d as createContextScope,
|
|
aZ as Anchor,
|
|
u as useComposedRefs,
|
|
c as composeEventHandlers,
|
|
b as Presence,
|
|
a_ as Root2$2,
|
|
n as useId$1,
|
|
a as useDirection,
|
|
a$ as createPopperScope,
|
|
b0 as createRovingFocusGroupScope,
|
|
b1 as Item,
|
|
b2 as createCollection,
|
|
R as ReactRemoveScroll,
|
|
l as useFocusGuards,
|
|
F as FocusScope,
|
|
D as DismissableLayer,
|
|
b3 as Root$1,
|
|
b4 as Content,
|
|
b5 as dispatchDiscreteCustomEvent,
|
|
j as hideOthers,
|
|
k as createSlot,
|
|
b6 as Arrow,
|
|
m as useControllableState,
|
|
b7 as Root$2,
|
|
b8 as createSlottable,
|
|
T as Trigger$3,
|
|
L as List,
|
|
H as Content$1,
|
|
a6 as Root2$3,
|
|
a5 as SelectValue,
|
|
J as SelectTrigger,
|
|
K as SelectIcon,
|
|
X as SelectItem,
|
|
Y as SelectItemIndicator,
|
|
Z as SelectItemText,
|
|
Q as SelectContent,
|
|
U as SelectViewport,
|
|
a3 as Select,
|
|
I as Root$3,
|
|
S as Slot$2,
|
|
b9 as At$2,
|
|
a0 as twMerge,
|
|
a1 as clsx,
|
|
a2 as cva,
|
|
M as SelectScrollUpButton,
|
|
N as SelectScrollDownButton,
|
|
a9 as defaultSchema,
|
|
} from "./index-BSkdT-DR.js";
|
|
import { j as jsxRuntimeExports } from "./jsx-runtime-CvJTHeKY.js";
|
|
import { a as PluginKey, P as Plugin, D as DecorationSet, A as Decoration, R as Mark, m as mergeAttributes, Y as posToDOMRect } from "./index-Bs--Ol2m.js";
|
|
import { w as withSelectorExports } from "./with-selector-B2V6shWK.js";
|
|
import { r as requireReactDom } from "./index-eoEhLOdg.js";
|
|
|
|
var x = Object.defineProperty;
|
|
var Y = (r, d, e) => (d in r ? x(r, d, { enumerable: true, configurable: true, writable: true, value: e }) : (r[d] = e));
|
|
var c = (r, d, e) => Y(r, typeof d != "symbol" ? d + "" : d, e);
|
|
const M$2 = Mark.create({
|
|
name: "comment",
|
|
excludes: "",
|
|
inclusive: false,
|
|
keepOnSplit: true,
|
|
addAttributes() {
|
|
return {
|
|
// orphans are marks that currently don't have an active thread. It could be
|
|
// that users have resolved the thread. Resolved threads by default are not shown in the document,
|
|
// but we need to keep the mark (positioning) data so we can still "revive" it when the thread is unresolved
|
|
// or we enter a "comments" view that includes resolved threads.
|
|
orphan: {
|
|
parseHTML: (r) => !!r.getAttribute("data-orphan"),
|
|
renderHTML: (r) =>
|
|
r.orphan ?
|
|
{
|
|
"data-orphan": "true",
|
|
}
|
|
: {},
|
|
default: false,
|
|
},
|
|
threadId: {
|
|
parseHTML: (r) => r.getAttribute("data-bn-thread-id"),
|
|
renderHTML: (r) => ({
|
|
"data-bn-thread-id": r.threadId,
|
|
}),
|
|
default: "",
|
|
},
|
|
};
|
|
},
|
|
renderHTML({ HTMLAttributes: r }) {
|
|
return [
|
|
"span",
|
|
mergeAttributes(r, {
|
|
class: "bn-thread-mark",
|
|
}),
|
|
];
|
|
},
|
|
parseHTML() {
|
|
return [{ tag: "span.bn-thread-mark" }];
|
|
},
|
|
extendMarkSchema(r) {
|
|
return r.name === "comment" ?
|
|
{
|
|
blocknoteIgnore: true,
|
|
}
|
|
: {};
|
|
},
|
|
});
|
|
let F$2 = class F extends f$2 {
|
|
constructor(e) {
|
|
super();
|
|
c(this, "userCache", /* @__PURE__ */ new Map());
|
|
// avoid duplicate loads
|
|
c(this, "loadingUsers", /* @__PURE__ */ new Set());
|
|
this.resolveUsers = e;
|
|
}
|
|
/**
|
|
* Load information about users based on an array of user ids.
|
|
*/
|
|
async loadUsers(e) {
|
|
const t = e.filter((a) => !this.userCache.has(a) && !this.loadingUsers.has(a));
|
|
if (t.length !== 0) {
|
|
for (const a of t) this.loadingUsers.add(a);
|
|
try {
|
|
const a = await this.resolveUsers(t);
|
|
for (const s of a) this.userCache.set(s.id, s);
|
|
this.emit("update", this.userCache);
|
|
} finally {
|
|
for (const a of t) this.loadingUsers.delete(a);
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* Retrieve information about a user based on their id, if cached.
|
|
*
|
|
* The user will have to be loaded via `loadUsers` first
|
|
*/
|
|
getUser(e) {
|
|
return this.userCache.get(e);
|
|
}
|
|
/**
|
|
* Subscribe to changes in the user store.
|
|
*
|
|
* @param cb - The callback to call when the user store changes.
|
|
* @returns A function to unsubscribe from the user store.
|
|
*/
|
|
subscribe(e) {
|
|
return this.on("update", e);
|
|
}
|
|
};
|
|
const w$1 = new PluginKey("blocknote-comments");
|
|
function K(r, d) {
|
|
const e = /* @__PURE__ */ new Map();
|
|
return (
|
|
r.descendants((t, a) => {
|
|
t.marks.forEach((s) => {
|
|
if (s.type.name === d) {
|
|
const o = s.attrs.threadId;
|
|
if (!o) return;
|
|
const m = a,
|
|
n = m + t.nodeSize,
|
|
i = e.get(o) ?? {
|
|
from: 1 / 0,
|
|
to: 0,
|
|
};
|
|
e.set(o, {
|
|
from: Math.min(m, i.from),
|
|
to: Math.max(n, i.to),
|
|
});
|
|
}
|
|
});
|
|
}),
|
|
e
|
|
);
|
|
}
|
|
const ne$1 = a(({ editor: r, options: { schema: d, threadStore: e, resolveUsers: t } }) => {
|
|
if (!t) throw new Error("resolveUsers is required to be defined when using comments");
|
|
if (!e) throw new Error("threadStore is required to be defined when using comments");
|
|
const a = M$2.name,
|
|
s = new F$2(t),
|
|
o = f$1(
|
|
{
|
|
pendingComment: false,
|
|
selectedThreadId: void 0,
|
|
threadPositions: /* @__PURE__ */ new Map(),
|
|
},
|
|
{
|
|
onUpdate() {
|
|
o.state.selectedThreadId !== o.prevState.selectedThreadId && r.transact((n) => n.setMeta(w$1, true));
|
|
},
|
|
},
|
|
),
|
|
m = (n) => {
|
|
r.transact((i) => {
|
|
i.doc.descendants((u, l) => {
|
|
u.marks.forEach((h) => {
|
|
if (h.type.name === a) {
|
|
const T = h.type,
|
|
f = h.attrs.threadId,
|
|
A = n.get(f),
|
|
v = !!(!A || A.resolved || A.deletedAt);
|
|
if (v !== h.attrs.orphan) {
|
|
const E = Math.max(l, 0),
|
|
b = Math.min(l + u.nodeSize, i.doc.content.size - 1, i.doc.content.size - 1);
|
|
(i.removeMark(E, b, h),
|
|
i.addMark(
|
|
E,
|
|
b,
|
|
T.create({
|
|
...h.attrs,
|
|
orphan: v,
|
|
}),
|
|
),
|
|
v &&
|
|
o.state.selectedThreadId === f &&
|
|
o.setState((P) => ({
|
|
...P,
|
|
selectedThreadId: void 0,
|
|
})));
|
|
}
|
|
}
|
|
});
|
|
});
|
|
});
|
|
};
|
|
return {
|
|
key: "comments",
|
|
store: o,
|
|
prosemirrorPlugins: [
|
|
new Plugin({
|
|
key: w$1,
|
|
state: {
|
|
init() {
|
|
return {
|
|
decorations: DecorationSet.empty,
|
|
};
|
|
},
|
|
apply(n, i) {
|
|
const u = n.getMeta(w$1);
|
|
if (!n.docChanged && !u) return i;
|
|
const l = n.docChanged ? K(n.doc, a) : o.state.threadPositions;
|
|
(l.size > 0 || o.state.threadPositions.size > 0) &&
|
|
o.setState((T) => ({
|
|
...T,
|
|
threadPositions: l,
|
|
}));
|
|
const h = [];
|
|
if (o.state.selectedThreadId) {
|
|
const T = l.get(o.state.selectedThreadId);
|
|
T &&
|
|
h.push(
|
|
Decoration.inline(T.from, T.to, {
|
|
class: "bn-thread-mark-selected",
|
|
}),
|
|
);
|
|
}
|
|
return {
|
|
decorations: DecorationSet.create(n.doc, h),
|
|
};
|
|
},
|
|
},
|
|
props: {
|
|
decorations(n) {
|
|
var i;
|
|
return ((i = w$1.getState(n)) == null ? void 0 : i.decorations) ?? DecorationSet.empty;
|
|
},
|
|
handleClick: (n, i, u) => {
|
|
if (u.button !== 0) return;
|
|
const l = n.state.doc.nodeAt(i);
|
|
if (!l) {
|
|
o.setState((f) => ({
|
|
...f,
|
|
selectedThreadId: void 0,
|
|
}));
|
|
return;
|
|
}
|
|
const h = l.marks.find((f) => f.type.name === a && f.attrs.orphan !== true),
|
|
T = h == null ? void 0 : h.attrs.threadId;
|
|
T !== o.state.selectedThreadId &&
|
|
o.setState((f) => ({
|
|
...f,
|
|
selectedThreadId: T,
|
|
}));
|
|
},
|
|
},
|
|
}),
|
|
],
|
|
threadStore: e,
|
|
mount() {
|
|
const n = e.subscribe(m);
|
|
m(e.getThreads());
|
|
const i = r.onSelectionChange(() => {
|
|
o.state.pendingComment &&
|
|
o.setState((u) => ({
|
|
...u,
|
|
pendingComment: false,
|
|
}));
|
|
});
|
|
return () => {
|
|
(n(), i());
|
|
};
|
|
},
|
|
selectThread(n, i = true) {
|
|
var u, l;
|
|
if (
|
|
o.state.selectedThreadId !== n &&
|
|
(o.setState((h) => ({
|
|
...h,
|
|
pendingComment: false,
|
|
selectedThreadId: n,
|
|
})),
|
|
n && i)
|
|
) {
|
|
const h = o.state.threadPositions.get(n);
|
|
if (!h) return;
|
|
(l = (u = r.prosemirrorView) == null ? void 0 : u.domAtPos(h.from).node) == null ||
|
|
l.scrollIntoView({
|
|
behavior: "smooth",
|
|
block: "center",
|
|
});
|
|
}
|
|
},
|
|
startPendingComment() {
|
|
var n;
|
|
(o.setState((i) => ({
|
|
...i,
|
|
selectedThreadId: void 0,
|
|
pendingComment: true,
|
|
})),
|
|
(n = r.getExtension(b)) == null || n.showSelection(true, "comments"));
|
|
},
|
|
stopPendingComment() {
|
|
var n;
|
|
(o.setState((i) => ({
|
|
...i,
|
|
selectedThreadId: void 0,
|
|
pendingComment: false,
|
|
})),
|
|
(n = r.getExtension(b)) == null || n.showSelection(false, "comments"));
|
|
},
|
|
async createThread(n) {
|
|
const i = await e.createThread(n);
|
|
if (e.addThreadToDocument) {
|
|
const u = r.prosemirrorView,
|
|
l = u.state.selection,
|
|
h = ySyncPluginKey.getState(u.state),
|
|
T = {
|
|
prosemirror: {
|
|
head: l.head,
|
|
anchor: l.anchor,
|
|
},
|
|
yjs: h ? getRelativeSelection(h.binding, u.state) : void 0,
|
|
};
|
|
await e.addThreadToDocument({
|
|
threadId: i.id,
|
|
selection: T,
|
|
});
|
|
} else
|
|
r._tiptapEditor.commands.setMark(a, {
|
|
orphan: false,
|
|
threadId: i.id,
|
|
});
|
|
},
|
|
userStore: s,
|
|
commentEditorSchema: d,
|
|
tiptapExtensions: [M$2],
|
|
};
|
|
});
|
|
|
|
/*!
|
|
* tabbable 6.5.0
|
|
* @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
|
|
*/
|
|
// NOTE: separate `:not()` selectors has broader browser support than the newer
|
|
// `:not([inert], [inert] *)` (Feb 2023)
|
|
var candidateSelectors = [
|
|
"input:not([inert]):not([inert] *)",
|
|
"select:not([inert]):not([inert] *)",
|
|
"textarea:not([inert]):not([inert] *)",
|
|
"a[href]:not([inert]):not([inert] *)",
|
|
"area[href]:not([inert]):not([inert] *)",
|
|
"button:not([inert]):not([inert] *)",
|
|
"[tabindex]:not(slot):not([inert]):not([inert] *)",
|
|
"audio[controls]:not([inert]):not([inert] *)",
|
|
"video[controls]:not([inert]):not([inert] *)",
|
|
'[contenteditable]:not([contenteditable="false"]):not([inert]):not([inert] *)',
|
|
"details>summary:first-of-type:not([inert]):not([inert] *)",
|
|
"details:not([inert]):not([inert] *)",
|
|
];
|
|
var candidateSelector = /* #__PURE__ */ candidateSelectors.join(",");
|
|
var NoElement = typeof Element === "undefined";
|
|
var matches = NoElement ? function () {} : Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
|
|
var getRootNode =
|
|
!NoElement && Element.prototype.getRootNode ?
|
|
function (element) {
|
|
var _element$getRootNode;
|
|
return (
|
|
element === null || element === void 0 ? void 0
|
|
: (_element$getRootNode = element.getRootNode) === null || _element$getRootNode === void 0 ? void 0
|
|
: _element$getRootNode.call(element)
|
|
);
|
|
}
|
|
: function (element) {
|
|
return element === null || element === void 0 ? void 0 : element.ownerDocument;
|
|
};
|
|
|
|
/**
|
|
* Determines if a node is inert or in an inert ancestor.
|
|
* @param {Node} [node]
|
|
* @param {boolean} [lookUp] If true and `node` is not inert, looks up at ancestors to
|
|
* see if any of them are inert. If false, only `node` itself is considered.
|
|
* @returns {boolean} True if inert itself or by way of being in an inert ancestor.
|
|
* False if `node` is falsy.
|
|
*/
|
|
var _isInert = function isInert(node, lookUp) {
|
|
var _node$getAttribute;
|
|
if (lookUp === void 0) {
|
|
lookUp = true;
|
|
}
|
|
// CAREFUL: JSDom does not support inert at all, so we can't use the `HTMLElement.inert`
|
|
// JS API property; we have to check the attribute, which can either be empty or 'true';
|
|
// if it's `null` (not specified) or 'false', it's an active element
|
|
var inertAtt =
|
|
node === null || node === void 0 ? void 0
|
|
: (_node$getAttribute = node.getAttribute) === null || _node$getAttribute === void 0 ? void 0
|
|
: _node$getAttribute.call(node, "inert");
|
|
var inert = inertAtt === "" || inertAtt === "true";
|
|
|
|
// NOTE: this could also be handled with `node.matches('[inert], :is([inert] *)')`
|
|
// if it weren't for `matches()` not being a function on shadow roots; the following
|
|
// code works for any kind of node
|
|
var result =
|
|
inert ||
|
|
(lookUp &&
|
|
node &&
|
|
// closest does not exist on shadow roots, so we fall back to a manual
|
|
// lookup upward, in case it is not defined.
|
|
(typeof node.closest === "function" ? node.closest("[inert]") : _isInert(node.parentNode)));
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Determines if a node's content is editable.
|
|
* @param {Element} [node]
|
|
* @returns True if it's content-editable; false if it's not or `node` is falsy.
|
|
*/
|
|
var isContentEditable = function isContentEditable(node) {
|
|
var _node$getAttribute2;
|
|
// CAREFUL: JSDom does not support the `HTMLElement.isContentEditable` API so we have
|
|
// to use the attribute directly to check for this, which can either be empty or 'true';
|
|
// if it's `null` (not specified) or 'false', it's a non-editable element
|
|
var attValue =
|
|
node === null || node === void 0 ? void 0
|
|
: (_node$getAttribute2 = node.getAttribute) === null || _node$getAttribute2 === void 0 ? void 0
|
|
: _node$getAttribute2.call(node, "contenteditable");
|
|
return attValue === "" || attValue === "true";
|
|
};
|
|
|
|
/**
|
|
* @param {Element} el container to check in
|
|
* @param {boolean} includeContainer add container to check
|
|
* @param {(node: Element) => boolean} filter filter candidates
|
|
* @returns {Element[]}
|
|
*/
|
|
var getCandidates = function getCandidates(el, includeContainer, filter) {
|
|
// even if `includeContainer=false`, we still have to check it for inertness because
|
|
// if it's inert (either by itself or via its parent), then all its children are inert
|
|
if (_isInert(el)) {
|
|
return [];
|
|
}
|
|
var candidates = Array.prototype.slice.apply(el.querySelectorAll(candidateSelector));
|
|
if (includeContainer && matches.call(el, candidateSelector)) {
|
|
candidates.unshift(el);
|
|
}
|
|
candidates = candidates.filter(filter);
|
|
return candidates;
|
|
};
|
|
|
|
/**
|
|
* @callback GetShadowRoot
|
|
* @param {Element} element to check for shadow root
|
|
* @returns {ShadowRoot|boolean} ShadowRoot if available or boolean indicating if a shadowRoot is attached but not available.
|
|
*/
|
|
|
|
/**
|
|
* @callback ShadowRootFilter
|
|
* @param {Element} shadowHostNode the element which contains shadow content
|
|
* @returns {boolean} true if a shadow root could potentially contain valid candidates.
|
|
*/
|
|
|
|
/**
|
|
* @typedef {Object} CandidateScope
|
|
* @property {Element} scopeParent contains inner candidates
|
|
* @property {Element[]} candidates list of candidates found in the scope parent
|
|
*/
|
|
|
|
/**
|
|
* @typedef {Object} IterativeOptions
|
|
* @property {GetShadowRoot|boolean} getShadowRoot true if shadow support is enabled; falsy if not;
|
|
* if a function, implies shadow support is enabled and either returns the shadow root of an element
|
|
* or a boolean stating if it has an undisclosed shadow root
|
|
* @property {(node: Element) => boolean} filter filter candidates
|
|
* @property {boolean} flatten if true then result will flatten any CandidateScope into the returned list
|
|
* @property {ShadowRootFilter} shadowRootFilter filter shadow roots;
|
|
*/
|
|
|
|
/**
|
|
* @param {Element[]} elements list of element containers to match candidates from
|
|
* @param {boolean} includeContainer add container list to check
|
|
* @param {IterativeOptions} options
|
|
* @returns {Array.<Element|CandidateScope>}
|
|
*/
|
|
var _getCandidatesIteratively = function getCandidatesIteratively(elements, includeContainer, options) {
|
|
var candidates = [];
|
|
var elementsToCheck = Array.from(elements);
|
|
while (elementsToCheck.length) {
|
|
var element = elementsToCheck.shift();
|
|
if (_isInert(element, false)) {
|
|
// no need to look up since we're drilling down
|
|
// anything inside this container will also be inert
|
|
continue;
|
|
}
|
|
if (element.tagName === "SLOT") {
|
|
// add shadow dom slot scope (slot itself cannot be focusable)
|
|
var assigned = element.assignedElements();
|
|
var content = assigned.length ? assigned : element.children;
|
|
var nestedCandidates = _getCandidatesIteratively(content, true, options);
|
|
if (options.flatten) {
|
|
candidates.push.apply(candidates, nestedCandidates);
|
|
} else {
|
|
candidates.push({
|
|
scopeParent: element,
|
|
candidates: nestedCandidates,
|
|
});
|
|
}
|
|
} else {
|
|
// check candidate element
|
|
var validCandidate = matches.call(element, candidateSelector);
|
|
if (validCandidate && options.filter(element) && (includeContainer || !elements.includes(element))) {
|
|
candidates.push(element);
|
|
}
|
|
|
|
// iterate over shadow content if possible
|
|
var shadowRoot =
|
|
element.shadowRoot ||
|
|
// check for an undisclosed shadow
|
|
(typeof options.getShadowRoot === "function" && options.getShadowRoot(element));
|
|
|
|
// no inert look up because we're already drilling down and checking for inertness
|
|
// on the way down, so all containers to this root node should have already been
|
|
// vetted as non-inert
|
|
var validShadowRoot = !_isInert(shadowRoot, false) && (!options.shadowRootFilter || options.shadowRootFilter(element));
|
|
if (shadowRoot && validShadowRoot) {
|
|
// add shadow dom scope IIF a shadow root node was given; otherwise, an undisclosed
|
|
// shadow exists, so look at light dom children as fallback BUT create a scope for any
|
|
// child candidates found because they're likely slotted elements (elements that are
|
|
// children of the web component element (which has the shadow), in the light dom, but
|
|
// slotted somewhere _inside_ the undisclosed shadow) -- the scope is created below,
|
|
// _after_ we return from this recursive call
|
|
var _nestedCandidates = _getCandidatesIteratively(shadowRoot === true ? element.children : shadowRoot.children, true, options);
|
|
if (options.flatten) {
|
|
candidates.push.apply(candidates, _nestedCandidates);
|
|
} else {
|
|
candidates.push({
|
|
scopeParent: element,
|
|
candidates: _nestedCandidates,
|
|
});
|
|
}
|
|
} else {
|
|
// there's not shadow so just dig into the element's (light dom) children
|
|
// __without__ giving the element special scope treatment
|
|
elementsToCheck.unshift.apply(elementsToCheck, element.children);
|
|
}
|
|
}
|
|
}
|
|
return candidates;
|
|
};
|
|
|
|
/**
|
|
* @private
|
|
* Determines if the node has an explicitly specified `tabindex` attribute.
|
|
* @param {HTMLElement} node
|
|
* @returns {boolean} True if so; false if not.
|
|
*/
|
|
var hasTabIndex = function hasTabIndex(node) {
|
|
return !isNaN(parseInt(node.getAttribute("tabindex"), 10));
|
|
};
|
|
|
|
/**
|
|
* Determine the tab index of a given node.
|
|
* @param {HTMLElement} node
|
|
* @returns {number} Tab order (negative, 0, or positive number).
|
|
* @throws {Error} If `node` is falsy.
|
|
*/
|
|
var getTabIndex = function getTabIndex(node) {
|
|
if (!node) {
|
|
throw new Error("No node provided");
|
|
}
|
|
if (node.tabIndex < 0) {
|
|
// in Chrome, <details/>, <audio controls/> and <video controls/> elements get a default
|
|
// `tabIndex` of -1 when the 'tabindex' attribute isn't specified in the DOM,
|
|
// yet they are still part of the regular tab order; in FF, they get a default
|
|
// `tabIndex` of 0; since Chrome still puts those elements in the regular tab
|
|
// order, consider their tab index to be 0.
|
|
// Also browsers do not return `tabIndex` correctly for contentEditable nodes;
|
|
// so if they don't have a tabindex attribute specifically set, assume it's 0.
|
|
if ((/^(AUDIO|VIDEO|DETAILS)$/.test(node.tagName) || isContentEditable(node)) && !hasTabIndex(node)) {
|
|
return 0;
|
|
}
|
|
}
|
|
return node.tabIndex;
|
|
};
|
|
|
|
/**
|
|
* Determine the tab index of a given node __for sort order purposes__.
|
|
* @param {HTMLElement} node
|
|
* @param {boolean} [isScope] True for a custom element with shadow root or slot that, by default,
|
|
* has tabIndex -1, but needs to be sorted by document order in order for its content to be
|
|
* inserted into the correct sort position.
|
|
* @returns {number} Tab order (negative, 0, or positive number).
|
|
*/
|
|
var getSortOrderTabIndex = function getSortOrderTabIndex(node, isScope) {
|
|
var tabIndex = getTabIndex(node);
|
|
if (tabIndex < 0 && isScope && !hasTabIndex(node)) {
|
|
return 0;
|
|
}
|
|
return tabIndex;
|
|
};
|
|
var sortOrderedTabbables = function sortOrderedTabbables(a, b) {
|
|
return a.tabIndex === b.tabIndex ? a.documentOrder - b.documentOrder : a.tabIndex - b.tabIndex;
|
|
};
|
|
var isInput = function isInput(node) {
|
|
return node.tagName === "INPUT";
|
|
};
|
|
var isHiddenInput = function isHiddenInput(node) {
|
|
return isInput(node) && node.type === "hidden";
|
|
};
|
|
var isDetailsWithSummary = function isDetailsWithSummary(node) {
|
|
var r =
|
|
node.tagName === "DETAILS" &&
|
|
Array.prototype.slice.apply(node.children).some(function (child) {
|
|
return child.tagName === "SUMMARY";
|
|
});
|
|
return r;
|
|
};
|
|
var getCheckedRadio = function getCheckedRadio(nodes, form) {
|
|
for (var i = 0; i < nodes.length; i++) {
|
|
if (nodes[i].checked && nodes[i].form === form) {
|
|
return nodes[i];
|
|
}
|
|
}
|
|
};
|
|
var isTabbableRadio = function isTabbableRadio(node) {
|
|
if (!node.name) {
|
|
return true;
|
|
}
|
|
var radioScope = node.form || getRootNode(node);
|
|
var queryRadios = function queryRadios(name) {
|
|
return radioScope.querySelectorAll('input[type="radio"][name="' + name + '"]');
|
|
};
|
|
var radioSet;
|
|
if (typeof window !== "undefined" && typeof window.CSS !== "undefined" && typeof window.CSS.escape === "function") {
|
|
radioSet = queryRadios(window.CSS.escape(node.name));
|
|
} else {
|
|
try {
|
|
radioSet = queryRadios(node.name);
|
|
} catch (err) {
|
|
// eslint-disable-next-line no-console
|
|
console.error("Looks like you have a radio button with a name attribute containing invalid CSS selector characters and need the CSS.escape polyfill: %s", err.message);
|
|
return false;
|
|
}
|
|
}
|
|
var checked = getCheckedRadio(radioSet, node.form);
|
|
return !checked || checked === node;
|
|
};
|
|
var isRadio = function isRadio(node) {
|
|
return isInput(node) && node.type === "radio";
|
|
};
|
|
var isNonTabbableRadio = function isNonTabbableRadio(node) {
|
|
return isRadio(node) && !isTabbableRadio(node);
|
|
};
|
|
|
|
// determines if a node is ultimately attached to the window's document
|
|
var isNodeAttached = function isNodeAttached(node) {
|
|
var _nodeRoot;
|
|
// The root node is the shadow root if the node is in a shadow DOM; some document otherwise
|
|
// (but NOT _the_ document; see second 'If' comment below for more).
|
|
// If rootNode is shadow root, it'll have a host, which is the element to which the shadow
|
|
// is attached, and the one we need to check if it's in the document or not (because the
|
|
// shadow, and all nodes it contains, is never considered in the document since shadows
|
|
// behave like self-contained DOMs; but if the shadow's HOST, which is part of the document,
|
|
// is hidden, or is not in the document itself but is detached, it will affect the shadow's
|
|
// visibility, including all the nodes it contains). The host could be any normal node,
|
|
// or a custom element (i.e. web component). Either way, that's the one that is considered
|
|
// part of the document, not the shadow root, nor any of its children (i.e. the node being
|
|
// tested).
|
|
// To further complicate things, we have to look all the way up until we find a shadow HOST
|
|
// that is attached (or find none) because the node might be in nested shadows...
|
|
// If rootNode is not a shadow root, it won't have a host, and so rootNode should be the
|
|
// document (per the docs) and while it's a Document-type object, that document does not
|
|
// appear to be the same as the node's `ownerDocument` for some reason, so it's safer
|
|
// to ignore the rootNode at this point, and use `node.ownerDocument`. Otherwise,
|
|
// using `rootNode.contains(node)` will _always_ be true we'll get false-positives when
|
|
// node is actually detached.
|
|
// NOTE: If `nodeRootHost` or `node` happens to be the `document` itself (which is possible
|
|
// if a tabbable/focusable node was quickly added to the DOM, focused, and then removed
|
|
// from the DOM as in https://github.com/focus-trap/focus-trap-react/issues/905), then
|
|
// `ownerDocument` will be `null`, hence the optional chaining on it.
|
|
var nodeRoot = node && getRootNode(node);
|
|
var nodeRootHost = (_nodeRoot = nodeRoot) === null || _nodeRoot === void 0 ? void 0 : _nodeRoot.host;
|
|
|
|
// in some cases, a detached node will return itself as the root instead of a document or
|
|
// shadow root object, in which case, we shouldn't try to look further up the host chain
|
|
var attached = false;
|
|
if (nodeRoot && nodeRoot !== node) {
|
|
var _nodeRootHost, _nodeRootHost$ownerDo, _node$ownerDocument;
|
|
attached = !!(
|
|
((_nodeRootHost = nodeRootHost) !== null &&
|
|
_nodeRootHost !== void 0 &&
|
|
(_nodeRootHost$ownerDo = _nodeRootHost.ownerDocument) !== null &&
|
|
_nodeRootHost$ownerDo !== void 0 &&
|
|
_nodeRootHost$ownerDo.contains(nodeRootHost)) ||
|
|
(node !== null && node !== void 0 && (_node$ownerDocument = node.ownerDocument) !== null && _node$ownerDocument !== void 0 && _node$ownerDocument.contains(node))
|
|
);
|
|
while (!attached && nodeRootHost) {
|
|
var _nodeRoot2, _nodeRootHost2, _nodeRootHost2$ownerD;
|
|
// since it's not attached and we have a root host, the node MUST be in a nested shadow DOM,
|
|
// which means we need to get the host's host and check if that parent host is contained
|
|
// in (i.e. attached to) the document
|
|
nodeRoot = getRootNode(nodeRootHost);
|
|
nodeRootHost = (_nodeRoot2 = nodeRoot) === null || _nodeRoot2 === void 0 ? void 0 : _nodeRoot2.host;
|
|
attached = !!(
|
|
(_nodeRootHost2 = nodeRootHost) !== null &&
|
|
_nodeRootHost2 !== void 0 &&
|
|
(_nodeRootHost2$ownerD = _nodeRootHost2.ownerDocument) !== null &&
|
|
_nodeRootHost2$ownerD !== void 0 &&
|
|
_nodeRootHost2$ownerD.contains(nodeRootHost)
|
|
);
|
|
}
|
|
}
|
|
return attached;
|
|
};
|
|
var isZeroArea = function isZeroArea(node) {
|
|
var _node$getBoundingClie = node.getBoundingClientRect(),
|
|
width = _node$getBoundingClie.width,
|
|
height = _node$getBoundingClie.height;
|
|
return width === 0 && height === 0;
|
|
};
|
|
var isHidden = function isHidden(node, _ref) {
|
|
var displayCheck = _ref.displayCheck,
|
|
getShadowRoot = _ref.getShadowRoot;
|
|
if (displayCheck === "full-native") {
|
|
if ("checkVisibility" in node) {
|
|
// Chrome >= 105, Edge >= 105, Firefox >= 106, Safari >= 17.4
|
|
// @see https://developer.mozilla.org/en-US/docs/Web/API/Element/checkVisibility#browser_compatibility
|
|
var visible = node.checkVisibility({
|
|
// Checking opacity might be desirable for some use cases, but natively,
|
|
// opacity zero elements _are_ focusable and tabbable.
|
|
checkOpacity: false,
|
|
opacityProperty: false,
|
|
contentVisibilityAuto: true,
|
|
visibilityProperty: true,
|
|
// This is an alias for `visibilityProperty`. Contemporary browsers
|
|
// support both. However, this alias has wider browser support (Chrome
|
|
// >= 105 and Firefox >= 106, vs. Chrome >= 121 and Firefox >= 122), so
|
|
// we include it anyway.
|
|
checkVisibilityCSS: true,
|
|
});
|
|
return !visible;
|
|
}
|
|
// Fall through to manual visibility checks
|
|
}
|
|
|
|
// NOTE: visibility will be `undefined` if node is detached from the document
|
|
// (see notes about this further down), which means we will consider it visible
|
|
// (this is legacy behavior from a very long way back)
|
|
// NOTE: we check this regardless of `displayCheck="none"` because this is a
|
|
// _visibility_ check, not a _display_ check
|
|
var _getComputedStyle = getComputedStyle(node),
|
|
visibility = _getComputedStyle.visibility;
|
|
if (visibility === "hidden" || visibility === "collapse") {
|
|
return true;
|
|
}
|
|
var isDirectSummary = matches.call(node, "details>summary:first-of-type");
|
|
var nodeUnderDetails = isDirectSummary ? node.parentElement : node;
|
|
if (matches.call(nodeUnderDetails, "details:not([open]) *")) {
|
|
return true;
|
|
}
|
|
if (
|
|
!displayCheck ||
|
|
displayCheck === "full" ||
|
|
// full-native can run this branch when it falls through in case
|
|
// Element#checkVisibility is unsupported
|
|
displayCheck === "full-native" ||
|
|
displayCheck === "legacy-full"
|
|
) {
|
|
if (typeof getShadowRoot === "function") {
|
|
// figure out if we should consider the node to be in an undisclosed shadow and use the
|
|
// 'non-zero-area' fallback
|
|
var originalNode = node;
|
|
while (node) {
|
|
var parentElement = node.parentElement;
|
|
var rootNode = getRootNode(node);
|
|
if (
|
|
parentElement &&
|
|
!parentElement.shadowRoot &&
|
|
getShadowRoot(parentElement) === true // check if there's an undisclosed shadow
|
|
) {
|
|
// node has an undisclosed shadow which means we can only treat it as a black box, so we
|
|
// fall back to a non-zero-area test
|
|
return isZeroArea(node);
|
|
} else if (node.assignedSlot) {
|
|
// iterate up slot
|
|
node = node.assignedSlot;
|
|
} else if (!parentElement && rootNode !== node.ownerDocument) {
|
|
// cross shadow boundary
|
|
node = rootNode.host;
|
|
} else {
|
|
// iterate up normal dom
|
|
node = parentElement;
|
|
}
|
|
}
|
|
node = originalNode;
|
|
}
|
|
// else, `getShadowRoot` might be true, but all that does is enable shadow DOM support
|
|
// (i.e. it does not also presume that all nodes might have undisclosed shadows); or
|
|
// it might be a falsy value, which means shadow DOM support is disabled
|
|
|
|
// Since we didn't find it sitting in an undisclosed shadow (or shadows are disabled)
|
|
// now we can just test to see if it would normally be visible or not, provided it's
|
|
// attached to the main document.
|
|
// NOTE: We must consider case where node is inside a shadow DOM and given directly to
|
|
// `isTabbable()` or `isFocusable()` -- regardless of `getShadowRoot` option setting.
|
|
|
|
if (isNodeAttached(node)) {
|
|
// this works wherever the node is: if there's at least one client rect, it's
|
|
// somehow displayed; it also covers the CSS 'display: contents' case where the
|
|
// node itself is hidden in place of its contents; and there's no need to search
|
|
// up the hierarchy either
|
|
return !node.getClientRects().length;
|
|
}
|
|
|
|
// Else, the node isn't attached to the document, which means the `getClientRects()`
|
|
// API will __always__ return zero rects (this can happen, for example, if React
|
|
// is used to render nodes onto a detached tree, as confirmed in this thread:
|
|
// https://github.com/facebook/react/issues/9117#issuecomment-284228870)
|
|
//
|
|
// It also means that even window.getComputedStyle(node).display will return `undefined`
|
|
// because styles are only computed for nodes that are in the document.
|
|
//
|
|
// NOTE: THIS HAS BEEN THE CASE FOR YEARS. It is not new, nor is it caused by tabbable
|
|
// somehow. Though it was never stated officially, anyone who has ever used tabbable
|
|
// APIs on nodes in detached containers has actually implicitly used tabbable in what
|
|
// was later (as of v5.2.0 on Apr 9, 2021) called `displayCheck="none"` mode -- essentially
|
|
// considering __everything__ to be visible because of the innability to determine styles.
|
|
//
|
|
// v6.0.0: As of this major release, the default 'full' option __no longer treats detached
|
|
// nodes as visible with the 'none' fallback.__
|
|
if (displayCheck !== "legacy-full") {
|
|
return true; // hidden
|
|
}
|
|
// else, fallback to 'none' mode and consider the node visible
|
|
} else if (displayCheck === "non-zero-area") {
|
|
// NOTE: Even though this tests that the node's client rect is non-zero to determine
|
|
// whether it's displayed, and that a detached node will __always__ have a zero-area
|
|
// client rect, we don't special-case for whether the node is attached or not. In
|
|
// this mode, we do want to consider nodes that have a zero area to be hidden at all
|
|
// times, and that includes attached or not.
|
|
return isZeroArea(node);
|
|
}
|
|
|
|
// visible, as far as we can tell, or per current `displayCheck=none` mode, we assume
|
|
// it's visible
|
|
return false;
|
|
};
|
|
|
|
// form fields (nested) inside a disabled fieldset are not focusable/tabbable
|
|
// unless they are in the _first_ <legend> element of the top-most disabled
|
|
// fieldset
|
|
var isDisabledFromFieldset = function isDisabledFromFieldset(node) {
|
|
if (/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(node.tagName)) {
|
|
var parentNode = node.parentElement;
|
|
// check if `node` is contained in a disabled <fieldset>
|
|
while (parentNode) {
|
|
if (parentNode.tagName === "FIELDSET" && parentNode.disabled) {
|
|
// look for the first <legend> among the children of the disabled <fieldset>
|
|
for (var i = 0; i < parentNode.children.length; i++) {
|
|
var child = parentNode.children.item(i);
|
|
// when the first <legend> (in document order) is found
|
|
if (child.tagName === "LEGEND") {
|
|
// if its parent <fieldset> is not nested in another disabled <fieldset>,
|
|
// return whether `node` is a descendant of its first <legend>
|
|
return matches.call(parentNode, "fieldset[disabled] *") ? true : !child.contains(node);
|
|
}
|
|
}
|
|
// the disabled <fieldset> containing `node` has no <legend>
|
|
return true;
|
|
}
|
|
parentNode = parentNode.parentElement;
|
|
}
|
|
}
|
|
|
|
// else, node's tabbable/focusable state should not be affected by a fieldset's
|
|
// enabled/disabled state
|
|
return false;
|
|
};
|
|
var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable(options, node) {
|
|
if (
|
|
node.disabled ||
|
|
isHiddenInput(node) ||
|
|
isHidden(node, options) ||
|
|
// For a details element with a summary, the summary element gets the focus
|
|
isDetailsWithSummary(node) ||
|
|
isDisabledFromFieldset(node)
|
|
) {
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
var isNodeMatchingSelectorTabbable = function isNodeMatchingSelectorTabbable(options, node) {
|
|
if (isNonTabbableRadio(node) || getTabIndex(node) < 0 || !isNodeMatchingSelectorFocusable(options, node)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
var isShadowRootTabbable = function isShadowRootTabbable(shadowHostNode) {
|
|
var tabIndex = parseInt(shadowHostNode.getAttribute("tabindex"), 10);
|
|
if (isNaN(tabIndex) || tabIndex >= 0) {
|
|
return true;
|
|
}
|
|
// If a custom element has an explicit negative tabindex,
|
|
// browsers will not allow tab targeting said element's children.
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* @param {Array.<Element|CandidateScope>} candidates
|
|
* @returns Element[]
|
|
*/
|
|
var _sortByOrder = function sortByOrder(candidates) {
|
|
var regularTabbables = [];
|
|
var orderedTabbables = [];
|
|
candidates.forEach(function (item, i) {
|
|
var isScope = !!item.scopeParent;
|
|
var element = isScope ? item.scopeParent : item;
|
|
var candidateTabindex = getSortOrderTabIndex(element, isScope);
|
|
var elements = isScope ? _sortByOrder(item.candidates) : element;
|
|
if (candidateTabindex === 0) {
|
|
isScope ? regularTabbables.push.apply(regularTabbables, elements) : regularTabbables.push(element);
|
|
} else {
|
|
orderedTabbables.push({
|
|
documentOrder: i,
|
|
tabIndex: candidateTabindex,
|
|
item: item,
|
|
isScope: isScope,
|
|
content: elements,
|
|
});
|
|
}
|
|
});
|
|
return orderedTabbables
|
|
.sort(sortOrderedTabbables)
|
|
.reduce(function (acc, sortable) {
|
|
sortable.isScope ? acc.push.apply(acc, sortable.content) : acc.push(sortable.content);
|
|
return acc;
|
|
}, [])
|
|
.concat(regularTabbables);
|
|
};
|
|
var tabbable = function tabbable(container, options) {
|
|
options = options || {};
|
|
var candidates;
|
|
if (options.getShadowRoot) {
|
|
candidates = _getCandidatesIteratively([container], options.includeContainer, {
|
|
filter: isNodeMatchingSelectorTabbable.bind(null, options),
|
|
flatten: false,
|
|
getShadowRoot: options.getShadowRoot,
|
|
shadowRootFilter: isShadowRootTabbable,
|
|
});
|
|
} else {
|
|
candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorTabbable.bind(null, options));
|
|
}
|
|
return _sortByOrder(candidates);
|
|
};
|
|
var focusable = function focusable(container, options) {
|
|
options = options || {};
|
|
var candidates;
|
|
if (options.getShadowRoot) {
|
|
candidates = _getCandidatesIteratively([container], options.includeContainer, {
|
|
filter: isNodeMatchingSelectorFocusable.bind(null, options),
|
|
flatten: true,
|
|
getShadowRoot: options.getShadowRoot,
|
|
});
|
|
} else {
|
|
candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorFocusable.bind(null, options));
|
|
}
|
|
return candidates;
|
|
};
|
|
var isTabbable = function isTabbable(node, options) {
|
|
options = options || {};
|
|
if (!node) {
|
|
throw new Error("No node provided");
|
|
}
|
|
if (matches.call(node, candidateSelector) === false) {
|
|
return false;
|
|
}
|
|
return isNodeMatchingSelectorTabbable(options, node);
|
|
};
|
|
|
|
const React$8 = await importShared("react");
|
|
|
|
const { useLayoutEffect } = await importShared("react");
|
|
function getPlatform() {
|
|
const uaData = navigator.userAgentData;
|
|
if (uaData != null && uaData.platform) {
|
|
return uaData.platform;
|
|
}
|
|
return navigator.platform;
|
|
}
|
|
function getUserAgent() {
|
|
const uaData = navigator.userAgentData;
|
|
if (uaData && Array.isArray(uaData.brands)) {
|
|
return uaData.brands
|
|
.map((_ref) => {
|
|
let { brand, version } = _ref;
|
|
return brand + "/" + version;
|
|
})
|
|
.join(" ");
|
|
}
|
|
return navigator.userAgent;
|
|
}
|
|
function isSafari() {
|
|
return /apple/i.test(navigator.vendor);
|
|
}
|
|
function isAndroid() {
|
|
const re = /android/i;
|
|
return re.test(getPlatform()) || re.test(getUserAgent());
|
|
}
|
|
function isJSDOM() {
|
|
return getUserAgent().includes("jsdom/");
|
|
}
|
|
const FOCUSABLE_ATTRIBUTE$1 = "data-floating-ui-focusable";
|
|
const TYPEABLE_SELECTOR = "input:not([type='hidden']):not([disabled]),[contenteditable]:not([contenteditable='false']),textarea:not([disabled])";
|
|
function activeElement(doc) {
|
|
let activeElement2 = doc.activeElement;
|
|
while (((_activeElement = activeElement2) == null || (_activeElement = _activeElement.shadowRoot) == null ? void 0 : _activeElement.activeElement) != null) {
|
|
var _activeElement;
|
|
activeElement2 = activeElement2.shadowRoot.activeElement;
|
|
}
|
|
return activeElement2;
|
|
}
|
|
function contains$1(parent, child) {
|
|
if (!parent || !child) {
|
|
return false;
|
|
}
|
|
const rootNode = child.getRootNode == null ? void 0 : child.getRootNode();
|
|
if (parent.contains(child)) {
|
|
return true;
|
|
}
|
|
if (rootNode && isShadowRoot(rootNode)) {
|
|
let next = child;
|
|
while (next) {
|
|
if (parent === next) {
|
|
return true;
|
|
}
|
|
next = next.parentNode || next.host;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
function getTarget$1(event) {
|
|
if ("composedPath" in event) {
|
|
return event.composedPath()[0];
|
|
}
|
|
return event.target;
|
|
}
|
|
function isEventTargetWithin(event, node) {
|
|
if (node == null) {
|
|
return false;
|
|
}
|
|
if ("composedPath" in event) {
|
|
return event.composedPath().includes(node);
|
|
}
|
|
const e = event;
|
|
return e.target != null && node.contains(e.target);
|
|
}
|
|
function isRootElement(element) {
|
|
return element.matches("html,body");
|
|
}
|
|
function getDocument$1(node) {
|
|
return (node == null ? void 0 : node.ownerDocument) || document;
|
|
}
|
|
function isTypeableElement(element) {
|
|
return isHTMLElement$1(element) && element.matches(TYPEABLE_SELECTOR);
|
|
}
|
|
function isTypeableCombobox(element) {
|
|
if (!element) return false;
|
|
return element.getAttribute("role") === "combobox" && isTypeableElement(element);
|
|
}
|
|
function getFloatingFocusElement(floatingElement) {
|
|
if (!floatingElement) {
|
|
return null;
|
|
}
|
|
return floatingElement.hasAttribute(FOCUSABLE_ATTRIBUTE$1) ? floatingElement : floatingElement.querySelector("[" + FOCUSABLE_ATTRIBUTE$1 + "]") || floatingElement;
|
|
}
|
|
function getNodeChildren$1(nodes, id, onlyOpenChildren) {
|
|
if (onlyOpenChildren === void 0) {
|
|
onlyOpenChildren = true;
|
|
}
|
|
const directChildren = nodes.filter((node) => {
|
|
var _node$context;
|
|
return node.parentId === id && (!onlyOpenChildren || ((_node$context = node.context) == null ? void 0 : _node$context.open));
|
|
});
|
|
return directChildren.flatMap((child) => [child, ...getNodeChildren$1(nodes, child.id, onlyOpenChildren)]);
|
|
}
|
|
function getNodeAncestors(nodes, id) {
|
|
var _nodes$find;
|
|
let allAncestors = [];
|
|
let currentParentId = (_nodes$find = nodes.find((node) => node.id === id)) == null ? void 0 : _nodes$find.parentId;
|
|
while (currentParentId) {
|
|
const currentNode = nodes.find((node) => node.id === currentParentId);
|
|
currentParentId = currentNode == null ? void 0 : currentNode.parentId;
|
|
if (currentNode) {
|
|
allAncestors = allAncestors.concat(currentNode);
|
|
}
|
|
}
|
|
return allAncestors;
|
|
}
|
|
function stopEvent(event) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
}
|
|
function isReactEvent(event) {
|
|
return "nativeEvent" in event;
|
|
}
|
|
function isVirtualClick(event) {
|
|
if (event.mozInputSource === 0 && event.isTrusted) {
|
|
return true;
|
|
}
|
|
if (isAndroid() && event.pointerType) {
|
|
return event.type === "click" && event.buttons === 1;
|
|
}
|
|
return event.detail === 0 && !event.pointerType;
|
|
}
|
|
function isVirtualPointerEvent(event) {
|
|
if (isJSDOM()) return false;
|
|
return (
|
|
(!isAndroid() && event.width === 0 && event.height === 0) ||
|
|
(isAndroid() && event.width === 1 && event.height === 1 && event.pressure === 0 && event.detail === 0 && event.pointerType === "mouse") || // iOS VoiceOver returns 0.333• for width/height.
|
|
(event.width < 1 && event.height < 1 && event.pressure === 0 && event.detail === 0 && event.pointerType === "touch")
|
|
);
|
|
}
|
|
function isMouseLikePointerType(pointerType, strict) {
|
|
const values = ["mouse", "pen"];
|
|
{
|
|
values.push("", void 0);
|
|
}
|
|
return values.includes(pointerType);
|
|
}
|
|
var isClient = typeof document !== "undefined";
|
|
var noop = function noop2() {};
|
|
var index = isClient ? useLayoutEffect : noop;
|
|
const SafeReact$1 = {
|
|
...React$8,
|
|
};
|
|
function useLatestRef(value) {
|
|
const ref = React$8.useRef(value);
|
|
index(() => {
|
|
ref.current = value;
|
|
});
|
|
return ref;
|
|
}
|
|
const useInsertionEffect = SafeReact$1.useInsertionEffect;
|
|
const useSafeInsertionEffect = useInsertionEffect || ((fn) => fn());
|
|
function useEffectEvent(callback) {
|
|
const ref = React$8.useRef(() => {});
|
|
useSafeInsertionEffect(() => {
|
|
ref.current = callback;
|
|
});
|
|
return React$8.useCallback(function () {
|
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
args[_key] = arguments[_key];
|
|
}
|
|
return ref.current == null ? void 0 : ref.current(...args);
|
|
}, []);
|
|
}
|
|
const getTabbableOptions = () => ({
|
|
getShadowRoot: true,
|
|
displayCheck:
|
|
// JSDOM does not support the `tabbable` library. To solve this we can
|
|
// check if `ResizeObserver` is a real function (not polyfilled), which
|
|
// determines if the current environment is JSDOM-like.
|
|
typeof ResizeObserver === "function" && ResizeObserver.toString().includes("[native code]") ? "full" : "none",
|
|
});
|
|
function getTabbableIn(container, dir) {
|
|
const list = tabbable(container, getTabbableOptions());
|
|
const len = list.length;
|
|
if (len === 0) return;
|
|
const active = activeElement(getDocument$1(container));
|
|
const index2 = list.indexOf(active);
|
|
const nextIndex =
|
|
index2 === -1 ?
|
|
dir === 1 ?
|
|
0
|
|
: len - 1
|
|
: index2 + dir;
|
|
return list[nextIndex];
|
|
}
|
|
function getNextTabbable(referenceElement) {
|
|
return getTabbableIn(getDocument$1(referenceElement).body, 1) || referenceElement;
|
|
}
|
|
function getPreviousTabbable(referenceElement) {
|
|
return getTabbableIn(getDocument$1(referenceElement).body, -1) || referenceElement;
|
|
}
|
|
function isOutsideEvent(event, container) {
|
|
const containerElement = container || event.currentTarget;
|
|
const relatedTarget = event.relatedTarget;
|
|
return !relatedTarget || !contains$1(containerElement, relatedTarget);
|
|
}
|
|
|
|
const React$7 = await importShared("react");
|
|
const ReactDOM = await importShared("react-dom");
|
|
function useMergeRefs(refs) {
|
|
const cleanupRef = React$7.useRef(void 0);
|
|
const refEffect = React$7.useCallback((instance) => {
|
|
const cleanups = refs.map((ref) => {
|
|
if (ref == null) {
|
|
return;
|
|
}
|
|
if (typeof ref === "function") {
|
|
const refCallback = ref;
|
|
const refCleanup = refCallback(instance);
|
|
return typeof refCleanup === "function" ? refCleanup : (
|
|
() => {
|
|
refCallback(null);
|
|
}
|
|
);
|
|
}
|
|
ref.current = instance;
|
|
return () => {
|
|
ref.current = null;
|
|
};
|
|
});
|
|
return () => {
|
|
cleanups.forEach((refCleanup) => (refCleanup == null ? void 0 : refCleanup()));
|
|
};
|
|
}, refs);
|
|
return React$7.useMemo(() => {
|
|
if (refs.every((ref) => ref == null)) {
|
|
return null;
|
|
}
|
|
return (value) => {
|
|
if (cleanupRef.current) {
|
|
cleanupRef.current();
|
|
cleanupRef.current = void 0;
|
|
}
|
|
if (value != null) {
|
|
cleanupRef.current = refEffect(value);
|
|
}
|
|
};
|
|
}, refs);
|
|
}
|
|
const FOCUSABLE_ATTRIBUTE = "data-floating-ui-focusable";
|
|
const ACTIVE_KEY = "active";
|
|
const SELECTED_KEY = "selected";
|
|
const SafeReact = {
|
|
...React$7,
|
|
};
|
|
let serverHandoffComplete = false;
|
|
let count = 0;
|
|
const genId = () =>
|
|
// Ensure the id is unique with multiple independent versions of Floating UI
|
|
// on <React 18
|
|
"floating-ui-" + Math.random().toString(36).slice(2, 6) + count++;
|
|
function useFloatingId() {
|
|
const [id, setId] = React$7.useState(() => (serverHandoffComplete ? genId() : void 0));
|
|
index(() => {
|
|
if (id == null) {
|
|
setId(genId());
|
|
}
|
|
}, []);
|
|
React$7.useEffect(() => {
|
|
serverHandoffComplete = true;
|
|
}, []);
|
|
return id;
|
|
}
|
|
const useReactId = SafeReact.useId;
|
|
const useId = useReactId || useFloatingId;
|
|
function createEventEmitter() {
|
|
const map = /* @__PURE__ */ new Map();
|
|
return {
|
|
emit(event, data) {
|
|
var _map$get;
|
|
(_map$get = map.get(event)) == null || _map$get.forEach((listener) => listener(data));
|
|
},
|
|
on(event, listener) {
|
|
if (!map.has(event)) {
|
|
map.set(event, /* @__PURE__ */ new Set());
|
|
}
|
|
map.get(event).add(listener);
|
|
},
|
|
off(event, listener) {
|
|
var _map$get2;
|
|
(_map$get2 = map.get(event)) == null || _map$get2.delete(listener);
|
|
},
|
|
};
|
|
}
|
|
const FloatingNodeContext = /* @__PURE__ */ React$7.createContext(null);
|
|
const FloatingTreeContext = /* @__PURE__ */ React$7.createContext(null);
|
|
const useFloatingParentNodeId = () => {
|
|
var _React$useContext;
|
|
return ((_React$useContext = React$7.useContext(FloatingNodeContext)) == null ? void 0 : _React$useContext.id) || null;
|
|
};
|
|
const useFloatingTree = () => React$7.useContext(FloatingTreeContext);
|
|
function createAttribute(name) {
|
|
return "data-floating-ui-" + name;
|
|
}
|
|
function clearTimeoutIfSet(timeoutRef) {
|
|
if (timeoutRef.current !== -1) {
|
|
clearTimeout(timeoutRef.current);
|
|
timeoutRef.current = -1;
|
|
}
|
|
}
|
|
const safePolygonIdentifier = /* @__PURE__ */ createAttribute("safe-polygon");
|
|
function getDelay(value, prop, pointerType) {
|
|
if (pointerType && !isMouseLikePointerType(pointerType)) {
|
|
return 0;
|
|
}
|
|
if (typeof value === "number") {
|
|
return value;
|
|
}
|
|
if (typeof value === "function") {
|
|
const result = value();
|
|
if (typeof result === "number") {
|
|
return result;
|
|
}
|
|
return result == null ? void 0 : result[prop];
|
|
}
|
|
return value == null ? void 0 : value[prop];
|
|
}
|
|
function getRestMs(value) {
|
|
if (typeof value === "function") {
|
|
return value();
|
|
}
|
|
return value;
|
|
}
|
|
function useHover(context, props) {
|
|
if (props === void 0) {
|
|
props = {};
|
|
}
|
|
const { open, onOpenChange, dataRef, events, elements } = context;
|
|
const { enabled = true, delay = 0, handleClose = null, mouseOnly = false, restMs = 0, move = true } = props;
|
|
const tree = useFloatingTree();
|
|
const parentId = useFloatingParentNodeId();
|
|
const handleCloseRef = useLatestRef(handleClose);
|
|
const delayRef = useLatestRef(delay);
|
|
const openRef = useLatestRef(open);
|
|
const restMsRef = useLatestRef(restMs);
|
|
const pointerTypeRef = React$7.useRef();
|
|
const timeoutRef = React$7.useRef(-1);
|
|
const handlerRef = React$7.useRef();
|
|
const restTimeoutRef = React$7.useRef(-1);
|
|
const blockMouseMoveRef = React$7.useRef(true);
|
|
const performedPointerEventsMutationRef = React$7.useRef(false);
|
|
const unbindMouseMoveRef = React$7.useRef(() => {});
|
|
const restTimeoutPendingRef = React$7.useRef(false);
|
|
const isHoverOpen = useEffectEvent(() => {
|
|
var _dataRef$current$open;
|
|
const type = (_dataRef$current$open = dataRef.current.openEvent) == null ? void 0 : _dataRef$current$open.type;
|
|
return (type == null ? void 0 : type.includes("mouse")) && type !== "mousedown";
|
|
});
|
|
React$7.useEffect(() => {
|
|
if (!enabled) return;
|
|
function onOpenChange2(_ref) {
|
|
let { open: open2 } = _ref;
|
|
if (!open2) {
|
|
clearTimeoutIfSet(timeoutRef);
|
|
clearTimeoutIfSet(restTimeoutRef);
|
|
blockMouseMoveRef.current = true;
|
|
restTimeoutPendingRef.current = false;
|
|
}
|
|
}
|
|
events.on("openchange", onOpenChange2);
|
|
return () => {
|
|
events.off("openchange", onOpenChange2);
|
|
};
|
|
}, [enabled, events]);
|
|
React$7.useEffect(() => {
|
|
if (!enabled) return;
|
|
if (!handleCloseRef.current) return;
|
|
if (!open) return;
|
|
function onLeave(event) {
|
|
if (isHoverOpen()) {
|
|
onOpenChange(false, event, "hover");
|
|
}
|
|
}
|
|
const html = getDocument$1(elements.floating).documentElement;
|
|
html.addEventListener("mouseleave", onLeave);
|
|
return () => {
|
|
html.removeEventListener("mouseleave", onLeave);
|
|
};
|
|
}, [elements.floating, open, onOpenChange, enabled, handleCloseRef, isHoverOpen]);
|
|
const closeWithDelay = React$7.useCallback(
|
|
function (event, runElseBranch, reason) {
|
|
if (runElseBranch === void 0) {
|
|
runElseBranch = true;
|
|
}
|
|
if (reason === void 0) {
|
|
reason = "hover";
|
|
}
|
|
const closeDelay = getDelay(delayRef.current, "close", pointerTypeRef.current);
|
|
if (closeDelay && !handlerRef.current) {
|
|
clearTimeoutIfSet(timeoutRef);
|
|
timeoutRef.current = window.setTimeout(() => onOpenChange(false, event, reason), closeDelay);
|
|
} else if (runElseBranch) {
|
|
clearTimeoutIfSet(timeoutRef);
|
|
onOpenChange(false, event, reason);
|
|
}
|
|
},
|
|
[delayRef, onOpenChange],
|
|
);
|
|
const cleanupMouseMoveHandler = useEffectEvent(() => {
|
|
unbindMouseMoveRef.current();
|
|
handlerRef.current = void 0;
|
|
});
|
|
const clearPointerEvents = useEffectEvent(() => {
|
|
if (performedPointerEventsMutationRef.current) {
|
|
const body = getDocument$1(elements.floating).body;
|
|
body.style.pointerEvents = "";
|
|
body.removeAttribute(safePolygonIdentifier);
|
|
performedPointerEventsMutationRef.current = false;
|
|
}
|
|
});
|
|
const isClickLikeOpenEvent = useEffectEvent(() => {
|
|
return dataRef.current.openEvent ? ["click", "mousedown"].includes(dataRef.current.openEvent.type) : false;
|
|
});
|
|
React$7.useEffect(() => {
|
|
if (!enabled) return;
|
|
function onReferenceMouseEnter(event) {
|
|
clearTimeoutIfSet(timeoutRef);
|
|
blockMouseMoveRef.current = false;
|
|
if ((mouseOnly && !isMouseLikePointerType(pointerTypeRef.current)) || (getRestMs(restMsRef.current) > 0 && !getDelay(delayRef.current, "open"))) {
|
|
return;
|
|
}
|
|
const openDelay = getDelay(delayRef.current, "open", pointerTypeRef.current);
|
|
if (openDelay) {
|
|
timeoutRef.current = window.setTimeout(() => {
|
|
if (!openRef.current) {
|
|
onOpenChange(true, event, "hover");
|
|
}
|
|
}, openDelay);
|
|
} else if (!open) {
|
|
onOpenChange(true, event, "hover");
|
|
}
|
|
}
|
|
function onReferenceMouseLeave(event) {
|
|
if (isClickLikeOpenEvent()) {
|
|
clearPointerEvents();
|
|
return;
|
|
}
|
|
unbindMouseMoveRef.current();
|
|
const doc = getDocument$1(elements.floating);
|
|
clearTimeoutIfSet(restTimeoutRef);
|
|
restTimeoutPendingRef.current = false;
|
|
if (handleCloseRef.current && dataRef.current.floatingContext) {
|
|
if (!open) {
|
|
clearTimeoutIfSet(timeoutRef);
|
|
}
|
|
handlerRef.current = handleCloseRef.current({
|
|
...dataRef.current.floatingContext,
|
|
tree,
|
|
x: event.clientX,
|
|
y: event.clientY,
|
|
onClose() {
|
|
clearPointerEvents();
|
|
cleanupMouseMoveHandler();
|
|
if (!isClickLikeOpenEvent()) {
|
|
closeWithDelay(event, true, "safe-polygon");
|
|
}
|
|
},
|
|
});
|
|
const handler = handlerRef.current;
|
|
doc.addEventListener("mousemove", handler);
|
|
unbindMouseMoveRef.current = () => {
|
|
doc.removeEventListener("mousemove", handler);
|
|
};
|
|
return;
|
|
}
|
|
const shouldClose = pointerTypeRef.current === "touch" ? !contains$1(elements.floating, event.relatedTarget) : true;
|
|
if (shouldClose) {
|
|
closeWithDelay(event);
|
|
}
|
|
}
|
|
function onScrollMouseLeave(event) {
|
|
if (isClickLikeOpenEvent()) return;
|
|
if (!dataRef.current.floatingContext) return;
|
|
handleCloseRef.current == null ||
|
|
handleCloseRef.current({
|
|
...dataRef.current.floatingContext,
|
|
tree,
|
|
x: event.clientX,
|
|
y: event.clientY,
|
|
onClose() {
|
|
clearPointerEvents();
|
|
cleanupMouseMoveHandler();
|
|
if (!isClickLikeOpenEvent()) {
|
|
closeWithDelay(event);
|
|
}
|
|
},
|
|
})(event);
|
|
}
|
|
function onFloatingMouseEnter() {
|
|
clearTimeoutIfSet(timeoutRef);
|
|
}
|
|
function onFloatingMouseLeave(event) {
|
|
if (!isClickLikeOpenEvent()) {
|
|
closeWithDelay(event, false);
|
|
}
|
|
}
|
|
if (isElement(elements.domReference)) {
|
|
const reference2 = elements.domReference;
|
|
const floating = elements.floating;
|
|
if (open) {
|
|
reference2.addEventListener("mouseleave", onScrollMouseLeave);
|
|
}
|
|
if (move) {
|
|
reference2.addEventListener("mousemove", onReferenceMouseEnter, {
|
|
once: true,
|
|
});
|
|
}
|
|
reference2.addEventListener("mouseenter", onReferenceMouseEnter);
|
|
reference2.addEventListener("mouseleave", onReferenceMouseLeave);
|
|
if (floating) {
|
|
floating.addEventListener("mouseleave", onScrollMouseLeave);
|
|
floating.addEventListener("mouseenter", onFloatingMouseEnter);
|
|
floating.addEventListener("mouseleave", onFloatingMouseLeave);
|
|
}
|
|
return () => {
|
|
if (open) {
|
|
reference2.removeEventListener("mouseleave", onScrollMouseLeave);
|
|
}
|
|
if (move) {
|
|
reference2.removeEventListener("mousemove", onReferenceMouseEnter);
|
|
}
|
|
reference2.removeEventListener("mouseenter", onReferenceMouseEnter);
|
|
reference2.removeEventListener("mouseleave", onReferenceMouseLeave);
|
|
if (floating) {
|
|
floating.removeEventListener("mouseleave", onScrollMouseLeave);
|
|
floating.removeEventListener("mouseenter", onFloatingMouseEnter);
|
|
floating.removeEventListener("mouseleave", onFloatingMouseLeave);
|
|
}
|
|
};
|
|
}
|
|
}, [
|
|
elements,
|
|
enabled,
|
|
context,
|
|
mouseOnly,
|
|
move,
|
|
closeWithDelay,
|
|
cleanupMouseMoveHandler,
|
|
clearPointerEvents,
|
|
onOpenChange,
|
|
open,
|
|
openRef,
|
|
tree,
|
|
delayRef,
|
|
handleCloseRef,
|
|
dataRef,
|
|
isClickLikeOpenEvent,
|
|
restMsRef,
|
|
]);
|
|
index(() => {
|
|
var _handleCloseRef$curre;
|
|
if (!enabled) return;
|
|
if (
|
|
open &&
|
|
(_handleCloseRef$curre = handleCloseRef.current) != null &&
|
|
(_handleCloseRef$curre = _handleCloseRef$curre.__options) != null &&
|
|
_handleCloseRef$curre.blockPointerEvents &&
|
|
isHoverOpen()
|
|
) {
|
|
performedPointerEventsMutationRef.current = true;
|
|
const floatingEl = elements.floating;
|
|
if (isElement(elements.domReference) && floatingEl) {
|
|
var _tree$nodesRef$curren;
|
|
const body = getDocument$1(elements.floating).body;
|
|
body.setAttribute(safePolygonIdentifier, "");
|
|
const ref = elements.domReference;
|
|
const parentFloating =
|
|
tree == null || (_tree$nodesRef$curren = tree.nodesRef.current.find((node) => node.id === parentId)) == null || (_tree$nodesRef$curren = _tree$nodesRef$curren.context) == null ?
|
|
void 0
|
|
: _tree$nodesRef$curren.elements.floating;
|
|
if (parentFloating) {
|
|
parentFloating.style.pointerEvents = "";
|
|
}
|
|
body.style.pointerEvents = "none";
|
|
ref.style.pointerEvents = "auto";
|
|
floatingEl.style.pointerEvents = "auto";
|
|
return () => {
|
|
body.style.pointerEvents = "";
|
|
ref.style.pointerEvents = "";
|
|
floatingEl.style.pointerEvents = "";
|
|
};
|
|
}
|
|
}
|
|
}, [enabled, open, parentId, elements, tree, handleCloseRef, isHoverOpen]);
|
|
index(() => {
|
|
if (!open) {
|
|
pointerTypeRef.current = void 0;
|
|
restTimeoutPendingRef.current = false;
|
|
cleanupMouseMoveHandler();
|
|
clearPointerEvents();
|
|
}
|
|
}, [open, cleanupMouseMoveHandler, clearPointerEvents]);
|
|
React$7.useEffect(() => {
|
|
return () => {
|
|
cleanupMouseMoveHandler();
|
|
clearTimeoutIfSet(timeoutRef);
|
|
clearTimeoutIfSet(restTimeoutRef);
|
|
clearPointerEvents();
|
|
};
|
|
}, [enabled, elements.domReference, cleanupMouseMoveHandler, clearPointerEvents]);
|
|
const reference = React$7.useMemo(() => {
|
|
function setPointerRef(event) {
|
|
pointerTypeRef.current = event.pointerType;
|
|
}
|
|
return {
|
|
onPointerDown: setPointerRef,
|
|
onPointerEnter: setPointerRef,
|
|
onMouseMove(event) {
|
|
const { nativeEvent } = event;
|
|
function handleMouseMove() {
|
|
if (!blockMouseMoveRef.current && !openRef.current) {
|
|
onOpenChange(true, nativeEvent, "hover");
|
|
}
|
|
}
|
|
if (mouseOnly && !isMouseLikePointerType(pointerTypeRef.current)) {
|
|
return;
|
|
}
|
|
if (open || getRestMs(restMsRef.current) === 0) {
|
|
return;
|
|
}
|
|
if (restTimeoutPendingRef.current && event.movementX ** 2 + event.movementY ** 2 < 2) {
|
|
return;
|
|
}
|
|
clearTimeoutIfSet(restTimeoutRef);
|
|
if (pointerTypeRef.current === "touch") {
|
|
handleMouseMove();
|
|
} else {
|
|
restTimeoutPendingRef.current = true;
|
|
restTimeoutRef.current = window.setTimeout(handleMouseMove, getRestMs(restMsRef.current));
|
|
}
|
|
},
|
|
};
|
|
}, [mouseOnly, onOpenChange, open, openRef, restMsRef]);
|
|
return React$7.useMemo(
|
|
() =>
|
|
enabled ?
|
|
{
|
|
reference,
|
|
}
|
|
: {},
|
|
[enabled, reference],
|
|
);
|
|
}
|
|
let rafId = 0;
|
|
function enqueueFocus(el, options) {
|
|
if (options === void 0) {
|
|
options = {};
|
|
}
|
|
const { preventScroll = false, cancelPrevious = true, sync = false } = options;
|
|
cancelPrevious && cancelAnimationFrame(rafId);
|
|
const exec = () =>
|
|
el == null ? void 0 : (
|
|
el.focus({
|
|
preventScroll,
|
|
})
|
|
);
|
|
if (sync) {
|
|
exec();
|
|
} else {
|
|
rafId = requestAnimationFrame(exec);
|
|
}
|
|
}
|
|
function contains(parent, child) {
|
|
if (!parent || !child) {
|
|
return false;
|
|
}
|
|
const rootNode = child.getRootNode == null ? void 0 : child.getRootNode();
|
|
if (parent.contains(child)) {
|
|
return true;
|
|
}
|
|
if (rootNode && isShadowRoot(rootNode)) {
|
|
let next = child;
|
|
while (next) {
|
|
if (parent === next) {
|
|
return true;
|
|
}
|
|
next = next.parentNode || next.host;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
function getTarget(event) {
|
|
if ("composedPath" in event) {
|
|
return event.composedPath()[0];
|
|
}
|
|
return event.target;
|
|
}
|
|
function getDocument(node) {
|
|
return (node == null ? void 0 : node.ownerDocument) || document;
|
|
}
|
|
const counters = {
|
|
"inert": /* @__PURE__ */ new WeakMap(),
|
|
"aria-hidden": /* @__PURE__ */ new WeakMap(),
|
|
"none": /* @__PURE__ */ new WeakMap(),
|
|
};
|
|
function getCounterMap(control) {
|
|
if (control === "inert") return counters.inert;
|
|
if (control === "aria-hidden") return counters["aria-hidden"];
|
|
return counters.none;
|
|
}
|
|
let uncontrolledElementsSet = /* @__PURE__ */ new WeakSet();
|
|
let markerMap = {};
|
|
let lockCount$1 = 0;
|
|
const supportsInert = () => typeof HTMLElement !== "undefined" && "inert" in HTMLElement.prototype;
|
|
function unwrapHost(node) {
|
|
if (!node) {
|
|
return null;
|
|
}
|
|
return isShadowRoot(node) ? node.host : unwrapHost(node.parentNode);
|
|
}
|
|
const correctElements = (parent, targets) =>
|
|
targets
|
|
.map((target) => {
|
|
if (parent.contains(target)) {
|
|
return target;
|
|
}
|
|
const correctedTarget = unwrapHost(target);
|
|
if (parent.contains(correctedTarget)) {
|
|
return correctedTarget;
|
|
}
|
|
return null;
|
|
})
|
|
.filter((x) => x != null);
|
|
function applyAttributeToOthers(uncorrectedAvoidElements, body, ariaHidden, inert) {
|
|
const markerName = "data-floating-ui-inert";
|
|
const controlAttribute =
|
|
inert ? "inert"
|
|
: ariaHidden ? "aria-hidden"
|
|
: null;
|
|
const avoidElements = correctElements(body, uncorrectedAvoidElements);
|
|
const elementsToKeep = /* @__PURE__ */ new Set();
|
|
const elementsToStop = new Set(avoidElements);
|
|
const hiddenElements = [];
|
|
if (!markerMap[markerName]) {
|
|
markerMap[markerName] = /* @__PURE__ */ new WeakMap();
|
|
}
|
|
const markerCounter = markerMap[markerName];
|
|
avoidElements.forEach(keep);
|
|
deep(body);
|
|
elementsToKeep.clear();
|
|
function keep(el) {
|
|
if (!el || elementsToKeep.has(el)) {
|
|
return;
|
|
}
|
|
elementsToKeep.add(el);
|
|
el.parentNode && keep(el.parentNode);
|
|
}
|
|
function deep(parent) {
|
|
if (!parent || elementsToStop.has(parent)) {
|
|
return;
|
|
}
|
|
[].forEach.call(parent.children, (node) => {
|
|
if (getNodeName(node) === "script") return;
|
|
if (elementsToKeep.has(node)) {
|
|
deep(node);
|
|
} else {
|
|
const attr2 = controlAttribute ? node.getAttribute(controlAttribute) : null;
|
|
const alreadyHidden = attr2 !== null && attr2 !== "false";
|
|
const counterMap = getCounterMap(controlAttribute);
|
|
const counterValue = (counterMap.get(node) || 0) + 1;
|
|
const markerValue = (markerCounter.get(node) || 0) + 1;
|
|
counterMap.set(node, counterValue);
|
|
markerCounter.set(node, markerValue);
|
|
hiddenElements.push(node);
|
|
if (counterValue === 1 && alreadyHidden) {
|
|
uncontrolledElementsSet.add(node);
|
|
}
|
|
if (markerValue === 1) {
|
|
node.setAttribute(markerName, "");
|
|
}
|
|
if (!alreadyHidden && controlAttribute) {
|
|
node.setAttribute(controlAttribute, controlAttribute === "inert" ? "" : "true");
|
|
}
|
|
}
|
|
});
|
|
}
|
|
lockCount$1++;
|
|
return () => {
|
|
hiddenElements.forEach((element) => {
|
|
const counterMap = getCounterMap(controlAttribute);
|
|
const currentCounterValue = counterMap.get(element) || 0;
|
|
const counterValue = currentCounterValue - 1;
|
|
const markerValue = (markerCounter.get(element) || 0) - 1;
|
|
counterMap.set(element, counterValue);
|
|
markerCounter.set(element, markerValue);
|
|
if (!counterValue) {
|
|
if (!uncontrolledElementsSet.has(element) && controlAttribute) {
|
|
element.removeAttribute(controlAttribute);
|
|
}
|
|
uncontrolledElementsSet.delete(element);
|
|
}
|
|
if (!markerValue) {
|
|
element.removeAttribute(markerName);
|
|
}
|
|
});
|
|
lockCount$1--;
|
|
if (!lockCount$1) {
|
|
counters.inert = /* @__PURE__ */ new WeakMap();
|
|
counters["aria-hidden"] = /* @__PURE__ */ new WeakMap();
|
|
counters.none = /* @__PURE__ */ new WeakMap();
|
|
uncontrolledElementsSet = /* @__PURE__ */ new WeakSet();
|
|
markerMap = {};
|
|
}
|
|
};
|
|
}
|
|
function markOthers(avoidElements, ariaHidden, inert) {
|
|
if (ariaHidden === void 0) {
|
|
ariaHidden = false;
|
|
}
|
|
if (inert === void 0) {
|
|
inert = false;
|
|
}
|
|
const body = getDocument(avoidElements[0]).body;
|
|
return applyAttributeToOthers(avoidElements.concat(Array.from(body.querySelectorAll('[aria-live],[role="status"],output'))), body, ariaHidden, inert);
|
|
}
|
|
const HIDDEN_STYLES = {
|
|
border: 0,
|
|
clip: "rect(0 0 0 0)",
|
|
height: "1px",
|
|
margin: "-1px",
|
|
overflow: "hidden",
|
|
padding: 0,
|
|
position: "fixed",
|
|
whiteSpace: "nowrap",
|
|
width: "1px",
|
|
top: 0,
|
|
left: 0,
|
|
};
|
|
const FocusGuard = /* @__PURE__ */ React$7.forwardRef(function FocusGuard2(props, ref) {
|
|
const [role, setRole] = React$7.useState();
|
|
index(() => {
|
|
if (isSafari()) {
|
|
setRole("button");
|
|
}
|
|
}, []);
|
|
const restProps = {
|
|
ref,
|
|
"tabIndex": 0,
|
|
// Role is only for VoiceOver
|
|
role,
|
|
"aria-hidden": role ? void 0 : true,
|
|
[createAttribute("focus-guard")]: "",
|
|
"style": HIDDEN_STYLES,
|
|
};
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", {
|
|
...props,
|
|
...restProps,
|
|
});
|
|
});
|
|
const PortalContext = /* @__PURE__ */ React$7.createContext(null);
|
|
const usePortalContext$3 = () => React$7.useContext(PortalContext);
|
|
function useLiteMergeRefs(refs) {
|
|
return React$7.useMemo(() => {
|
|
return (value) => {
|
|
refs.forEach((ref) => {
|
|
if (ref) {
|
|
ref.current = value;
|
|
}
|
|
});
|
|
};
|
|
}, refs);
|
|
}
|
|
const LIST_LIMIT = 20;
|
|
let previouslyFocusedElements = [];
|
|
function clearDisconnectedPreviouslyFocusedElements() {
|
|
previouslyFocusedElements = previouslyFocusedElements.filter((elementRef) => {
|
|
var _elementRef$deref;
|
|
return (_elementRef$deref = elementRef.deref()) == null ? void 0 : _elementRef$deref.isConnected;
|
|
});
|
|
}
|
|
function addPreviouslyFocusedElement(element) {
|
|
clearDisconnectedPreviouslyFocusedElements();
|
|
if (element && getNodeName(element) !== "body") {
|
|
previouslyFocusedElements.push(new WeakRef(element));
|
|
if (previouslyFocusedElements.length > LIST_LIMIT) {
|
|
previouslyFocusedElements = previouslyFocusedElements.slice(-LIST_LIMIT);
|
|
}
|
|
}
|
|
}
|
|
function getPreviouslyFocusedElement() {
|
|
clearDisconnectedPreviouslyFocusedElements();
|
|
const elementRef = previouslyFocusedElements[previouslyFocusedElements.length - 1];
|
|
return elementRef == null ? void 0 : elementRef.deref();
|
|
}
|
|
function getFirstTabbableElement(container) {
|
|
const tabbableOptions = getTabbableOptions();
|
|
if (isTabbable(container, tabbableOptions)) {
|
|
return container;
|
|
}
|
|
return tabbable(container, tabbableOptions)[0] || container;
|
|
}
|
|
function handleTabIndex(floatingFocusElement, orderRef) {
|
|
var _floatingFocusElement;
|
|
if (!orderRef.current.includes("floating") && !((_floatingFocusElement = floatingFocusElement.getAttribute("role")) != null && _floatingFocusElement.includes("dialog"))) {
|
|
return;
|
|
}
|
|
const options = getTabbableOptions();
|
|
const focusableElements = focusable(floatingFocusElement, options);
|
|
const tabbableContent = focusableElements.filter((element) => {
|
|
const dataTabIndex = element.getAttribute("data-tabindex") || "";
|
|
return isTabbable(element, options) || (element.hasAttribute("data-tabindex") && !dataTabIndex.startsWith("-"));
|
|
});
|
|
const tabIndex = floatingFocusElement.getAttribute("tabindex");
|
|
if (orderRef.current.includes("floating") || tabbableContent.length === 0) {
|
|
if (tabIndex !== "0") {
|
|
floatingFocusElement.setAttribute("tabindex", "0");
|
|
}
|
|
} else if (tabIndex !== "-1" || (floatingFocusElement.hasAttribute("data-tabindex") && floatingFocusElement.getAttribute("data-tabindex") !== "-1")) {
|
|
floatingFocusElement.setAttribute("tabindex", "-1");
|
|
floatingFocusElement.setAttribute("data-tabindex", "-1");
|
|
}
|
|
}
|
|
const VisuallyHiddenDismiss = /* @__PURE__ */ React$7.forwardRef(function VisuallyHiddenDismiss2(props, ref) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("button", {
|
|
...props,
|
|
type: "button",
|
|
ref,
|
|
tabIndex: -1,
|
|
style: HIDDEN_STYLES,
|
|
});
|
|
});
|
|
function FloatingFocusManager(props) {
|
|
const {
|
|
context,
|
|
children,
|
|
disabled = false,
|
|
order = ["content"],
|
|
guards: _guards = true,
|
|
initialFocus = 0,
|
|
returnFocus = true,
|
|
restoreFocus = false,
|
|
modal = true,
|
|
visuallyHiddenDismiss = false,
|
|
closeOnFocusOut = true,
|
|
outsideElementsInert = false,
|
|
getInsideElements: _getInsideElements = () => [],
|
|
} = props;
|
|
const {
|
|
open,
|
|
onOpenChange,
|
|
events,
|
|
dataRef,
|
|
elements: { domReference, floating },
|
|
} = context;
|
|
const getNodeId = useEffectEvent(() => {
|
|
var _dataRef$current$floa;
|
|
return (_dataRef$current$floa = dataRef.current.floatingContext) == null ? void 0 : _dataRef$current$floa.nodeId;
|
|
});
|
|
const getInsideElements = useEffectEvent(_getInsideElements);
|
|
const ignoreInitialFocus = typeof initialFocus === "number" && initialFocus < 0;
|
|
const isUntrappedTypeableCombobox = isTypeableCombobox(domReference) && ignoreInitialFocus;
|
|
const inertSupported = supportsInert();
|
|
const guards = inertSupported ? _guards : true;
|
|
const useInert = !guards || (inertSupported && outsideElementsInert);
|
|
const orderRef = useLatestRef(order);
|
|
const initialFocusRef = useLatestRef(initialFocus);
|
|
const returnFocusRef = useLatestRef(returnFocus);
|
|
const tree = useFloatingTree();
|
|
const portalContext = usePortalContext$3();
|
|
const startDismissButtonRef = React$7.useRef(null);
|
|
const endDismissButtonRef = React$7.useRef(null);
|
|
const preventReturnFocusRef = React$7.useRef(false);
|
|
const isPointerDownRef = React$7.useRef(false);
|
|
const tabbableIndexRef = React$7.useRef(-1);
|
|
const blurTimeoutRef = React$7.useRef(-1);
|
|
const isInsidePortal = portalContext != null;
|
|
const floatingFocusElement = getFloatingFocusElement(floating);
|
|
const getTabbableContent = useEffectEvent(function (container) {
|
|
if (container === void 0) {
|
|
container = floatingFocusElement;
|
|
}
|
|
return container ? tabbable(container, getTabbableOptions()) : [];
|
|
});
|
|
const getTabbableElements = useEffectEvent((container) => {
|
|
const content = getTabbableContent(container);
|
|
return orderRef.current
|
|
.map((type) => {
|
|
if (domReference && type === "reference") {
|
|
return domReference;
|
|
}
|
|
if (floatingFocusElement && type === "floating") {
|
|
return floatingFocusElement;
|
|
}
|
|
return content;
|
|
})
|
|
.filter(Boolean)
|
|
.flat();
|
|
});
|
|
React$7.useEffect(() => {
|
|
if (disabled) return;
|
|
if (!modal) return;
|
|
function onKeyDown(event) {
|
|
if (event.key === "Tab") {
|
|
if (contains$1(floatingFocusElement, activeElement(getDocument$1(floatingFocusElement))) && getTabbableContent().length === 0 && !isUntrappedTypeableCombobox) {
|
|
stopEvent(event);
|
|
}
|
|
const els = getTabbableElements();
|
|
const target = getTarget$1(event);
|
|
if (orderRef.current[0] === "reference" && target === domReference) {
|
|
stopEvent(event);
|
|
if (event.shiftKey) {
|
|
enqueueFocus(els[els.length - 1]);
|
|
} else {
|
|
enqueueFocus(els[1]);
|
|
}
|
|
}
|
|
if (orderRef.current[1] === "floating" && target === floatingFocusElement && event.shiftKey) {
|
|
stopEvent(event);
|
|
enqueueFocus(els[0]);
|
|
}
|
|
}
|
|
}
|
|
const doc = getDocument$1(floatingFocusElement);
|
|
doc.addEventListener("keydown", onKeyDown);
|
|
return () => {
|
|
doc.removeEventListener("keydown", onKeyDown);
|
|
};
|
|
}, [disabled, domReference, floatingFocusElement, modal, orderRef, isUntrappedTypeableCombobox, getTabbableContent, getTabbableElements]);
|
|
React$7.useEffect(() => {
|
|
if (disabled) return;
|
|
if (!floating) return;
|
|
function handleFocusIn(event) {
|
|
const target = getTarget$1(event);
|
|
const tabbableContent = getTabbableContent();
|
|
const tabbableIndex = tabbableContent.indexOf(target);
|
|
if (tabbableIndex !== -1) {
|
|
tabbableIndexRef.current = tabbableIndex;
|
|
}
|
|
}
|
|
floating.addEventListener("focusin", handleFocusIn);
|
|
return () => {
|
|
floating.removeEventListener("focusin", handleFocusIn);
|
|
};
|
|
}, [disabled, floating, getTabbableContent]);
|
|
React$7.useEffect(() => {
|
|
if (disabled) return;
|
|
if (!closeOnFocusOut) return;
|
|
function handlePointerDown() {
|
|
isPointerDownRef.current = true;
|
|
setTimeout(() => {
|
|
isPointerDownRef.current = false;
|
|
});
|
|
}
|
|
function handleFocusOutside(event) {
|
|
const relatedTarget = event.relatedTarget;
|
|
const currentTarget = event.currentTarget;
|
|
const target = getTarget$1(event);
|
|
queueMicrotask(() => {
|
|
const nodeId = getNodeId();
|
|
const movedToUnrelatedNode = !(
|
|
contains$1(domReference, relatedTarget) ||
|
|
contains$1(floating, relatedTarget) ||
|
|
contains$1(relatedTarget, floating) ||
|
|
contains$1(portalContext == null ? void 0 : portalContext.portalNode, relatedTarget) ||
|
|
(relatedTarget != null && relatedTarget.hasAttribute(createAttribute("focus-guard"))) ||
|
|
(tree &&
|
|
(getNodeChildren$1(tree.nodesRef.current, nodeId).find((node) => {
|
|
var _node$context, _node$context2;
|
|
return (
|
|
contains$1((_node$context = node.context) == null ? void 0 : _node$context.elements.floating, relatedTarget) ||
|
|
contains$1((_node$context2 = node.context) == null ? void 0 : _node$context2.elements.domReference, relatedTarget)
|
|
);
|
|
}) ||
|
|
getNodeAncestors(tree.nodesRef.current, nodeId).find((node) => {
|
|
var _node$context3, _node$context4, _node$context5;
|
|
return (
|
|
[
|
|
(_node$context3 = node.context) == null ? void 0 : _node$context3.elements.floating,
|
|
getFloatingFocusElement((_node$context4 = node.context) == null ? void 0 : _node$context4.elements.floating),
|
|
].includes(relatedTarget) || ((_node$context5 = node.context) == null ? void 0 : _node$context5.elements.domReference) === relatedTarget
|
|
);
|
|
})))
|
|
);
|
|
if (currentTarget === domReference && floatingFocusElement) {
|
|
handleTabIndex(floatingFocusElement, orderRef);
|
|
}
|
|
if (
|
|
restoreFocus &&
|
|
currentTarget !== domReference &&
|
|
!(target != null && target.isConnected) &&
|
|
activeElement(getDocument$1(floatingFocusElement)) === getDocument$1(floatingFocusElement).body
|
|
) {
|
|
if (isHTMLElement$1(floatingFocusElement)) {
|
|
floatingFocusElement.focus();
|
|
}
|
|
const prevTabbableIndex = tabbableIndexRef.current;
|
|
const tabbableContent = getTabbableContent();
|
|
const nodeToFocus = tabbableContent[prevTabbableIndex] || tabbableContent[tabbableContent.length - 1] || floatingFocusElement;
|
|
if (isHTMLElement$1(nodeToFocus)) {
|
|
nodeToFocus.focus();
|
|
}
|
|
}
|
|
if (dataRef.current.insideReactTree) {
|
|
dataRef.current.insideReactTree = false;
|
|
return;
|
|
}
|
|
if (
|
|
(isUntrappedTypeableCombobox ? true : !modal) &&
|
|
relatedTarget &&
|
|
movedToUnrelatedNode &&
|
|
!isPointerDownRef.current && // Fix React 18 Strict Mode returnFocus due to double rendering.
|
|
relatedTarget !== getPreviouslyFocusedElement()
|
|
) {
|
|
preventReturnFocusRef.current = true;
|
|
onOpenChange(false, event, "focus-out");
|
|
}
|
|
});
|
|
}
|
|
const shouldHandleBlurCapture = Boolean(!tree && portalContext);
|
|
function markInsideReactTree() {
|
|
clearTimeoutIfSet(blurTimeoutRef);
|
|
dataRef.current.insideReactTree = true;
|
|
blurTimeoutRef.current = window.setTimeout(() => {
|
|
dataRef.current.insideReactTree = false;
|
|
});
|
|
}
|
|
if (floating && isHTMLElement$1(domReference)) {
|
|
domReference.addEventListener("focusout", handleFocusOutside);
|
|
domReference.addEventListener("pointerdown", handlePointerDown);
|
|
floating.addEventListener("focusout", handleFocusOutside);
|
|
if (shouldHandleBlurCapture) {
|
|
floating.addEventListener("focusout", markInsideReactTree, true);
|
|
}
|
|
return () => {
|
|
domReference.removeEventListener("focusout", handleFocusOutside);
|
|
domReference.removeEventListener("pointerdown", handlePointerDown);
|
|
floating.removeEventListener("focusout", handleFocusOutside);
|
|
if (shouldHandleBlurCapture) {
|
|
floating.removeEventListener("focusout", markInsideReactTree, true);
|
|
}
|
|
};
|
|
}
|
|
}, [
|
|
disabled,
|
|
domReference,
|
|
floating,
|
|
floatingFocusElement,
|
|
modal,
|
|
tree,
|
|
portalContext,
|
|
onOpenChange,
|
|
closeOnFocusOut,
|
|
restoreFocus,
|
|
getTabbableContent,
|
|
isUntrappedTypeableCombobox,
|
|
getNodeId,
|
|
orderRef,
|
|
dataRef,
|
|
]);
|
|
const beforeGuardRef = React$7.useRef(null);
|
|
const afterGuardRef = React$7.useRef(null);
|
|
const mergedBeforeGuardRef = useLiteMergeRefs([beforeGuardRef, portalContext == null ? void 0 : portalContext.beforeInsideRef]);
|
|
const mergedAfterGuardRef = useLiteMergeRefs([afterGuardRef, portalContext == null ? void 0 : portalContext.afterInsideRef]);
|
|
React$7.useEffect(() => {
|
|
var _portalContext$portal, _ancestors$find;
|
|
if (disabled) return;
|
|
if (!floating) return;
|
|
const portalNodes = Array.from(
|
|
(portalContext == null || (_portalContext$portal = portalContext.portalNode) == null ? void 0 : _portalContext$portal.querySelectorAll("[" + createAttribute("portal") + "]")) || [],
|
|
);
|
|
const ancestors = tree ? getNodeAncestors(tree.nodesRef.current, getNodeId()) : [];
|
|
const rootAncestorComboboxDomReference =
|
|
(
|
|
(_ancestors$find = ancestors.find((node) => {
|
|
var _node$context6;
|
|
return isTypeableCombobox(((_node$context6 = node.context) == null ? void 0 : _node$context6.elements.domReference) || null);
|
|
})) == null || (_ancestors$find = _ancestors$find.context) == null
|
|
) ?
|
|
void 0
|
|
: _ancestors$find.elements.domReference;
|
|
const insideElements = [
|
|
floating,
|
|
rootAncestorComboboxDomReference,
|
|
...portalNodes,
|
|
...getInsideElements(),
|
|
startDismissButtonRef.current,
|
|
endDismissButtonRef.current,
|
|
beforeGuardRef.current,
|
|
afterGuardRef.current,
|
|
portalContext == null ? void 0 : portalContext.beforeOutsideRef.current,
|
|
portalContext == null ? void 0 : portalContext.afterOutsideRef.current,
|
|
orderRef.current.includes("reference") || isUntrappedTypeableCombobox ? domReference : null,
|
|
].filter((x) => x != null);
|
|
const cleanup2 = modal || isUntrappedTypeableCombobox ? markOthers(insideElements, !useInert, useInert) : markOthers(insideElements);
|
|
return () => {
|
|
cleanup2();
|
|
};
|
|
}, [disabled, domReference, floating, modal, orderRef, portalContext, isUntrappedTypeableCombobox, guards, useInert, tree, getNodeId, getInsideElements]);
|
|
index(() => {
|
|
if (disabled || !isHTMLElement$1(floatingFocusElement)) return;
|
|
const doc = getDocument$1(floatingFocusElement);
|
|
const previouslyFocusedElement = activeElement(doc);
|
|
queueMicrotask(() => {
|
|
const focusableElements = getTabbableElements(floatingFocusElement);
|
|
const initialFocusValue = initialFocusRef.current;
|
|
const elToFocus = (typeof initialFocusValue === "number" ? focusableElements[initialFocusValue] : initialFocusValue.current) || floatingFocusElement;
|
|
const focusAlreadyInsideFloatingEl = contains$1(floatingFocusElement, previouslyFocusedElement);
|
|
if (!ignoreInitialFocus && !focusAlreadyInsideFloatingEl && open) {
|
|
enqueueFocus(elToFocus, {
|
|
preventScroll: elToFocus === floatingFocusElement,
|
|
});
|
|
}
|
|
});
|
|
}, [disabled, open, floatingFocusElement, ignoreInitialFocus, getTabbableElements, initialFocusRef]);
|
|
index(() => {
|
|
if (disabled || !floatingFocusElement) return;
|
|
const doc = getDocument$1(floatingFocusElement);
|
|
const previouslyFocusedElement = activeElement(doc);
|
|
addPreviouslyFocusedElement(previouslyFocusedElement);
|
|
function onOpenChange2(_ref) {
|
|
let { reason, event, nested } = _ref;
|
|
if (["hover", "safe-polygon"].includes(reason) && event.type === "mouseleave") {
|
|
preventReturnFocusRef.current = true;
|
|
}
|
|
if (reason !== "outside-press") return;
|
|
if (nested) {
|
|
preventReturnFocusRef.current = false;
|
|
} else if (isVirtualClick(event) || isVirtualPointerEvent(event)) {
|
|
preventReturnFocusRef.current = false;
|
|
} else {
|
|
let isPreventScrollSupported = false;
|
|
document.createElement("div").focus({
|
|
get preventScroll() {
|
|
isPreventScrollSupported = true;
|
|
return false;
|
|
},
|
|
});
|
|
if (isPreventScrollSupported) {
|
|
preventReturnFocusRef.current = false;
|
|
} else {
|
|
preventReturnFocusRef.current = true;
|
|
}
|
|
}
|
|
}
|
|
events.on("openchange", onOpenChange2);
|
|
const fallbackEl = doc.createElement("span");
|
|
fallbackEl.setAttribute("tabindex", "-1");
|
|
fallbackEl.setAttribute("aria-hidden", "true");
|
|
Object.assign(fallbackEl.style, HIDDEN_STYLES);
|
|
if (isInsidePortal && domReference) {
|
|
domReference.insertAdjacentElement("afterend", fallbackEl);
|
|
}
|
|
function getReturnElement() {
|
|
if (typeof returnFocusRef.current === "boolean") {
|
|
const el = domReference || getPreviouslyFocusedElement();
|
|
return el && el.isConnected ? el : fallbackEl;
|
|
}
|
|
return returnFocusRef.current.current || fallbackEl;
|
|
}
|
|
return () => {
|
|
events.off("openchange", onOpenChange2);
|
|
const activeEl = activeElement(doc);
|
|
const isFocusInsideFloatingTree =
|
|
contains$1(floating, activeEl) ||
|
|
(tree &&
|
|
getNodeChildren$1(tree.nodesRef.current, getNodeId(), false).some((node) => {
|
|
var _node$context7;
|
|
return contains$1((_node$context7 = node.context) == null ? void 0 : _node$context7.elements.floating, activeEl);
|
|
}));
|
|
const returnElement = getReturnElement();
|
|
queueMicrotask(() => {
|
|
const tabbableReturnElement = getFirstTabbableElement(returnElement);
|
|
if (
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
returnFocusRef.current &&
|
|
!preventReturnFocusRef.current &&
|
|
isHTMLElement$1(tabbableReturnElement) && // If the focus moved somewhere else after mount, avoid returning focus
|
|
// since it likely entered a different element which should be
|
|
// respected: https://github.com/floating-ui/floating-ui/issues/2607
|
|
(tabbableReturnElement !== activeEl && activeEl !== doc.body ? isFocusInsideFloatingTree : true)
|
|
) {
|
|
tabbableReturnElement.focus({
|
|
preventScroll: true,
|
|
});
|
|
}
|
|
fallbackEl.remove();
|
|
});
|
|
};
|
|
}, [disabled, floating, floatingFocusElement, returnFocusRef, dataRef, events, tree, isInsidePortal, domReference, getNodeId]);
|
|
React$7.useEffect(() => {
|
|
queueMicrotask(() => {
|
|
preventReturnFocusRef.current = false;
|
|
});
|
|
return () => {
|
|
queueMicrotask(clearDisconnectedPreviouslyFocusedElements);
|
|
};
|
|
}, [disabled]);
|
|
index(() => {
|
|
if (disabled) return;
|
|
if (!portalContext) return;
|
|
portalContext.setFocusManagerState({
|
|
modal,
|
|
closeOnFocusOut,
|
|
open,
|
|
onOpenChange,
|
|
domReference,
|
|
});
|
|
return () => {
|
|
portalContext.setFocusManagerState(null);
|
|
};
|
|
}, [disabled, portalContext, modal, open, onOpenChange, closeOnFocusOut, domReference]);
|
|
index(() => {
|
|
if (disabled) return;
|
|
if (!floatingFocusElement) return;
|
|
handleTabIndex(floatingFocusElement, orderRef);
|
|
}, [disabled, floatingFocusElement, orderRef]);
|
|
function renderDismissButton(location) {
|
|
if (disabled || !visuallyHiddenDismiss || !modal) {
|
|
return null;
|
|
}
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(VisuallyHiddenDismiss, {
|
|
ref: location === "start" ? startDismissButtonRef : endDismissButtonRef,
|
|
onClick: (event) => onOpenChange(false, event.nativeEvent),
|
|
children: typeof visuallyHiddenDismiss === "string" ? visuallyHiddenDismiss : "Dismiss",
|
|
});
|
|
}
|
|
const shouldRenderGuards = !disabled && guards && (modal ? !isUntrappedTypeableCombobox : true) && (isInsidePortal || modal);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
|
|
children: [
|
|
shouldRenderGuards &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(FocusGuard, {
|
|
"data-type": "inside",
|
|
"ref": mergedBeforeGuardRef,
|
|
"onFocus": (event) => {
|
|
if (modal) {
|
|
const els = getTabbableElements();
|
|
enqueueFocus(order[0] === "reference" ? els[0] : els[els.length - 1]);
|
|
} else if (portalContext != null && portalContext.preserveTabOrder && portalContext.portalNode) {
|
|
preventReturnFocusRef.current = false;
|
|
if (isOutsideEvent(event, portalContext.portalNode)) {
|
|
const nextTabbable = getNextTabbable(domReference);
|
|
nextTabbable == null || nextTabbable.focus();
|
|
} else {
|
|
var _portalContext$before;
|
|
(_portalContext$before = portalContext.beforeOutsideRef.current) == null || _portalContext$before.focus();
|
|
}
|
|
}
|
|
},
|
|
}),
|
|
!isUntrappedTypeableCombobox && renderDismissButton("start"),
|
|
children,
|
|
renderDismissButton("end"),
|
|
shouldRenderGuards &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(FocusGuard, {
|
|
"data-type": "inside",
|
|
"ref": mergedAfterGuardRef,
|
|
"onFocus": (event) => {
|
|
if (modal) {
|
|
enqueueFocus(getTabbableElements()[0]);
|
|
} else if (portalContext != null && portalContext.preserveTabOrder && portalContext.portalNode) {
|
|
if (closeOnFocusOut) {
|
|
preventReturnFocusRef.current = true;
|
|
}
|
|
if (isOutsideEvent(event, portalContext.portalNode)) {
|
|
const prevTabbable = getPreviousTabbable(domReference);
|
|
prevTabbable == null || prevTabbable.focus();
|
|
} else {
|
|
var _portalContext$afterO;
|
|
(_portalContext$afterO = portalContext.afterOutsideRef.current) == null || _portalContext$afterO.focus();
|
|
}
|
|
}
|
|
},
|
|
}),
|
|
],
|
|
});
|
|
}
|
|
const bubbleHandlerKeys = {
|
|
pointerdown: "onPointerDown",
|
|
mousedown: "onMouseDown",
|
|
click: "onClick",
|
|
};
|
|
const captureHandlerKeys = {
|
|
pointerdown: "onPointerDownCapture",
|
|
mousedown: "onMouseDownCapture",
|
|
click: "onClickCapture",
|
|
};
|
|
const normalizeProp = (normalizable) => {
|
|
var _normalizable$escapeK, _normalizable$outside;
|
|
return {
|
|
escapeKey:
|
|
typeof normalizable === "boolean" ? normalizable
|
|
: (_normalizable$escapeK = normalizable == null ? void 0 : normalizable.escapeKey) != null ? _normalizable$escapeK
|
|
: false,
|
|
outsidePress:
|
|
typeof normalizable === "boolean" ? normalizable
|
|
: (_normalizable$outside = normalizable == null ? void 0 : normalizable.outsidePress) != null ? _normalizable$outside
|
|
: true,
|
|
};
|
|
};
|
|
function useDismiss(context, props) {
|
|
if (props === void 0) {
|
|
props = {};
|
|
}
|
|
const { open, onOpenChange, elements, dataRef } = context;
|
|
const {
|
|
enabled = true,
|
|
escapeKey = true,
|
|
outsidePress: unstable_outsidePress = true,
|
|
outsidePressEvent = "pointerdown",
|
|
referencePress = false,
|
|
referencePressEvent = "pointerdown",
|
|
ancestorScroll = false,
|
|
bubbles,
|
|
capture,
|
|
} = props;
|
|
const tree = useFloatingTree();
|
|
const outsidePressFn = useEffectEvent(typeof unstable_outsidePress === "function" ? unstable_outsidePress : () => false);
|
|
const outsidePress = typeof unstable_outsidePress === "function" ? outsidePressFn : unstable_outsidePress;
|
|
const endedOrStartedInsideRef = React$7.useRef(false);
|
|
const { escapeKey: escapeKeyBubbles, outsidePress: outsidePressBubbles } = normalizeProp(bubbles);
|
|
const { escapeKey: escapeKeyCapture, outsidePress: outsidePressCapture } = normalizeProp(capture);
|
|
const isComposingRef = React$7.useRef(false);
|
|
const closeOnEscapeKeyDown = useEffectEvent((event) => {
|
|
var _dataRef$current$floa;
|
|
if (!open || !enabled || !escapeKey || event.key !== "Escape") {
|
|
return;
|
|
}
|
|
if (isComposingRef.current) {
|
|
return;
|
|
}
|
|
const nodeId = (_dataRef$current$floa = dataRef.current.floatingContext) == null ? void 0 : _dataRef$current$floa.nodeId;
|
|
const children = tree ? getNodeChildren$1(tree.nodesRef.current, nodeId) : [];
|
|
if (!escapeKeyBubbles) {
|
|
event.stopPropagation();
|
|
if (children.length > 0) {
|
|
let shouldDismiss = true;
|
|
children.forEach((child) => {
|
|
var _child$context;
|
|
if ((_child$context = child.context) != null && _child$context.open && !child.context.dataRef.current.__escapeKeyBubbles) {
|
|
shouldDismiss = false;
|
|
return;
|
|
}
|
|
});
|
|
if (!shouldDismiss) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
onOpenChange(false, isReactEvent(event) ? event.nativeEvent : event, "escape-key");
|
|
});
|
|
const closeOnEscapeKeyDownCapture = useEffectEvent((event) => {
|
|
var _getTarget2;
|
|
const callback = () => {
|
|
var _getTarget;
|
|
closeOnEscapeKeyDown(event);
|
|
(_getTarget = getTarget$1(event)) == null || _getTarget.removeEventListener("keydown", callback);
|
|
};
|
|
(_getTarget2 = getTarget$1(event)) == null || _getTarget2.addEventListener("keydown", callback);
|
|
});
|
|
const closeOnPressOutside = useEffectEvent((event) => {
|
|
var _dataRef$current$floa2;
|
|
const insideReactTree = dataRef.current.insideReactTree;
|
|
dataRef.current.insideReactTree = false;
|
|
const endedOrStartedInside = endedOrStartedInsideRef.current;
|
|
endedOrStartedInsideRef.current = false;
|
|
if (outsidePressEvent === "click" && endedOrStartedInside) {
|
|
return;
|
|
}
|
|
if (insideReactTree) {
|
|
return;
|
|
}
|
|
if (typeof outsidePress === "function" && !outsidePress(event)) {
|
|
return;
|
|
}
|
|
const target = getTarget$1(event);
|
|
const inertSelector = "[" + createAttribute("inert") + "]";
|
|
const markers = getDocument$1(elements.floating).querySelectorAll(inertSelector);
|
|
let targetRootAncestor = isElement(target) ? target : null;
|
|
while (targetRootAncestor && !isLastTraversableNode(targetRootAncestor)) {
|
|
const nextParent = getParentNode(targetRootAncestor);
|
|
if (isLastTraversableNode(nextParent) || !isElement(nextParent)) {
|
|
break;
|
|
}
|
|
targetRootAncestor = nextParent;
|
|
}
|
|
if (
|
|
markers.length &&
|
|
isElement(target) &&
|
|
!isRootElement(target) && // Clicked on a direct ancestor (e.g. FloatingOverlay).
|
|
!contains$1(target, elements.floating) && // If the target root element contains none of the markers, then the
|
|
// element was injected after the floating element rendered.
|
|
Array.from(markers).every((marker) => !contains$1(targetRootAncestor, marker))
|
|
) {
|
|
return;
|
|
}
|
|
if (isHTMLElement$1(target) && floating) {
|
|
const lastTraversableNode = isLastTraversableNode(target);
|
|
const style = getComputedStyle$1(target);
|
|
const scrollRe = /auto|scroll/;
|
|
const isScrollableX = lastTraversableNode || scrollRe.test(style.overflowX);
|
|
const isScrollableY = lastTraversableNode || scrollRe.test(style.overflowY);
|
|
const canScrollX = isScrollableX && target.clientWidth > 0 && target.scrollWidth > target.clientWidth;
|
|
const canScrollY = isScrollableY && target.clientHeight > 0 && target.scrollHeight > target.clientHeight;
|
|
const isRTL = style.direction === "rtl";
|
|
const pressedVerticalScrollbar = canScrollY && (isRTL ? event.offsetX <= target.offsetWidth - target.clientWidth : event.offsetX > target.clientWidth);
|
|
const pressedHorizontalScrollbar = canScrollX && event.offsetY > target.clientHeight;
|
|
if (pressedVerticalScrollbar || pressedHorizontalScrollbar) {
|
|
return;
|
|
}
|
|
}
|
|
const nodeId = (_dataRef$current$floa2 = dataRef.current.floatingContext) == null ? void 0 : _dataRef$current$floa2.nodeId;
|
|
const targetIsInsideChildren =
|
|
tree &&
|
|
getNodeChildren$1(tree.nodesRef.current, nodeId).some((node) => {
|
|
var _node$context;
|
|
return isEventTargetWithin(event, (_node$context = node.context) == null ? void 0 : _node$context.elements.floating);
|
|
});
|
|
if (isEventTargetWithin(event, elements.floating) || isEventTargetWithin(event, elements.domReference) || targetIsInsideChildren) {
|
|
return;
|
|
}
|
|
const children = tree ? getNodeChildren$1(tree.nodesRef.current, nodeId) : [];
|
|
if (children.length > 0) {
|
|
let shouldDismiss = true;
|
|
children.forEach((child) => {
|
|
var _child$context2;
|
|
if ((_child$context2 = child.context) != null && _child$context2.open && !child.context.dataRef.current.__outsidePressBubbles) {
|
|
shouldDismiss = false;
|
|
return;
|
|
}
|
|
});
|
|
if (!shouldDismiss) {
|
|
return;
|
|
}
|
|
}
|
|
onOpenChange(false, event, "outside-press");
|
|
});
|
|
const closeOnPressOutsideCapture = useEffectEvent((event) => {
|
|
var _getTarget4;
|
|
const callback = () => {
|
|
var _getTarget3;
|
|
closeOnPressOutside(event);
|
|
(_getTarget3 = getTarget$1(event)) == null || _getTarget3.removeEventListener(outsidePressEvent, callback);
|
|
};
|
|
(_getTarget4 = getTarget$1(event)) == null || _getTarget4.addEventListener(outsidePressEvent, callback);
|
|
});
|
|
React$7.useEffect(() => {
|
|
if (!open || !enabled) {
|
|
return;
|
|
}
|
|
dataRef.current.__escapeKeyBubbles = escapeKeyBubbles;
|
|
dataRef.current.__outsidePressBubbles = outsidePressBubbles;
|
|
let compositionTimeout = -1;
|
|
function onScroll(event) {
|
|
onOpenChange(false, event, "ancestor-scroll");
|
|
}
|
|
function handleCompositionStart() {
|
|
window.clearTimeout(compositionTimeout);
|
|
isComposingRef.current = true;
|
|
}
|
|
function handleCompositionEnd() {
|
|
compositionTimeout = window.setTimeout(
|
|
() => {
|
|
isComposingRef.current = false;
|
|
},
|
|
// 0ms or 1ms don't work in Safari. 5ms appears to consistently work.
|
|
// Only apply to WebKit for the test to remain 0ms.
|
|
isWebKit() ? 5 : 0,
|
|
);
|
|
}
|
|
const doc = getDocument$1(elements.floating);
|
|
if (escapeKey) {
|
|
doc.addEventListener("keydown", escapeKeyCapture ? closeOnEscapeKeyDownCapture : closeOnEscapeKeyDown, escapeKeyCapture);
|
|
doc.addEventListener("compositionstart", handleCompositionStart);
|
|
doc.addEventListener("compositionend", handleCompositionEnd);
|
|
}
|
|
outsidePress && doc.addEventListener(outsidePressEvent, outsidePressCapture ? closeOnPressOutsideCapture : closeOnPressOutside, outsidePressCapture);
|
|
let ancestors = [];
|
|
if (ancestorScroll) {
|
|
if (isElement(elements.domReference)) {
|
|
ancestors = getOverflowAncestors(elements.domReference);
|
|
}
|
|
if (isElement(elements.floating)) {
|
|
ancestors = ancestors.concat(getOverflowAncestors(elements.floating));
|
|
}
|
|
if (!isElement(elements.reference) && elements.reference && elements.reference.contextElement) {
|
|
ancestors = ancestors.concat(getOverflowAncestors(elements.reference.contextElement));
|
|
}
|
|
}
|
|
ancestors = ancestors.filter((ancestor) => {
|
|
var _doc$defaultView;
|
|
return ancestor !== ((_doc$defaultView = doc.defaultView) == null ? void 0 : _doc$defaultView.visualViewport);
|
|
});
|
|
ancestors.forEach((ancestor) => {
|
|
ancestor.addEventListener("scroll", onScroll, {
|
|
passive: true,
|
|
});
|
|
});
|
|
return () => {
|
|
if (escapeKey) {
|
|
doc.removeEventListener("keydown", escapeKeyCapture ? closeOnEscapeKeyDownCapture : closeOnEscapeKeyDown, escapeKeyCapture);
|
|
doc.removeEventListener("compositionstart", handleCompositionStart);
|
|
doc.removeEventListener("compositionend", handleCompositionEnd);
|
|
}
|
|
outsidePress && doc.removeEventListener(outsidePressEvent, outsidePressCapture ? closeOnPressOutsideCapture : closeOnPressOutside, outsidePressCapture);
|
|
ancestors.forEach((ancestor) => {
|
|
ancestor.removeEventListener("scroll", onScroll);
|
|
});
|
|
window.clearTimeout(compositionTimeout);
|
|
};
|
|
}, [
|
|
dataRef,
|
|
elements,
|
|
escapeKey,
|
|
outsidePress,
|
|
outsidePressEvent,
|
|
open,
|
|
onOpenChange,
|
|
ancestorScroll,
|
|
enabled,
|
|
escapeKeyBubbles,
|
|
outsidePressBubbles,
|
|
closeOnEscapeKeyDown,
|
|
escapeKeyCapture,
|
|
closeOnEscapeKeyDownCapture,
|
|
closeOnPressOutside,
|
|
outsidePressCapture,
|
|
closeOnPressOutsideCapture,
|
|
]);
|
|
React$7.useEffect(() => {
|
|
dataRef.current.insideReactTree = false;
|
|
}, [dataRef, outsidePress, outsidePressEvent]);
|
|
const reference = React$7.useMemo(
|
|
() => ({
|
|
onKeyDown: closeOnEscapeKeyDown,
|
|
...(referencePress && {
|
|
[bubbleHandlerKeys[referencePressEvent]]: (event) => {
|
|
onOpenChange(false, event.nativeEvent, "reference-press");
|
|
},
|
|
...(referencePressEvent !== "click" && {
|
|
onClick(event) {
|
|
onOpenChange(false, event.nativeEvent, "reference-press");
|
|
},
|
|
}),
|
|
}),
|
|
}),
|
|
[closeOnEscapeKeyDown, onOpenChange, referencePress, referencePressEvent],
|
|
);
|
|
const floating = React$7.useMemo(() => {
|
|
function setMouseDownOrUpInside(event) {
|
|
if (event.button !== 0) {
|
|
return;
|
|
}
|
|
endedOrStartedInsideRef.current = true;
|
|
}
|
|
return {
|
|
onKeyDown: closeOnEscapeKeyDown,
|
|
onMouseDown: setMouseDownOrUpInside,
|
|
onMouseUp: setMouseDownOrUpInside,
|
|
[captureHandlerKeys[outsidePressEvent]]: () => {
|
|
dataRef.current.insideReactTree = true;
|
|
},
|
|
};
|
|
}, [closeOnEscapeKeyDown, outsidePressEvent, dataRef]);
|
|
return React$7.useMemo(
|
|
() =>
|
|
enabled ?
|
|
{
|
|
reference,
|
|
floating,
|
|
}
|
|
: {},
|
|
[enabled, reference, floating],
|
|
);
|
|
}
|
|
function useFloatingRootContext(options) {
|
|
const { open = false, onOpenChange: onOpenChangeProp, elements: elementsProp } = options;
|
|
const floatingId = useId();
|
|
const dataRef = React$7.useRef({});
|
|
const [events] = React$7.useState(() => createEventEmitter());
|
|
const nested = useFloatingParentNodeId() != null;
|
|
const [positionReference, setPositionReference] = React$7.useState(elementsProp.reference);
|
|
const onOpenChange = useEffectEvent((open2, event, reason) => {
|
|
dataRef.current.openEvent = open2 ? event : void 0;
|
|
events.emit("openchange", {
|
|
open: open2,
|
|
event,
|
|
reason,
|
|
nested,
|
|
});
|
|
onOpenChangeProp == null || onOpenChangeProp(open2, event, reason);
|
|
});
|
|
const refs = React$7.useMemo(
|
|
() => ({
|
|
setPositionReference,
|
|
}),
|
|
[],
|
|
);
|
|
const elements = React$7.useMemo(
|
|
() => ({
|
|
reference: positionReference || elementsProp.reference || null,
|
|
floating: elementsProp.floating || null,
|
|
domReference: elementsProp.reference,
|
|
}),
|
|
[positionReference, elementsProp.reference, elementsProp.floating],
|
|
);
|
|
return React$7.useMemo(
|
|
() => ({
|
|
dataRef,
|
|
open,
|
|
onOpenChange,
|
|
elements,
|
|
events,
|
|
floatingId,
|
|
refs,
|
|
}),
|
|
[open, onOpenChange, elements, events, floatingId, refs],
|
|
);
|
|
}
|
|
function useFloating(options) {
|
|
if (options === void 0) {
|
|
options = {};
|
|
}
|
|
const { nodeId } = options;
|
|
const internalRootContext = useFloatingRootContext({
|
|
...options,
|
|
elements: {
|
|
reference: null,
|
|
floating: null,
|
|
...options.elements,
|
|
},
|
|
});
|
|
const rootContext = options.rootContext || internalRootContext;
|
|
const computedElements = rootContext.elements;
|
|
const [_domReference, setDomReference] = React$7.useState(null);
|
|
const [positionReference, _setPositionReference] = React$7.useState(null);
|
|
const optionDomReference = computedElements == null ? void 0 : computedElements.domReference;
|
|
const domReference = optionDomReference || _domReference;
|
|
const domReferenceRef = React$7.useRef(null);
|
|
const tree = useFloatingTree();
|
|
index(() => {
|
|
if (domReference) {
|
|
domReferenceRef.current = domReference;
|
|
}
|
|
}, [domReference]);
|
|
const position = useFloating$1({
|
|
...options,
|
|
elements: {
|
|
...computedElements,
|
|
...(positionReference && {
|
|
reference: positionReference,
|
|
}),
|
|
},
|
|
});
|
|
const setPositionReference = React$7.useCallback(
|
|
(node) => {
|
|
const computedPositionReference =
|
|
isElement(node) ?
|
|
{
|
|
getBoundingClientRect: () => node.getBoundingClientRect(),
|
|
getClientRects: () => node.getClientRects(),
|
|
contextElement: node,
|
|
}
|
|
: node;
|
|
_setPositionReference(computedPositionReference);
|
|
position.refs.setReference(computedPositionReference);
|
|
},
|
|
[position.refs],
|
|
);
|
|
const setReference = React$7.useCallback(
|
|
(node) => {
|
|
if (isElement(node) || node === null) {
|
|
domReferenceRef.current = node;
|
|
setDomReference(node);
|
|
}
|
|
if (
|
|
isElement(position.refs.reference.current) ||
|
|
position.refs.reference.current === null || // Don't allow setting virtual elements using the old technique back to
|
|
// `null` to support `positionReference` + an unstable `reference`
|
|
// callback ref.
|
|
(node !== null && !isElement(node))
|
|
) {
|
|
position.refs.setReference(node);
|
|
}
|
|
},
|
|
[position.refs],
|
|
);
|
|
const refs = React$7.useMemo(
|
|
() => ({
|
|
...position.refs,
|
|
setReference,
|
|
setPositionReference,
|
|
domReference: domReferenceRef,
|
|
}),
|
|
[position.refs, setReference, setPositionReference],
|
|
);
|
|
const elements = React$7.useMemo(
|
|
() => ({
|
|
...position.elements,
|
|
domReference,
|
|
}),
|
|
[position.elements, domReference],
|
|
);
|
|
const context = React$7.useMemo(
|
|
() => ({
|
|
...position,
|
|
...rootContext,
|
|
refs,
|
|
elements,
|
|
nodeId,
|
|
}),
|
|
[position, refs, elements, nodeId, rootContext],
|
|
);
|
|
index(() => {
|
|
rootContext.dataRef.current.floatingContext = context;
|
|
const node = tree == null ? void 0 : tree.nodesRef.current.find((node2) => node2.id === nodeId);
|
|
if (node) {
|
|
node.context = context;
|
|
}
|
|
});
|
|
return React$7.useMemo(
|
|
() => ({
|
|
...position,
|
|
context,
|
|
refs,
|
|
elements,
|
|
}),
|
|
[position, refs, elements, context],
|
|
);
|
|
}
|
|
function mergeProps(userProps, propsList, elementKey) {
|
|
const map = /* @__PURE__ */ new Map();
|
|
const isItem = elementKey === "item";
|
|
let domUserProps = userProps;
|
|
if (isItem && userProps) {
|
|
const { [ACTIVE_KEY]: _, [SELECTED_KEY]: __, ...validProps } = userProps;
|
|
domUserProps = validProps;
|
|
}
|
|
return {
|
|
...(elementKey === "floating" && {
|
|
tabIndex: -1,
|
|
[FOCUSABLE_ATTRIBUTE]: "",
|
|
}),
|
|
...domUserProps,
|
|
...propsList
|
|
.map((value) => {
|
|
const propsOrGetProps = value ? value[elementKey] : null;
|
|
if (typeof propsOrGetProps === "function") {
|
|
return userProps ? propsOrGetProps(userProps) : null;
|
|
}
|
|
return propsOrGetProps;
|
|
})
|
|
.concat(userProps)
|
|
.reduce((acc, props) => {
|
|
if (!props) {
|
|
return acc;
|
|
}
|
|
Object.entries(props).forEach((_ref) => {
|
|
let [key, value] = _ref;
|
|
if (isItem && [ACTIVE_KEY, SELECTED_KEY].includes(key)) {
|
|
return;
|
|
}
|
|
if (key.indexOf("on") === 0) {
|
|
if (!map.has(key)) {
|
|
map.set(key, []);
|
|
}
|
|
if (typeof value === "function") {
|
|
var _map$get;
|
|
(_map$get = map.get(key)) == null || _map$get.push(value);
|
|
acc[key] = function () {
|
|
var _map$get2;
|
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
args[_key] = arguments[_key];
|
|
}
|
|
return (_map$get2 = map.get(key)) == null ? void 0 : _map$get2.map((fn) => fn(...args)).find((val) => val !== void 0);
|
|
};
|
|
}
|
|
} else {
|
|
acc[key] = value;
|
|
}
|
|
});
|
|
return acc;
|
|
}, {}),
|
|
};
|
|
}
|
|
function useInteractions(propsList) {
|
|
if (propsList === void 0) {
|
|
propsList = [];
|
|
}
|
|
const referenceDeps = propsList.map((key) => (key == null ? void 0 : key.reference));
|
|
const floatingDeps = propsList.map((key) => (key == null ? void 0 : key.floating));
|
|
const itemDeps = propsList.map((key) => (key == null ? void 0 : key.item));
|
|
const getReferenceProps = React$7.useCallback(
|
|
(userProps) => mergeProps(userProps, propsList, "reference"),
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
referenceDeps,
|
|
);
|
|
const getFloatingProps = React$7.useCallback(
|
|
(userProps) => mergeProps(userProps, propsList, "floating"),
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
floatingDeps,
|
|
);
|
|
const getItemProps = React$7.useCallback(
|
|
(userProps) => mergeProps(userProps, propsList, "item"),
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
itemDeps,
|
|
);
|
|
return React$7.useMemo(
|
|
() => ({
|
|
getReferenceProps,
|
|
getFloatingProps,
|
|
getItemProps,
|
|
}),
|
|
[getReferenceProps, getFloatingProps, getItemProps],
|
|
);
|
|
}
|
|
const camelCaseToKebabCase = (str) => str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, ($, ofs) => (ofs ? "-" : "") + $.toLowerCase());
|
|
function execWithArgsOrReturn(valueOrFn, args) {
|
|
return typeof valueOrFn === "function" ? valueOrFn(args) : valueOrFn;
|
|
}
|
|
function useDelayUnmount(open, durationMs) {
|
|
const [isMounted, setIsMounted] = React$7.useState(open);
|
|
if (open && !isMounted) {
|
|
setIsMounted(true);
|
|
}
|
|
React$7.useEffect(() => {
|
|
if (!open && isMounted) {
|
|
const timeout = setTimeout(() => setIsMounted(false), durationMs);
|
|
return () => clearTimeout(timeout);
|
|
}
|
|
}, [open, isMounted, durationMs]);
|
|
return isMounted;
|
|
}
|
|
function useTransitionStatus(context, props) {
|
|
if (props === void 0) {
|
|
props = {};
|
|
}
|
|
const {
|
|
open,
|
|
elements: { floating },
|
|
} = context;
|
|
const { duration = 250 } = props;
|
|
const isNumberDuration = typeof duration === "number";
|
|
const closeDuration = (isNumberDuration ? duration : duration.close) || 0;
|
|
const [status, setStatus] = React$7.useState("unmounted");
|
|
const isMounted = useDelayUnmount(open, closeDuration);
|
|
if (!isMounted && status === "close") {
|
|
setStatus("unmounted");
|
|
}
|
|
index(() => {
|
|
if (!floating) return;
|
|
if (open) {
|
|
setStatus("initial");
|
|
const frame = requestAnimationFrame(() => {
|
|
ReactDOM.flushSync(() => {
|
|
setStatus("open");
|
|
});
|
|
});
|
|
return () => {
|
|
cancelAnimationFrame(frame);
|
|
};
|
|
}
|
|
setStatus("close");
|
|
}, [open, floating]);
|
|
return {
|
|
isMounted,
|
|
status,
|
|
};
|
|
}
|
|
function useTransitionStyles(context, props) {
|
|
if (props === void 0) {
|
|
props = {};
|
|
}
|
|
const {
|
|
initial: unstable_initial = {
|
|
opacity: 0,
|
|
},
|
|
open: unstable_open,
|
|
close: unstable_close,
|
|
common: unstable_common,
|
|
duration = 250,
|
|
} = props;
|
|
const placement = context.placement;
|
|
const side = placement.split("-")[0];
|
|
const fnArgs = React$7.useMemo(
|
|
() => ({
|
|
side,
|
|
placement,
|
|
}),
|
|
[side, placement],
|
|
);
|
|
const isNumberDuration = typeof duration === "number";
|
|
const openDuration = (isNumberDuration ? duration : duration.open) || 0;
|
|
const closeDuration = (isNumberDuration ? duration : duration.close) || 0;
|
|
const [styles, setStyles] = React$7.useState(() => ({
|
|
...execWithArgsOrReturn(unstable_common, fnArgs),
|
|
...execWithArgsOrReturn(unstable_initial, fnArgs),
|
|
}));
|
|
const { isMounted, status } = useTransitionStatus(context, {
|
|
duration,
|
|
});
|
|
const initialRef = useLatestRef(unstable_initial);
|
|
const openRef = useLatestRef(unstable_open);
|
|
const closeRef = useLatestRef(unstable_close);
|
|
const commonRef = useLatestRef(unstable_common);
|
|
index(() => {
|
|
const initialStyles = execWithArgsOrReturn(initialRef.current, fnArgs);
|
|
const closeStyles = execWithArgsOrReturn(closeRef.current, fnArgs);
|
|
const commonStyles = execWithArgsOrReturn(commonRef.current, fnArgs);
|
|
const openStyles =
|
|
execWithArgsOrReturn(openRef.current, fnArgs) ||
|
|
Object.keys(initialStyles).reduce((acc, key) => {
|
|
acc[key] = "";
|
|
return acc;
|
|
}, {});
|
|
if (status === "initial") {
|
|
setStyles((styles2) => ({
|
|
transitionProperty: styles2.transitionProperty,
|
|
...commonStyles,
|
|
...initialStyles,
|
|
}));
|
|
}
|
|
if (status === "open") {
|
|
setStyles({
|
|
transitionProperty: Object.keys(openStyles).map(camelCaseToKebabCase).join(","),
|
|
transitionDuration: openDuration + "ms",
|
|
...commonStyles,
|
|
...openStyles,
|
|
});
|
|
}
|
|
if (status === "close") {
|
|
const styles2 = closeStyles || initialStyles;
|
|
setStyles({
|
|
transitionProperty: Object.keys(styles2).map(camelCaseToKebabCase).join(","),
|
|
transitionDuration: closeDuration + "ms",
|
|
...commonStyles,
|
|
...styles2,
|
|
});
|
|
}
|
|
}, [closeDuration, closeRef, initialRef, openRef, commonRef, openDuration, status, fnArgs]);
|
|
return {
|
|
isMounted,
|
|
styles,
|
|
};
|
|
}
|
|
function getNodeChildren(nodes, id, onlyOpenChildren) {
|
|
if (onlyOpenChildren === void 0) {
|
|
onlyOpenChildren = true;
|
|
}
|
|
const directChildren = nodes.filter((node) => {
|
|
var _node$context;
|
|
return node.parentId === id && (!onlyOpenChildren || ((_node$context = node.context) == null ? void 0 : _node$context.open));
|
|
});
|
|
return directChildren.flatMap((child) => [child, ...getNodeChildren(nodes, child.id, onlyOpenChildren)]);
|
|
}
|
|
function isPointInPolygon$2(point, polygon) {
|
|
const [x, y] = point;
|
|
let isInside2 = false;
|
|
const length = polygon.length;
|
|
for (let i = 0, j = length - 1; i < length; j = i++) {
|
|
const [xi, yi] = polygon[i] || [0, 0];
|
|
const [xj, yj] = polygon[j] || [0, 0];
|
|
const intersect = yi >= y !== yj >= y && x <= ((xj - xi) * (y - yi)) / (yj - yi) + xi;
|
|
if (intersect) {
|
|
isInside2 = !isInside2;
|
|
}
|
|
}
|
|
return isInside2;
|
|
}
|
|
function isInside(point, rect) {
|
|
return point[0] >= rect.x && point[0] <= rect.x + rect.width && point[1] >= rect.y && point[1] <= rect.y + rect.height;
|
|
}
|
|
function safePolygon(options) {
|
|
if (options === void 0) {
|
|
options = {};
|
|
}
|
|
const { buffer = 0.5, blockPointerEvents = false, requireIntent = true } = options;
|
|
const timeoutRef = {
|
|
current: -1,
|
|
};
|
|
let hasLanded = false;
|
|
let lastX = null;
|
|
let lastY = null;
|
|
let lastCursorTime = typeof performance !== "undefined" ? performance.now() : 0;
|
|
function getCursorSpeed(x, y) {
|
|
const currentTime = performance.now();
|
|
const elapsedTime = currentTime - lastCursorTime;
|
|
if (lastX === null || lastY === null || elapsedTime === 0) {
|
|
lastX = x;
|
|
lastY = y;
|
|
lastCursorTime = currentTime;
|
|
return null;
|
|
}
|
|
const deltaX = x - lastX;
|
|
const deltaY = y - lastY;
|
|
const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
const speed = distance / elapsedTime;
|
|
lastX = x;
|
|
lastY = y;
|
|
lastCursorTime = currentTime;
|
|
return speed;
|
|
}
|
|
const fn = (_ref) => {
|
|
let { x, y, placement, elements, onClose, nodeId, tree } = _ref;
|
|
return function onMouseMove(event) {
|
|
function close() {
|
|
clearTimeoutIfSet(timeoutRef);
|
|
onClose();
|
|
}
|
|
clearTimeoutIfSet(timeoutRef);
|
|
if (!elements.domReference || !elements.floating || placement == null || x == null || y == null) {
|
|
return;
|
|
}
|
|
const { clientX, clientY } = event;
|
|
const clientPoint = [clientX, clientY];
|
|
const target = getTarget(event);
|
|
const isLeave = event.type === "mouseleave";
|
|
const isOverFloatingEl = contains(elements.floating, target);
|
|
const isOverReferenceEl = contains(elements.domReference, target);
|
|
const refRect = elements.domReference.getBoundingClientRect();
|
|
const rect = elements.floating.getBoundingClientRect();
|
|
const side = placement.split("-")[0];
|
|
const cursorLeaveFromRight = x > rect.right - rect.width / 2;
|
|
const cursorLeaveFromBottom = y > rect.bottom - rect.height / 2;
|
|
const isOverReferenceRect = isInside(clientPoint, refRect);
|
|
const isFloatingWider = rect.width > refRect.width;
|
|
const isFloatingTaller = rect.height > refRect.height;
|
|
const left = (isFloatingWider ? refRect : rect).left;
|
|
const right = (isFloatingWider ? refRect : rect).right;
|
|
const top = (isFloatingTaller ? refRect : rect).top;
|
|
const bottom = (isFloatingTaller ? refRect : rect).bottom;
|
|
if (isOverFloatingEl) {
|
|
hasLanded = true;
|
|
if (!isLeave) {
|
|
return;
|
|
}
|
|
}
|
|
if (isOverReferenceEl) {
|
|
hasLanded = false;
|
|
}
|
|
if (isOverReferenceEl && !isLeave) {
|
|
hasLanded = true;
|
|
return;
|
|
}
|
|
if (isLeave && isElement(event.relatedTarget) && contains(elements.floating, event.relatedTarget)) {
|
|
return;
|
|
}
|
|
if (tree && getNodeChildren(tree.nodesRef.current, nodeId).length) {
|
|
return;
|
|
}
|
|
if (
|
|
(side === "top" && y >= refRect.bottom - 1) ||
|
|
(side === "bottom" && y <= refRect.top + 1) ||
|
|
(side === "left" && x >= refRect.right - 1) ||
|
|
(side === "right" && x <= refRect.left + 1)
|
|
) {
|
|
return close();
|
|
}
|
|
let rectPoly = [];
|
|
switch (side) {
|
|
case "top":
|
|
rectPoly = [
|
|
[left, refRect.top + 1],
|
|
[left, rect.bottom - 1],
|
|
[right, rect.bottom - 1],
|
|
[right, refRect.top + 1],
|
|
];
|
|
break;
|
|
case "bottom":
|
|
rectPoly = [
|
|
[left, rect.top + 1],
|
|
[left, refRect.bottom - 1],
|
|
[right, refRect.bottom - 1],
|
|
[right, rect.top + 1],
|
|
];
|
|
break;
|
|
case "left":
|
|
rectPoly = [
|
|
[rect.right - 1, bottom],
|
|
[rect.right - 1, top],
|
|
[refRect.left + 1, top],
|
|
[refRect.left + 1, bottom],
|
|
];
|
|
break;
|
|
case "right":
|
|
rectPoly = [
|
|
[refRect.right - 1, bottom],
|
|
[refRect.right - 1, top],
|
|
[rect.left + 1, top],
|
|
[rect.left + 1, bottom],
|
|
];
|
|
break;
|
|
}
|
|
function getPolygon(_ref2) {
|
|
let [x2, y2] = _ref2;
|
|
switch (side) {
|
|
case "top": {
|
|
const cursorPointOne = [
|
|
isFloatingWider ? x2 + buffer / 2
|
|
: cursorLeaveFromRight ? x2 + buffer * 4
|
|
: x2 - buffer * 4,
|
|
y2 + buffer + 1,
|
|
];
|
|
const cursorPointTwo = [
|
|
isFloatingWider ? x2 - buffer / 2
|
|
: cursorLeaveFromRight ? x2 + buffer * 4
|
|
: x2 - buffer * 4,
|
|
y2 + buffer + 1,
|
|
];
|
|
const commonPoints = [
|
|
[
|
|
rect.left,
|
|
cursorLeaveFromRight ? rect.bottom - buffer
|
|
: isFloatingWider ? rect.bottom - buffer
|
|
: rect.top,
|
|
],
|
|
[
|
|
rect.right,
|
|
cursorLeaveFromRight ?
|
|
isFloatingWider ? rect.bottom - buffer
|
|
: rect.top
|
|
: rect.bottom - buffer,
|
|
],
|
|
];
|
|
return [cursorPointOne, cursorPointTwo, ...commonPoints];
|
|
}
|
|
case "bottom": {
|
|
const cursorPointOne = [
|
|
isFloatingWider ? x2 + buffer / 2
|
|
: cursorLeaveFromRight ? x2 + buffer * 4
|
|
: x2 - buffer * 4,
|
|
y2 - buffer,
|
|
];
|
|
const cursorPointTwo = [
|
|
isFloatingWider ? x2 - buffer / 2
|
|
: cursorLeaveFromRight ? x2 + buffer * 4
|
|
: x2 - buffer * 4,
|
|
y2 - buffer,
|
|
];
|
|
const commonPoints = [
|
|
[
|
|
rect.left,
|
|
cursorLeaveFromRight ? rect.top + buffer
|
|
: isFloatingWider ? rect.top + buffer
|
|
: rect.bottom,
|
|
],
|
|
[
|
|
rect.right,
|
|
cursorLeaveFromRight ?
|
|
isFloatingWider ? rect.top + buffer
|
|
: rect.bottom
|
|
: rect.top + buffer,
|
|
],
|
|
];
|
|
return [cursorPointOne, cursorPointTwo, ...commonPoints];
|
|
}
|
|
case "left": {
|
|
const cursorPointOne = [
|
|
x2 + buffer + 1,
|
|
isFloatingTaller ? y2 + buffer / 2
|
|
: cursorLeaveFromBottom ? y2 + buffer * 4
|
|
: y2 - buffer * 4,
|
|
];
|
|
const cursorPointTwo = [
|
|
x2 + buffer + 1,
|
|
isFloatingTaller ? y2 - buffer / 2
|
|
: cursorLeaveFromBottom ? y2 + buffer * 4
|
|
: y2 - buffer * 4,
|
|
];
|
|
const commonPoints = [
|
|
[
|
|
cursorLeaveFromBottom ? rect.right - buffer
|
|
: isFloatingTaller ? rect.right - buffer
|
|
: rect.left,
|
|
rect.top,
|
|
],
|
|
[
|
|
cursorLeaveFromBottom ?
|
|
isFloatingTaller ? rect.right - buffer
|
|
: rect.left
|
|
: rect.right - buffer,
|
|
rect.bottom,
|
|
],
|
|
];
|
|
return [...commonPoints, cursorPointOne, cursorPointTwo];
|
|
}
|
|
case "right": {
|
|
const cursorPointOne = [
|
|
x2 - buffer,
|
|
isFloatingTaller ? y2 + buffer / 2
|
|
: cursorLeaveFromBottom ? y2 + buffer * 4
|
|
: y2 - buffer * 4,
|
|
];
|
|
const cursorPointTwo = [
|
|
x2 - buffer,
|
|
isFloatingTaller ? y2 - buffer / 2
|
|
: cursorLeaveFromBottom ? y2 + buffer * 4
|
|
: y2 - buffer * 4,
|
|
];
|
|
const commonPoints = [
|
|
[
|
|
cursorLeaveFromBottom ? rect.left + buffer
|
|
: isFloatingTaller ? rect.left + buffer
|
|
: rect.right,
|
|
rect.top,
|
|
],
|
|
[
|
|
cursorLeaveFromBottom ?
|
|
isFloatingTaller ? rect.left + buffer
|
|
: rect.right
|
|
: rect.left + buffer,
|
|
rect.bottom,
|
|
],
|
|
];
|
|
return [cursorPointOne, cursorPointTwo, ...commonPoints];
|
|
}
|
|
}
|
|
}
|
|
if (isPointInPolygon$2([clientX, clientY], rectPoly)) {
|
|
return;
|
|
}
|
|
if (hasLanded && !isOverReferenceRect) {
|
|
return close();
|
|
}
|
|
if (!isLeave && requireIntent) {
|
|
const cursorSpeed = getCursorSpeed(event.clientX, event.clientY);
|
|
const cursorSpeedThreshold = 0.1;
|
|
if (cursorSpeed !== null && cursorSpeed < cursorSpeedThreshold) {
|
|
return close();
|
|
}
|
|
}
|
|
if (!isPointInPolygon$2([clientX, clientY], getPolygon([x, y]))) {
|
|
close();
|
|
} else if (!hasLanded && requireIntent) {
|
|
timeoutRef.current = window.setTimeout(close, 40);
|
|
}
|
|
};
|
|
};
|
|
fn.__options = {
|
|
blockPointerEvents,
|
|
};
|
|
return fn;
|
|
}
|
|
|
|
function useStore(store, selector = (d) => d) {
|
|
const slice = withSelectorExports.useSyncExternalStoreWithSelector(
|
|
store.subscribe,
|
|
() => store.state,
|
|
() => store.state,
|
|
selector,
|
|
shallow,
|
|
);
|
|
return slice;
|
|
}
|
|
function shallow(objA, objB) {
|
|
if (Object.is(objA, objB)) {
|
|
return true;
|
|
}
|
|
if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
|
|
return false;
|
|
}
|
|
if (objA instanceof Map && objB instanceof Map) {
|
|
if (objA.size !== objB.size) return false;
|
|
for (const [k, v] of objA) {
|
|
if (!objB.has(k) || !Object.is(v, objB.get(k))) return false;
|
|
}
|
|
return true;
|
|
}
|
|
if (objA instanceof Set && objB instanceof Set) {
|
|
if (objA.size !== objB.size) return false;
|
|
for (const v of objA) {
|
|
if (!objB.has(v)) return false;
|
|
}
|
|
return true;
|
|
}
|
|
if (objA instanceof Date && objB instanceof Date) {
|
|
if (objA.getTime() !== objB.getTime()) return false;
|
|
return true;
|
|
}
|
|
const keysA = getOwnKeys(objA);
|
|
if (keysA.length !== getOwnKeys(objB).length) {
|
|
return false;
|
|
}
|
|
for (let i = 0; i < keysA.length; i++) {
|
|
if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !Object.is(objA[keysA[i]], objB[keysA[i]])) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
function getOwnKeys(obj) {
|
|
return Object.keys(obj).concat(Object.getOwnPropertySymbols(obj));
|
|
}
|
|
|
|
var client = {};
|
|
|
|
var hasRequiredClient;
|
|
|
|
function requireClient() {
|
|
if (hasRequiredClient) return client;
|
|
hasRequiredClient = 1;
|
|
var m = requireReactDom();
|
|
{
|
|
client.createRoot = m.createRoot;
|
|
client.hydrateRoot = m.hydrateRoot;
|
|
}
|
|
return client;
|
|
}
|
|
|
|
requireClient();
|
|
|
|
var ln = Object.defineProperty;
|
|
var cn = (e2, t, n) => (t in e2 ? ln(e2, t, { enumerable: true, configurable: true, writable: true, value: n }) : (e2[t] = n));
|
|
var ee = (e2, t, n) => cn(e2, typeof t != "symbol" ? t + "" : t, n);
|
|
const Z = await importShared("react");
|
|
const {
|
|
createContext: Ae$1,
|
|
useContext: we$1,
|
|
useRef: F$1,
|
|
useEffect: M$1,
|
|
useMemo: V,
|
|
useState: T,
|
|
useCallback: H,
|
|
useLayoutEffect: an,
|
|
useDebugValue: sn,
|
|
Suspense: dn,
|
|
lazy: Ct$1,
|
|
useSyncExternalStore: De$1,
|
|
forwardRef: un,
|
|
useImperativeHandle: mn,
|
|
useReducer: fn,
|
|
} = Z;
|
|
const { createPortal: Ue$1, flushSync: Mt$1 } = await importShared("react-dom");
|
|
const _t$1 = Ae$1(void 0);
|
|
function q(e2) {
|
|
return we$1(_t$1);
|
|
}
|
|
function v(e2) {
|
|
const t = q();
|
|
if (!(t != null && t.editor)) throw new Error("useBlockNoteEditor was called outside of a BlockNoteContext provider or BlockNoteView component");
|
|
return t.editor;
|
|
}
|
|
function _(e2, t) {
|
|
const o = ((t == null ? void 0 : t.editor) ?? v()).getExtension(e2);
|
|
if (!o) throw new Error("Extension not found", { cause: { plugin: e2 } });
|
|
return o;
|
|
}
|
|
function B(e2, t) {
|
|
const { store: n } = _(e2, t);
|
|
if (!n) throw new Error("Store not found on plugin", { cause: { plugin: e2 } });
|
|
return useStore(n, t == null ? void 0 : t.selector);
|
|
}
|
|
function co(e2) {
|
|
let t = new DOMRect();
|
|
const n = "getBoundingClientRect" in e2 ? () => e2.getBoundingClientRect() : () => e2.element.getBoundingClientRect();
|
|
return () => (e2.element && (e2.cacheMountedBoundingClientRect ?? true) ? (e2.element.isConnected && (t = n()), t) : n());
|
|
}
|
|
const $$1 = (e2) => {
|
|
var h, b, p, C;
|
|
const {
|
|
refs: t,
|
|
floatingStyles: n,
|
|
context: o,
|
|
} = useFloating({
|
|
whileElementsMounted: autoUpdate,
|
|
...e2.useFloatingOptions,
|
|
}),
|
|
{ isMounted: r, styles: i } = useTransitionStyles(o, e2.useTransitionStylesProps),
|
|
{ status: c } = useTransitionStatus(o, e2.useTransitionStatusProps),
|
|
s = useDismiss(o, e2.useDismissProps),
|
|
a = useHover(o, { enabled: false, ...e2.useHoverProps }),
|
|
{ getFloatingProps: d } = useInteractions([s, a]),
|
|
u = F$1(""),
|
|
m = F$1(null),
|
|
f = useMergeRefs([m, t.setFloating]);
|
|
if (
|
|
(M$1(() => {
|
|
if (e2.reference) {
|
|
const x = "element" in e2.reference ? e2.reference.element : void 0;
|
|
(x !== void 0 && t.setReference(x),
|
|
t.setPositionReference({
|
|
getBoundingClientRect: co(e2.reference),
|
|
contextElement: x,
|
|
}));
|
|
}
|
|
}, [e2.reference, t]),
|
|
M$1(
|
|
() => {
|
|
var x;
|
|
(c === "initial" || c === "open") && (x = m.current) != null && x.innerHTML && (u.current = m.current.innerHTML);
|
|
},
|
|
// `props.children` is added to the deps, since it's ultimately the HTML of
|
|
// the children that we're storing.
|
|
[c, e2.reference, e2.children],
|
|
),
|
|
!r)
|
|
)
|
|
return false;
|
|
const g = {
|
|
...e2.elementProps,
|
|
style: {
|
|
display: "flex",
|
|
...((h = e2.elementProps) == null ? void 0 : h.style),
|
|
zIndex: `calc(var(--bn-ui-base-z-index) + ${((p = (b = e2.elementProps) == null ? void 0 : b.style) == null ? void 0 : p.zIndex) || 0})`,
|
|
...n,
|
|
...i,
|
|
},
|
|
...d(),
|
|
};
|
|
return (
|
|
c === "close" ?
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
ref: f,
|
|
...g,
|
|
dangerouslySetInnerHTML: { __html: u.current },
|
|
})
|
|
: (C = e2.focusManagerProps) != null && C.disabled ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: f, ...g, children: e2.children })
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsx(FloatingFocusManager, {
|
|
...e2.focusManagerProps,
|
|
context: o,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: f, ...g, children: e2.children }),
|
|
})
|
|
);
|
|
},
|
|
Bt$1 = (e2) => {
|
|
const { blockId: t, children: n, ...o } = e2,
|
|
r = v(),
|
|
i = V(
|
|
() =>
|
|
r.transact((c) => {
|
|
if (!t) return;
|
|
const s = Bt$2(t, c.doc);
|
|
if (!s) return;
|
|
const { node: a } = r.prosemirrorView.domAtPos(s.posBeforeNode + 1);
|
|
if (a instanceof Element)
|
|
return {
|
|
element: a,
|
|
};
|
|
}),
|
|
[r, t],
|
|
);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx($$1, { reference: i, ...o, children: t !== void 0 && n });
|
|
},
|
|
ao = Ae$1(void 0);
|
|
function w() {
|
|
return we$1(ao);
|
|
}
|
|
function S() {
|
|
return q().editor.dictionary;
|
|
}
|
|
const so = (e2) => {
|
|
const t = w(),
|
|
n = S(),
|
|
o = v(),
|
|
r = o.getBlock(e2.blockId),
|
|
[i, c] = T(""),
|
|
s = H((u) => {
|
|
c(u.currentTarget.value);
|
|
}, []),
|
|
a = H(
|
|
(u) => {
|
|
u.key === "Enter" &&
|
|
!u.nativeEvent.isComposing &&
|
|
(u.preventDefault(),
|
|
o.updateBlock(r.id, {
|
|
props: {
|
|
name: fo$1(i),
|
|
url: i,
|
|
},
|
|
}));
|
|
},
|
|
[o, r.id, i],
|
|
),
|
|
d = H(() => {
|
|
o.updateBlock(r.id, {
|
|
props: {
|
|
name: fo$1(i),
|
|
url: i,
|
|
},
|
|
});
|
|
}, [o, r.id, i]);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(t.FilePanel.TabPanel, {
|
|
className: "bn-tab-panel",
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.FilePanel.TextInput, {
|
|
"className": "bn-text-input",
|
|
"placeholder": n.file_panel.embed.url_placeholder,
|
|
"value": i,
|
|
"onChange": s,
|
|
"onKeyDown": a,
|
|
"data-test": "embed-input",
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.FilePanel.Button, {
|
|
"className": "bn-button",
|
|
"onClick": d,
|
|
"data-test": "embed-input-button",
|
|
"children": n.file_panel.embed.embed_button[r.type] || n.file_panel.embed.embed_button.file,
|
|
}),
|
|
],
|
|
});
|
|
},
|
|
uo = (e2) => {
|
|
var m, f;
|
|
const t = w(),
|
|
n = S(),
|
|
{ setLoading: o } = e2,
|
|
r = v(),
|
|
i = r.getBlock(e2.blockId),
|
|
[c, s] = T(false);
|
|
M$1(() => {
|
|
c &&
|
|
setTimeout(() => {
|
|
s(false);
|
|
}, 3e3);
|
|
}, [c]);
|
|
const a = H(
|
|
(g) => {
|
|
if (g === null) return;
|
|
async function h(b) {
|
|
if ((o(true), r.uploadFile !== void 0))
|
|
try {
|
|
let p = await r.uploadFile(b, e2.blockId);
|
|
(typeof p == "string" &&
|
|
(p = {
|
|
props: {
|
|
name: b.name,
|
|
url: p,
|
|
},
|
|
}),
|
|
r.updateBlock(e2.blockId, p));
|
|
} catch {
|
|
s(true);
|
|
} finally {
|
|
o(false);
|
|
}
|
|
}
|
|
h(g);
|
|
},
|
|
[e2.blockId, r, o],
|
|
),
|
|
d = r.schema.blockSpecs[i.type],
|
|
u = (f = (m = d.implementation.meta) == null ? void 0 : m.fileBlockAccept) != null && f.length ? d.implementation.meta.fileBlockAccept.join(",") : "*/*";
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(t.FilePanel.TabPanel, {
|
|
className: "bn-tab-panel",
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.FilePanel.FileInput, {
|
|
"className": "bn-file-input",
|
|
"data-test": "upload-input",
|
|
"accept": u,
|
|
"placeholder": n.file_panel.upload.file_placeholder[i.type] || n.file_panel.upload.file_placeholder.file,
|
|
"value": null,
|
|
"onChange": a,
|
|
}),
|
|
c && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bn-error-text", children: n.file_panel.upload.upload_error }),
|
|
],
|
|
});
|
|
},
|
|
Lt$1 = (e2) => {
|
|
const t = w(),
|
|
n = S(),
|
|
o = v(),
|
|
[r, i] = T(false),
|
|
c = e2.tabs ?? [
|
|
...(o.uploadFile !== void 0 ?
|
|
[
|
|
{
|
|
name: n.file_panel.upload.title,
|
|
tabPanel: /* @__PURE__ */ jsxRuntimeExports.jsx(uo, { blockId: e2.blockId, setLoading: i }),
|
|
},
|
|
]
|
|
: []),
|
|
{
|
|
name: n.file_panel.embed.title,
|
|
tabPanel: /* @__PURE__ */ jsxRuntimeExports.jsx(so, { blockId: e2.blockId }),
|
|
},
|
|
],
|
|
[s, a] = T(e2.defaultOpenTab || c[0].name);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(t.FilePanel.Root, {
|
|
className: "bn-panel",
|
|
defaultOpenTab: s,
|
|
openTab: s,
|
|
setOpenTab: a,
|
|
tabs: c,
|
|
loading: r,
|
|
});
|
|
},
|
|
mo = (e2) => {
|
|
const t = v(),
|
|
n = _(H$1),
|
|
o = B(H$1),
|
|
r = V(() => {
|
|
var c, s, a;
|
|
return {
|
|
...e2.floatingUIOptions,
|
|
useFloatingOptions: {
|
|
open: !!o,
|
|
// Needed as hooks like `useDismiss` call `onOpenChange` to change the
|
|
// open state.
|
|
onOpenChange: (d, u, m) => {
|
|
(d || n.closeMenu(), m === "escape-key" && t.focus());
|
|
},
|
|
middleware: [offset(10), flip()],
|
|
...((c = e2.floatingUIOptions) == null ? void 0 : c.useFloatingOptions),
|
|
},
|
|
focusManagerProps: {
|
|
disabled: true,
|
|
...((s = e2.floatingUIOptions) == null ? void 0 : s.focusManagerProps),
|
|
},
|
|
elementProps: {
|
|
style: {
|
|
zIndex: 90,
|
|
},
|
|
...((a = e2.floatingUIOptions) == null ? void 0 : a.elementProps),
|
|
},
|
|
};
|
|
}, [o, t, n, e2.floatingUIOptions]),
|
|
i = e2.filePanel || Lt$1;
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Bt$1, { blockId: o, ...r, children: o && /* @__PURE__ */ jsxRuntimeExports.jsx(i, { blockId: o }) });
|
|
};
|
|
function fo(e2) {
|
|
return e2 && e2.__esModule && Object.prototype.hasOwnProperty.call(e2, "default") ? e2.default : e2;
|
|
}
|
|
var go = function e(t, n) {
|
|
if (t === n) return true;
|
|
if (t && n && typeof t == "object" && typeof n == "object") {
|
|
if (t.constructor !== n.constructor) return false;
|
|
var o, r, i;
|
|
if (Array.isArray(t)) {
|
|
if (((o = t.length), o != n.length)) return false;
|
|
for (r = o; r-- !== 0; ) if (!e(t[r], n[r])) return false;
|
|
return true;
|
|
}
|
|
if (t instanceof Map && n instanceof Map) {
|
|
if (t.size !== n.size) return false;
|
|
for (r of t.entries()) if (!n.has(r[0])) return false;
|
|
for (r of t.entries()) if (!e(r[1], n.get(r[0]))) return false;
|
|
return true;
|
|
}
|
|
if (t instanceof Set && n instanceof Set) {
|
|
if (t.size !== n.size) return false;
|
|
for (r of t.entries()) if (!n.has(r[0])) return false;
|
|
return true;
|
|
}
|
|
if (ArrayBuffer.isView(t) && ArrayBuffer.isView(n)) {
|
|
if (((o = t.length), o != n.length)) return false;
|
|
for (r = o; r-- !== 0; ) if (t[r] !== n[r]) return false;
|
|
return true;
|
|
}
|
|
if (t.constructor === RegExp) return t.source === n.source && t.flags === n.flags;
|
|
if (t.valueOf !== Object.prototype.valueOf) return t.valueOf() === n.valueOf();
|
|
if (t.toString !== Object.prototype.toString) return t.toString() === n.toString();
|
|
if (((i = Object.keys(t)), (o = i.length), o !== Object.keys(n).length)) return false;
|
|
for (r = o; r-- !== 0; ) if (!Object.prototype.hasOwnProperty.call(n, i[r])) return false;
|
|
for (r = o; r-- !== 0; ) {
|
|
var c = i[r];
|
|
if (!(c === "_owner" && t.$$typeof) && !e(t[c], n[c])) return false;
|
|
}
|
|
return true;
|
|
}
|
|
return t !== t && n !== n;
|
|
};
|
|
const ho = /* @__PURE__ */ fo(go);
|
|
var Ie$1 = { exports: {} },
|
|
Ve$1 = {},
|
|
se = { exports: {} },
|
|
Te$1 = {};
|
|
/**
|
|
* @license React
|
|
* use-sync-external-store-shim.production.js
|
|
*
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
var tt$1;
|
|
function bo() {
|
|
if (tt$1) return Te$1;
|
|
tt$1 = 1;
|
|
var e2 = Z;
|
|
function t(m, f) {
|
|
return (m === f && (m !== 0 || 1 / m === 1 / f)) || (m !== m && f !== f);
|
|
}
|
|
var n = typeof Object.is == "function" ? Object.is : t,
|
|
o = e2.useState,
|
|
r = e2.useEffect,
|
|
i = e2.useLayoutEffect,
|
|
c = e2.useDebugValue;
|
|
function s(m, f) {
|
|
var g = f(),
|
|
h = o({ inst: { value: g, getSnapshot: f } }),
|
|
b = h[0].inst,
|
|
p = h[1];
|
|
return (
|
|
i(
|
|
function () {
|
|
((b.value = g), (b.getSnapshot = f), a(b) && p({ inst: b }));
|
|
},
|
|
[m, g, f],
|
|
),
|
|
r(
|
|
function () {
|
|
return (
|
|
a(b) && p({ inst: b }),
|
|
m(function () {
|
|
a(b) && p({ inst: b });
|
|
})
|
|
);
|
|
},
|
|
[m],
|
|
),
|
|
c(g),
|
|
g
|
|
);
|
|
}
|
|
function a(m) {
|
|
var f = m.getSnapshot;
|
|
m = m.value;
|
|
try {
|
|
var g = f();
|
|
return !n(m, g);
|
|
} catch {
|
|
return true;
|
|
}
|
|
}
|
|
function d(m, f) {
|
|
return f();
|
|
}
|
|
var u = typeof window > "u" || typeof window.document > "u" || typeof window.document.createElement > "u" ? d : s;
|
|
return ((Te$1.useSyncExternalStore = e2.useSyncExternalStore !== void 0 ? e2.useSyncExternalStore : u), Te$1);
|
|
}
|
|
var ot$1;
|
|
function Et$1() {
|
|
return (ot$1 || ((ot$1 = 1), (se.exports = bo())), se.exports);
|
|
}
|
|
/**
|
|
* @license React
|
|
* use-sync-external-store-shim/with-selector.production.js
|
|
*
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
var rt$1;
|
|
function Co() {
|
|
if (rt$1) return Ve$1;
|
|
rt$1 = 1;
|
|
var e2 = Z,
|
|
t = Et$1();
|
|
function n(d, u) {
|
|
return (d === u && (d !== 0 || 1 / d === 1 / u)) || (d !== d && u !== u);
|
|
}
|
|
var o = typeof Object.is == "function" ? Object.is : n,
|
|
r = t.useSyncExternalStore,
|
|
i = e2.useRef,
|
|
c = e2.useEffect,
|
|
s = e2.useMemo,
|
|
a = e2.useDebugValue;
|
|
return (
|
|
(Ve$1.useSyncExternalStoreWithSelector = function (d, u, m, f, g) {
|
|
var h = i(null);
|
|
if (h.current === null) {
|
|
var b = { hasValue: false, value: null };
|
|
h.current = b;
|
|
} else b = h.current;
|
|
h = s(
|
|
function () {
|
|
function C(L) {
|
|
if (!x) {
|
|
if (((x = true), (O = L), (L = f(L)), g !== void 0 && b.hasValue)) {
|
|
var P = b.value;
|
|
if (g(P, L)) return (I = P);
|
|
}
|
|
return (I = L);
|
|
}
|
|
if (((P = I), o(O, L))) return P;
|
|
var K = f(L);
|
|
return g !== void 0 && g(P, K) ? ((O = L), P) : ((O = L), (I = K));
|
|
}
|
|
var x = false,
|
|
O,
|
|
I,
|
|
j = m === void 0 ? null : m;
|
|
return [
|
|
function () {
|
|
return C(u());
|
|
},
|
|
j === null ? void 0 : (
|
|
function () {
|
|
return C(j());
|
|
}
|
|
),
|
|
];
|
|
},
|
|
[u, m, f, g],
|
|
);
|
|
var p = r(d, h[0], h[1]);
|
|
return (
|
|
c(
|
|
function () {
|
|
((b.hasValue = true), (b.value = p));
|
|
},
|
|
[p],
|
|
),
|
|
a(p),
|
|
p
|
|
);
|
|
}),
|
|
Ve$1
|
|
);
|
|
}
|
|
Ie$1.exports = Co();
|
|
var wo = Ie$1.exports;
|
|
const ko = typeof window < "u" ? an : M$1;
|
|
class Ho {
|
|
constructor(t) {
|
|
ee(this, "transactionNumber", 0);
|
|
ee(this, "lastTransactionNumber", 0);
|
|
ee(this, "lastSnapshot");
|
|
ee(this, "editor");
|
|
ee(this, "subscribers", /* @__PURE__ */ new Set());
|
|
((this.editor = t),
|
|
(this.lastSnapshot = { editor: t, transactionNumber: 0 }),
|
|
(this.getSnapshot = this.getSnapshot.bind(this)),
|
|
(this.getServerSnapshot = this.getServerSnapshot.bind(this)),
|
|
(this.watch = this.watch.bind(this)),
|
|
(this.subscribe = this.subscribe.bind(this)));
|
|
}
|
|
/**
|
|
* Get the current editor instance.
|
|
*/
|
|
getSnapshot() {
|
|
return this.transactionNumber === this.lastTransactionNumber ?
|
|
this.lastSnapshot
|
|
: ((this.lastTransactionNumber = this.transactionNumber),
|
|
(this.lastSnapshot = {
|
|
editor: this.editor,
|
|
transactionNumber: this.transactionNumber,
|
|
}),
|
|
this.lastSnapshot);
|
|
}
|
|
/**
|
|
* Always disable the editor on the server-side.
|
|
*/
|
|
getServerSnapshot() {
|
|
return { editor: null, transactionNumber: 0 };
|
|
}
|
|
/**
|
|
* Subscribe to the editor instance's changes.
|
|
*/
|
|
subscribe(t) {
|
|
return (
|
|
this.subscribers.add(t),
|
|
() => {
|
|
this.subscribers.delete(t);
|
|
}
|
|
);
|
|
}
|
|
/**
|
|
* Watch the editor instance for changes.
|
|
*/
|
|
watch(t, n) {
|
|
if (((this.editor = t), this.editor)) {
|
|
const o = () => {
|
|
((this.transactionNumber += 1), this.subscribers.forEach((c) => c()));
|
|
},
|
|
r = this.editor._tiptapEditor,
|
|
i = {
|
|
all: "transaction",
|
|
selection: "selectionUpdate",
|
|
change: "update",
|
|
};
|
|
return (
|
|
r.on(i[n], o),
|
|
() => {
|
|
r.off(i[n], o);
|
|
}
|
|
);
|
|
}
|
|
}
|
|
}
|
|
function R(e2) {
|
|
const t = q(),
|
|
n = e2.editor || (t == null ? void 0 : t.editor) || null,
|
|
o = e2.on || "all",
|
|
[r] = T(() => new Ho(n)),
|
|
i = wo.useSyncExternalStoreWithSelector(r.subscribe, r.getSnapshot, r.getServerSnapshot, e2.selector, e2.equalityFn ?? ho);
|
|
return (ko(() => r.watch(n, o), [n, r, o]), sn(i), i);
|
|
}
|
|
const Ge$1 = (e2) => {
|
|
const { position: t, children: n, ...o } = e2,
|
|
{ from: r, to: i } = t || {},
|
|
c = v(),
|
|
s = V(() => {
|
|
var a;
|
|
if (!(r === void 0 || i === void 0))
|
|
return {
|
|
// Use first child as the editor DOM element may itself be scrollable.
|
|
// For FloatingUI to auto-update the position during scrolling, the
|
|
// `contextElement` must be a descendant of the scroll container.
|
|
element: ((a = c.domElement) == null ? void 0 : a.firstElementChild) || void 0,
|
|
getBoundingClientRect: () => posToDOMRect(c.prosemirrorView, r, i ?? r),
|
|
};
|
|
}, [c, r, i]);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx($$1, { reference: s, ...o, children: t !== void 0 && n });
|
|
};
|
|
var Rt$1 = {
|
|
color: void 0,
|
|
size: void 0,
|
|
className: void 0,
|
|
style: void 0,
|
|
attr: void 0,
|
|
},
|
|
lt$1 = Z.createContext && /* @__PURE__ */ Z.createContext(Rt$1),
|
|
xo = ["attr", "size", "title"];
|
|
function yo(e2, t) {
|
|
if (e2 == null) return {};
|
|
var n = Mo(e2, t),
|
|
o,
|
|
r;
|
|
if (Object.getOwnPropertySymbols) {
|
|
var i = Object.getOwnPropertySymbols(e2);
|
|
for (r = 0; r < i.length; r++) ((o = i[r]), !(t.indexOf(o) >= 0) && Object.prototype.propertyIsEnumerable.call(e2, o) && (n[o] = e2[o]));
|
|
}
|
|
return n;
|
|
}
|
|
function Mo(e2, t) {
|
|
if (e2 == null) return {};
|
|
var n = {};
|
|
for (var o in e2)
|
|
if (Object.prototype.hasOwnProperty.call(e2, o)) {
|
|
if (t.indexOf(o) >= 0) continue;
|
|
n[o] = e2[o];
|
|
}
|
|
return n;
|
|
}
|
|
function he$1() {
|
|
return (
|
|
(he$1 =
|
|
Object.assign ?
|
|
Object.assign.bind()
|
|
: function (e2) {
|
|
for (var t = 1; t < arguments.length; t++) {
|
|
var n = arguments[t];
|
|
for (var o in n) Object.prototype.hasOwnProperty.call(n, o) && (e2[o] = n[o]);
|
|
}
|
|
return e2;
|
|
}),
|
|
he$1.apply(this, arguments)
|
|
);
|
|
}
|
|
function ct$1(e2, t) {
|
|
var n = Object.keys(e2);
|
|
if (Object.getOwnPropertySymbols) {
|
|
var o = Object.getOwnPropertySymbols(e2);
|
|
(t &&
|
|
(o = o.filter(function (r) {
|
|
return Object.getOwnPropertyDescriptor(e2, r).enumerable;
|
|
})),
|
|
n.push.apply(n, o));
|
|
}
|
|
return n;
|
|
}
|
|
function be$1(e2) {
|
|
for (var t = 1; t < arguments.length; t++) {
|
|
var n = arguments[t] != null ? arguments[t] : {};
|
|
t % 2 ?
|
|
ct$1(Object(n), true).forEach(function (o) {
|
|
So(e2, o, n[o]);
|
|
})
|
|
: Object.getOwnPropertyDescriptors ? Object.defineProperties(e2, Object.getOwnPropertyDescriptors(n))
|
|
: ct$1(Object(n)).forEach(function (o) {
|
|
Object.defineProperty(e2, o, Object.getOwnPropertyDescriptor(n, o));
|
|
});
|
|
}
|
|
return e2;
|
|
}
|
|
function So(e2, t, n) {
|
|
return ((t = Vo(t)), t in e2 ? Object.defineProperty(e2, t, { value: n, enumerable: true, configurable: true, writable: true }) : (e2[t] = n), e2);
|
|
}
|
|
function Vo(e2) {
|
|
var t = To(e2, "string");
|
|
return typeof t == "symbol" ? t : t + "";
|
|
}
|
|
function To(e2, t) {
|
|
if (typeof e2 != "object" || !e2) return e2;
|
|
var n = e2[Symbol.toPrimitive];
|
|
if (n !== void 0) {
|
|
var o = n.call(e2, t);
|
|
if (typeof o != "object") return o;
|
|
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
}
|
|
return (t === "string" ? String : Number)(e2);
|
|
}
|
|
function Ot$1(e2) {
|
|
return (
|
|
e2 &&
|
|
e2.map((t, n) =>
|
|
/* @__PURE__ */ Z.createElement(
|
|
t.tag,
|
|
be$1(
|
|
{
|
|
key: n,
|
|
},
|
|
t.attr,
|
|
),
|
|
Ot$1(t.child),
|
|
),
|
|
)
|
|
);
|
|
}
|
|
function k$1(e2) {
|
|
return (t) =>
|
|
/* @__PURE__ */ Z.createElement(
|
|
_o,
|
|
he$1(
|
|
{
|
|
attr: be$1({}, e2.attr),
|
|
},
|
|
t,
|
|
),
|
|
Ot$1(e2.child),
|
|
);
|
|
}
|
|
function _o(e2) {
|
|
var t = (n) => {
|
|
var { attr: o, size: r, title: i } = e2,
|
|
c = yo(e2, xo),
|
|
s = r || n.size || "1em",
|
|
a;
|
|
return (
|
|
n.className && (a = n.className),
|
|
e2.className && (a = (a ? a + " " : "") + e2.className),
|
|
/* @__PURE__ */ Z.createElement(
|
|
"svg",
|
|
he$1(
|
|
{
|
|
stroke: "currentColor",
|
|
fill: "currentColor",
|
|
strokeWidth: "0",
|
|
},
|
|
n.attr,
|
|
o,
|
|
c,
|
|
{
|
|
className: a,
|
|
style: be$1(
|
|
be$1(
|
|
{
|
|
color: e2.color || n.color,
|
|
},
|
|
n.style,
|
|
),
|
|
e2.style,
|
|
),
|
|
height: s,
|
|
width: s,
|
|
xmlns: "http://www.w3.org/2000/svg",
|
|
},
|
|
),
|
|
i && /* @__PURE__ */ Z.createElement("title", null, i),
|
|
e2.children,
|
|
)
|
|
);
|
|
};
|
|
return lt$1 !== void 0 ? /* @__PURE__ */ Z.createElement(lt$1.Consumer, null, (n) => t(n)) : t(Rt$1);
|
|
}
|
|
function Bo(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{ tag: "path", attr: { d: "M8 7V11L2 6L8 1V5H13C17.4183 5 21 8.58172 21 13C21 17.4183 17.4183 21 13 21H4V19H13C16.3137 19 19 16.3137 19 13C19 9.68629 16.3137 7 13 7H8Z" }, child: [] },
|
|
],
|
|
})(e2);
|
|
}
|
|
function It$1(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M7.29117 20.8242L2 22L3.17581 16.7088C2.42544 15.3056 2 13.7025 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C10.2975 22 8.6944 21.5746 7.29117 20.8242ZM7.58075 18.711L8.23428 19.0605C9.38248 19.6745 10.6655 20 12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 13.3345 4.32549 14.6175 4.93949 15.7657L5.28896 16.4192L4.63416 19.3658L7.58075 18.711Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function Lo(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M7.24264 17.9967H3V13.754L14.435 2.319C14.8256 1.92848 15.4587 1.92848 15.8492 2.319L18.6777 5.14743C19.0682 5.53795 19.0682 6.17112 18.6777 6.56164L7.24264 17.9967ZM3 19.9967H21V21.9967H3V19.9967Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function Eo(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M23 12L15.9289 19.0711L14.5147 17.6569L20.1716 12L14.5147 6.34317L15.9289 4.92896L23 12ZM3.82843 12L9.48528 17.6569L8.07107 19.0711L1 12L8.07107 4.92896L9.48528 6.34317L3.82843 12Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function ze$1(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: { d: "M3 8L9.00319 2H19.9978C20.5513 2 21 2.45531 21 2.9918V21.0082C21 21.556 20.5551 22 20.0066 22H3.9934C3.44476 22 3 21.5501 3 20.9932V8ZM10 4V9H5V20H19V4H10Z" },
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function Ro(e2) {
|
|
return k$1({ attr: { viewBox: "0 0 24 24", fill: "currentColor" }, child: [{ tag: "path", attr: { d: "M3 4H21V6H3V4ZM5 19H19V21H5V19ZM3 14H21V16H3V14ZM5 9H19V11H5V9Z" }, child: [] }] })(e2);
|
|
}
|
|
function Oo(e2) {
|
|
return k$1({ attr: { viewBox: "0 0 24 24", fill: "currentColor" }, child: [{ tag: "path", attr: { d: "M3 4H21V6H3V4ZM3 19H21V21H3V19ZM3 14H21V16H3V14ZM3 9H21V11H3V9Z" }, child: [] }] })(e2);
|
|
}
|
|
function Io(e2) {
|
|
return k$1({ attr: { viewBox: "0 0 24 24", fill: "currentColor" }, child: [{ tag: "path", attr: { d: "M3 4H21V6H3V4ZM3 19H17V21H3V19ZM3 14H21V16H3V14ZM3 9H17V11H3V9Z" }, child: [] }] })(e2);
|
|
}
|
|
function Po(e2) {
|
|
return k$1({ attr: { viewBox: "0 0 24 24", fill: "currentColor" }, child: [{ tag: "path", attr: { d: "M3 4H21V6H3V4ZM7 19H21V21H7V19ZM3 14H21V16H3V14ZM7 9H21V11H7V9Z" }, child: [] }] })(e2);
|
|
}
|
|
function No(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M8 11H12.5C13.8807 11 15 9.88071 15 8.5C15 7.11929 13.8807 6 12.5 6H8V11ZM18 15.5C18 17.9853 15.9853 20 13.5 20H6V4H12.5C14.9853 4 17 6.01472 17 8.5C17 9.70431 16.5269 10.7981 15.7564 11.6058C17.0979 12.3847 18 13.837 18 15.5ZM8 13V18H13.5C14.8807 18 16 16.8807 16 15.5C16 14.1193 14.8807 13 13.5 13H8Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function Ao(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M3.41436 5.99995L5.70726 3.70706L4.29304 2.29285L0.585938 5.99995L4.29304 9.70706L5.70726 8.29285L3.41436 5.99995ZM9.58594 5.99995L7.29304 3.70706L8.70726 2.29285L12.4144 5.99995L8.70726 9.70706L7.29304 8.29285L9.58594 5.99995ZM14.0002 2.99995H21.0002C21.5524 2.99995 22.0002 3.44767 22.0002 3.99995V20C22.0002 20.5522 21.5524 21 21.0002 21H3.00015C2.44787 21 2.00015 20.5522 2.00015 20V12H4.00015V19H20.0002V4.99995H14.0002V2.99995Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function at$1(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [{ tag: "path", attr: { d: "M5.55397 22H3.3999L10.9999 3H12.9999L20.5999 22H18.4458L16.0458 16H7.95397L5.55397 22ZM8.75397 14H15.2458L11.9999 5.88517L8.75397 14Z" }, child: [] }],
|
|
})(e2);
|
|
}
|
|
function pe(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [{ tag: "path", attr: { d: "M13 20H11V13H4V20H2V4H4V11H11V4H13V20ZM21.0005 8V20H19.0005L19 10.204L17 10.74V8.67L19.5005 8H21.0005Z" }, child: [] }],
|
|
})(e2);
|
|
}
|
|
function Ce$1(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M4 4V11H11V4H13V20H11V13H4V20H2V4H4ZM18.5 8C20.5711 8 22.25 9.67893 22.25 11.75C22.25 12.6074 21.9623 13.3976 21.4781 14.0292L21.3302 14.2102L18.0343 18H22V20H15L14.9993 18.444L19.8207 12.8981C20.0881 12.5908 20.25 12.1893 20.25 11.75C20.25 10.7835 19.4665 10 18.5 10C17.5818 10 16.8288 10.7071 16.7558 11.6065L16.75 11.75H14.75C14.75 9.67893 16.4289 8 18.5 8Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function ve$1(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M22 8L21.9984 10L19.4934 12.883C21.0823 13.3184 22.25 14.7728 22.25 16.5C22.25 18.5711 20.5711 20.25 18.5 20.25C16.674 20.25 15.1528 18.9449 14.8184 17.2166L16.7821 16.8352C16.9384 17.6413 17.6481 18.25 18.5 18.25C19.4665 18.25 20.25 17.4665 20.25 16.5C20.25 15.5335 19.4665 14.75 18.5 14.75C18.214 14.75 17.944 14.8186 17.7056 14.9403L16.3992 13.3932L19.3484 10H15V8H22ZM4 4V11H11V4H13V20H11V13H4V20H2V4H4Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function Pt$1(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [{ tag: "path", attr: { d: "M13 20H11V13H4V20H2V4H4V11H11V4H13V20ZM22 8V16H23.5V18H22V20H20V18H14.5V16.66L19.5 8H22ZM20 11.133L17.19 16H20V11.133Z" }, child: [] }],
|
|
})(e2);
|
|
}
|
|
function Nt$1(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M22 8V10H17.6769L17.2126 12.6358C17.5435 12.5472 17.8912 12.5 18.25 12.5C20.4591 12.5 22.25 14.2909 22.25 16.5C22.25 18.7091 20.4591 20.5 18.25 20.5C16.4233 20.5 14.8827 19.2756 14.4039 17.6027L16.3271 17.0519C16.5667 17.8881 17.3369 18.5 18.25 18.5C19.3546 18.5 20.25 17.6046 20.25 16.5C20.25 15.3954 19.3546 14.5 18.25 14.5C17.6194 14.5 17.057 14.7918 16.6904 15.2478L14.8803 14.3439L16 8H22ZM4 4V11H11V4H13V20H11V13H4V20H2V4H4Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function At$1(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M21.097 8L18.499 12.5C20.7091 12.5 22.5 14.2909 22.5 16.5C22.5 18.7091 20.7091 20.5 18.5 20.5C16.2909 20.5 14.5 18.7091 14.5 16.5C14.5 15.7636 14.699 15.0737 15.0461 14.4811L18.788 8H21.097ZM4 4V11H11V4H13V20H11V13H4V20H2V4H4ZM18.5 14.5C17.3954 14.5 16.5 15.3954 16.5 16.5C16.5 17.6046 17.3954 18.5 18.5 18.5C19.6046 18.5 20.5 17.6046 20.5 16.5C20.5 15.3954 19.6046 14.5 18.5 14.5Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function Do(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [{ tag: "path", attr: { d: "M3 4H21V6H3V4ZM3 19H21V21H3V19ZM11 14H21V16H11V14ZM11 9H21V11H11V9ZM3 12.5L7 9V16L3 12.5Z" }, child: [] }],
|
|
})(e2);
|
|
}
|
|
function Zo(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [{ tag: "path", attr: { d: "M3 4H21V6H3V4ZM3 19H21V21H3V19ZM11 14H21V16H11V14ZM11 9H21V11H11V9ZM7 12.5L3 16V9L7 12.5Z" }, child: [] }],
|
|
})(e2);
|
|
}
|
|
function st$1(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M8 5H11V19H8V21H16V19H13V5H16V3H8V5ZM2 7C1.44772 7 1 7.44772 1 8V16C1 16.5523 1.44772 17 2 17H8V15H3V9H8V7H2ZM16 9H21V15H16V17H22C22.5523 17 23 16.5523 23 16V8C23 7.44772 22.5523 7 22 7H16V9Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function Fo(e2) {
|
|
return k$1({ attr: { viewBox: "0 0 24 24", fill: "currentColor" }, child: [{ tag: "path", attr: { d: "M15 20H7V18H9.92661L12.0425 6H9V4H17V6H14.0734L11.9575 18H15V20Z" }, child: [] }] })(e2);
|
|
}
|
|
function Uo(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M17 17H22V19H19V22H17V17ZM7 7H2V5H5V2H7V7ZM18.364 15.5355L16.9497 14.1213L18.364 12.7071C20.3166 10.7545 20.3166 7.58866 18.364 5.63604C16.4113 3.68342 13.2455 3.68342 11.2929 5.63604L9.87868 7.05025L8.46447 5.63604L9.87868 4.22183C12.6123 1.48816 17.0445 1.48816 19.7782 4.22183C22.5118 6.9555 22.5118 11.3877 19.7782 14.1213L18.364 15.5355ZM15.5355 18.364L14.1213 19.7782C11.3877 22.5118 6.9555 22.5118 4.22183 19.7782C1.48816 17.0445 1.48816 12.6123 4.22183 9.87868L5.63604 8.46447L7.05025 9.87868L5.63604 11.2929C3.68342 13.2455 3.68342 16.4113 5.63604 18.364C7.58866 20.3166 10.7545 20.3166 12.7071 18.364L14.1213 16.9497L15.5355 18.364ZM14.8284 7.75736L16.2426 9.17157L9.17157 16.2426L7.75736 14.8284L14.8284 7.75736Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function Dt$1(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M18.3638 15.5355L16.9496 14.1213L18.3638 12.7071C20.3164 10.7545 20.3164 7.58866 18.3638 5.63604C16.4112 3.68341 13.2453 3.68341 11.2927 5.63604L9.87849 7.05025L8.46428 5.63604L9.87849 4.22182C12.6122 1.48815 17.0443 1.48815 19.778 4.22182C22.5117 6.95549 22.5117 11.3876 19.778 14.1213L18.3638 15.5355ZM15.5353 18.364L14.1211 19.7782C11.3875 22.5118 6.95531 22.5118 4.22164 19.7782C1.48797 17.0445 1.48797 12.6123 4.22164 9.87868L5.63585 8.46446L7.05007 9.87868L5.63585 11.2929C3.68323 13.2455 3.68323 16.4113 5.63585 18.364C7.58847 20.3166 10.7543 20.3166 12.7069 18.364L14.1211 16.9497L15.5353 18.364ZM14.8282 7.75736L16.2425 9.17157L9.17139 16.2426L7.75717 14.8284L14.8282 7.75736Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function Zt(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M8.00008 6V9H5.00008V6H8.00008ZM3.00008 4V11H10.0001V4H3.00008ZM13.0001 4H21.0001V6H13.0001V4ZM13.0001 11H21.0001V13H13.0001V11ZM13.0001 18H21.0001V20H13.0001V18ZM10.7072 16.2071L9.29297 14.7929L6.00008 18.0858L4.20718 16.2929L2.79297 17.7071L6.00008 20.9142L10.7072 16.2071Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function Ft$1(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: { d: "M8 4H21V6H8V4ZM5 3V6H6V7H3V6H4V4H3V3H5ZM3 14V11.5H5V11H3V10H6V12.5H4V13H6V14H3ZM5 19.5H3V18.5H5V18H3V17H6V21H3V20H5V19.5ZM8 11H21V13H8V11ZM8 18H21V20H8V18Z" },
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function Ut(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M8 4H21V6H8V4ZM4.5 6.5C3.67157 6.5 3 5.82843 3 5C3 4.17157 3.67157 3.5 4.5 3.5C5.32843 3.5 6 4.17157 6 5C6 5.82843 5.32843 6.5 4.5 6.5ZM4.5 13.5C3.67157 13.5 3 12.8284 3 12C3 11.1716 3.67157 10.5 4.5 10.5C5.32843 10.5 6 11.1716 6 12C6 12.8284 5.32843 13.5 4.5 13.5ZM4.5 20.4C3.67157 20.4 3 19.7284 3 18.9C3 18.0716 3.67157 17.4 4.5 17.4C5.32843 17.4 6 18.0716 6 18.9C6 19.7284 5.32843 20.4 4.5 20.4ZM8 11H21V13H8V11ZM8 18H21V20H8V18Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function Go(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M20 3C20.5523 3 21 3.44772 21 4V20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V4C3 3.44772 3.44772 3 4 3H20ZM11 5H5V10.999H7V9L10 12L7 15V13H5V19H11V17H13V19H19V13H17V15L14 12L17 9V10.999H19V5H13V7H11V5ZM13 13V15H11V13H13ZM13 9V11H11V9H13Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function zo(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M21 20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V4C3 3.44772 3.44772 3 4 3H20C20.5523 3 21 3.44772 21 4V20ZM19 11V5H13.001V7H15L12 10L9 7H11V5H5V11H7V13H5V19H11V17H9L12 14L15 17H13.001V19H19V13H17V11H19ZM11 13H9V11H11V13ZM15 13H13V11H15V13Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function Gt$1(e2) {
|
|
return k$1({ attr: { viewBox: "0 0 24 24", fill: "currentColor" }, child: [{ tag: "path", attr: { d: "M21 4H3V6H21V4ZM21 11H8V13H21V11ZM21 18H8V20H21V18ZM5 11H3V20H5V11Z" }, child: [] }] })(e2);
|
|
}
|
|
function jo(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M17.1538 14C17.3846 14.5161 17.5 15.0893 17.5 15.7196C17.5 17.0625 16.9762 18.1116 15.9286 18.867C14.8809 19.6223 13.4335 20 11.5862 20C9.94674 20 8.32335 19.6185 6.71592 18.8555V16.6009C8.23538 17.4783 9.7908 17.917 11.3822 17.917C13.9333 17.917 15.2128 17.1846 15.2208 15.7196C15.2208 15.0939 15.0049 14.5598 14.5731 14.1173C14.5339 14.0772 14.4939 14.0381 14.4531 14H3V12H21V14H17.1538ZM13.076 11H7.62908C7.4566 10.8433 7.29616 10.6692 7.14776 10.4778C6.71592 9.92084 6.5 9.24559 6.5 8.45207C6.5 7.21602 6.96583 6.165 7.89749 5.299C8.82916 4.43299 10.2706 4 12.2219 4C13.6934 4 15.1009 4.32808 16.4444 4.98426V7.13591C15.2448 6.44921 13.9293 6.10587 12.4978 6.10587C10.0187 6.10587 8.77917 6.88793 8.77917 8.45207C8.77917 8.87172 8.99709 9.23796 9.43293 9.55079C9.86878 9.86362 10.4066 10.1135 11.0463 10.3004C11.6665 10.4816 12.3431 10.7148 13.076 11H13.076Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function $o(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M13 10V14H19V10H13ZM11 10H5V14H11V10ZM13 19H19V16H13V19ZM11 19V16H5V19H11ZM13 5V8H19V5H13ZM11 5H5V8H11V5ZM4 3H20C20.5523 3 21 3.44772 21 4V20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V4C3 3.44772 3.44772 3 4 3Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function je$1(e2) {
|
|
return k$1({ attr: { viewBox: "0 0 24 24", fill: "currentColor" }, child: [{ tag: "path", attr: { d: "M13 6V21H11V6H5V4H19V6H13Z" }, child: [] }] })(e2);
|
|
}
|
|
function Wo(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: { d: "M8 3V12C8 14.2091 9.79086 16 12 16C14.2091 16 16 14.2091 16 12V3H18V12C18 15.3137 15.3137 18 12 18C8.68629 18 6 15.3137 6 12V3H8ZM4 20H20V22H4V20Z" },
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function qo(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M2 3.9934C2 3.44476 2.45531 3 2.9918 3H21.0082C21.556 3 22 3.44495 22 3.9934V20.0066C22 20.5552 21.5447 21 21.0082 21H2.9918C2.44405 21 2 20.5551 2 20.0066V3.9934ZM8 5V19H16V5H8ZM4 5V7H6V5H4ZM18 5V7H20V5H18ZM4 9V11H6V9H4ZM18 9V11H20V9H18ZM4 13V15H6V13H4ZM18 13V15H20V13H18ZM4 17V19H6V17H4ZM18 17V19H20V17H18Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function zt$1(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M5 11.1005L7 9.1005L12.5 14.6005L16 11.1005L19 14.1005V5H5V11.1005ZM4 3H20C20.5523 3 21 3.44772 21 4V20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V4C3 3.44772 3.44772 3 4 3ZM15.5 10C14.6716 10 14 9.32843 14 8.5C14 7.67157 14.6716 7 15.5 7C16.3284 7 17 7.67157 17 8.5C17 9.32843 16.3284 10 15.5 10Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function Ko(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M21 15V18H24V20H21V23H19V20H16V18H19V15H21ZM21.0082 3C21.556 3 22 3.44495 22 3.9934L22.0007 13.3417C21.3749 13.1204 20.7015 13 20 13V5H4L4.001 19L13.2929 9.70715C13.6528 9.34604 14.22 9.31823 14.6123 9.62322L14.7065 9.70772L18.2521 13.2586C15.791 14.0069 14 16.2943 14 19C14 19.7015 14.1204 20.3749 14.3417 21.0007L2.9918 21C2.44405 21 2 20.5551 2 20.0066V3.9934C2 3.44476 2.45531 3 2.9918 3H21.0082ZM8 7C9.10457 7 10 7.89543 10 9C10 10.1046 9.10457 11 8 11C6.89543 11 6 10.1046 6 9C6 7.89543 6.89543 7 8 7Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function Xo(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M20 3C20.5523 3 21 3.44772 21 4V5.757L19 7.757V5H5V13.1L9 9.1005L13.328 13.429L12.0012 14.7562L11.995 18.995L16.2414 19.0012L17.571 17.671L18.8995 19H19V16.242L21 14.242V20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V4C3 3.44772 3.44772 3 4 3H20ZM21.7782 7.80761L23.1924 9.22183L15.4142 17L13.9979 16.9979L14 15.5858L21.7782 7.80761ZM15.5 7C16.3284 7 17 7.67157 17 8.5C17 9.32843 16.3284 10 15.5 10C14.6716 10 14 9.32843 14 8.5C14 7.67157 14.6716 7 15.5 7Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function jt$1(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [{ tag: "path", attr: { d: "M22 18V20H2V18H22ZM2 3.5L10 8.5L2 13.5V3.5ZM22 11V13H12V11H22ZM22 4V6H12V4H22Z" }, child: [] }],
|
|
})(e2);
|
|
}
|
|
function $t$1(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M2 16.0001H5.88889L11.1834 20.3319C11.2727 20.405 11.3846 20.4449 11.5 20.4449C11.7761 20.4449 12 20.2211 12 19.9449V4.05519C12 3.93977 11.9601 3.8279 11.887 3.73857C11.7121 3.52485 11.3971 3.49335 11.1834 3.66821L5.88889 8.00007H2C1.44772 8.00007 1 8.44778 1 9.00007V15.0001C1 15.5524 1.44772 16.0001 2 16.0001ZM23 12C23 15.292 21.5539 18.2463 19.2622 20.2622L17.8445 18.8444C19.7758 17.1937 21 14.7398 21 12C21 9.26016 19.7758 6.80629 17.8445 5.15557L19.2622 3.73779C21.5539 5.75368 23 8.70795 23 12ZM18 12C18 10.0883 17.106 8.38548 15.7133 7.28673L14.2842 8.71584C15.3213 9.43855 16 10.64 16 12C16 13.36 15.3213 14.5614 14.2842 15.2841L15.7133 16.7132C17.106 15.6145 18 13.9116 18 12Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function Jo(e2) {
|
|
return k$1({ attr: { viewBox: "0 0 24 24", fill: "currentColor" }, child: [{ tag: "path", attr: { d: "M11 11V5H13V11H19V13H13V19H11V13H5V11H11Z" }, child: [] }] })(e2);
|
|
}
|
|
function Qo(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [{ tag: "path", attr: { d: "M9.9997 15.1709L19.1921 5.97852L20.6063 7.39273L9.9997 17.9993L3.63574 11.6354L5.04996 10.2212L9.9997 15.1709Z" }, child: [] }],
|
|
})(e2);
|
|
}
|
|
function er(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: { d: "M17 6H22V8H20V21C20 21.5523 19.5523 22 19 22H5C4.44772 22 4 21.5523 4 21V8H2V6H7V3C7 2.44772 7.44772 2 8 2H16C16.5523 2 17 2.44772 17 3V6ZM18 8H6V20H18V8ZM9 4V6H15V4H9Z" },
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function tr(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M17 6H22V8H20V21C20 21.5523 19.5523 22 19 22H5C4.44772 22 4 21.5523 4 21V8H2V6H7V3C7 2.44772 7.44772 2 8 2H16C16.5523 2 17 2.44772 17 3V6ZM9 11V17H11V11H9ZM13 11V17H15V11H13ZM9 4V6H15V4H9Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function nr(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [{ tag: "path", attr: { d: "M4 19H20V12H22V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V12H4V19ZM14 9H19L12 16L5 9H10V3H14V9Z" }, child: [] }],
|
|
})(e2);
|
|
}
|
|
function or(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M10 6V8H5V19H16V14H18V20C18 20.5523 17.5523 21 17 21H4C3.44772 21 3 20.5523 3 20V7C3 6.44772 3.44772 6 4 6H10ZM21 3V12L17.206 8.207L11.2071 14.2071L9.79289 12.7929L15.792 6.793L12 3H21Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function rr(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M5 10C3.9 10 3 10.9 3 12C3 13.1 3.9 14 5 14C6.1 14 7 13.1 7 12C7 10.9 6.1 10 5 10ZM19 10C17.9 10 17 10.9 17 12C17 13.1 17.9 14 19 14C20.1 14 21 13.1 21 12C21 10.9 20.1 10 19 10ZM12 10C10.9 10 10 10.9 10 12C10 13.1 10.9 14 12 14C13.1 14 14 13.1 14 12C14 10.9 13.1 10 12 10Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function ir(e2) {
|
|
return k$1({ attr: { viewBox: "0 0 24 24", fill: "currentColor" }, child: [{ tag: "path", attr: { d: "M5 11V13H19V11H5Z" }, child: [] }] })(e2);
|
|
}
|
|
function lr(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM8 13C8 15.2091 9.79086 17 12 17C14.2091 17 16 15.2091 16 13H8ZM8 11C8.82843 11 9.5 10.3284 9.5 9.5C9.5 8.67157 8.82843 8 8 8C7.17157 8 6.5 8.67157 6.5 9.5C6.5 10.3284 7.17157 11 8 11ZM16 11C16.8284 11 17.5 10.3284 17.5 9.5C17.5 8.67157 16.8284 8 16 8C15.1716 8 14.5 8.67157 14.5 9.5C14.5 10.3284 15.1716 11 16 11Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function dt$1(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24", fill: "currentColor" },
|
|
child: [
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM8 13H16C16 15.2091 14.2091 17 12 17C9.79086 17 8 15.2091 8 13ZM8 11C7.17157 11 6.5 10.3284 6.5 9.5C6.5 8.67157 7.17157 8 8 8C8.82843 8 9.5 8.67157 9.5 9.5C9.5 10.3284 8.82843 11 8 11ZM16 11C15.1716 11 14.5 10.3284 14.5 9.5C14.5 8.67157 15.1716 8 16 8C16.8284 8 17.5 8.67157 17.5 9.5C17.5 10.3284 16.8284 11 16 11Z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
const cr = {
|
|
bold: No,
|
|
italic: Fo,
|
|
underline: Wo,
|
|
strike: jo,
|
|
code: Eo,
|
|
};
|
|
function ar(e2, t) {
|
|
return e2 in t.schema.styleSchema && t.schema.styleSchema[e2].type === e2 && t.schema.styleSchema[e2].propSchema === "boolean";
|
|
}
|
|
const de = (e2) => {
|
|
const t = S(),
|
|
n = w(),
|
|
o = v(),
|
|
r = R({
|
|
editor: o,
|
|
selector: ({ editor: s }) => {
|
|
var a;
|
|
if (
|
|
// The editor is read-only.
|
|
!(
|
|
!s.isEditable || // The style is not in the schema.
|
|
!ar(e2.basicTextStyle, s) || // None of the selected blocks have inline content
|
|
!(((a = s.getSelection()) == null ? void 0 : a.blocks) || [s.getTextCursorPosition().block]).find((d) => d.content !== void 0)
|
|
)
|
|
)
|
|
return e2.basicTextStyle in s.getActiveStyles() ? { active: true } : { active: false };
|
|
},
|
|
}),
|
|
i = H(
|
|
(s) => {
|
|
(o.focus(), o.toggleStyles({ [s]: true }));
|
|
},
|
|
[o, e2],
|
|
);
|
|
if (r === void 0) return null;
|
|
const c = cr[e2.basicTextStyle];
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(n.FormattingToolbar.Button, {
|
|
"className": "bn-button",
|
|
"data-test": e2.basicTextStyle,
|
|
"onClick": () => i(e2.basicTextStyle),
|
|
"isSelected": r.active,
|
|
"label": t.formatting_toolbar[e2.basicTextStyle].tooltip,
|
|
"mainTooltip": t.formatting_toolbar[e2.basicTextStyle].tooltip,
|
|
"secondaryTooltip": L$1(t.formatting_toolbar[e2.basicTextStyle].secondary_tooltip, t.generic.ctrl_shortcut),
|
|
"icon": /* @__PURE__ */ jsxRuntimeExports.jsx(c, {}),
|
|
});
|
|
},
|
|
Pe$1 = (e2) => {
|
|
const t = e2.textColor || "default",
|
|
n = e2.backgroundColor || "default",
|
|
o = e2.size || 16,
|
|
r = V(
|
|
() => ({
|
|
pointerEvents: "none",
|
|
fontSize: (o * 0.75).toString() + "px",
|
|
height: o.toString() + "px",
|
|
lineHeight: o.toString() + "px",
|
|
textAlign: "center",
|
|
width: o.toString() + "px",
|
|
}),
|
|
[o],
|
|
);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
"className": "bn-color-icon",
|
|
"data-background-color": n,
|
|
"data-text-color": t,
|
|
"style": r,
|
|
"children": "A",
|
|
});
|
|
},
|
|
ut$1 = ["default", "gray", "brown", "red", "orange", "yellow", "green", "blue", "purple", "pink"],
|
|
xe$1 = (e2) => {
|
|
const t = w(),
|
|
n = S();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
() =>
|
|
e2.text ?
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Label, { children: n.color_picker.text_title }),
|
|
ut$1.map((i) =>
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
t.Generic.Menu.Item,
|
|
{
|
|
"onClick": () => {
|
|
(e2.onClick && e2.onClick(), e2.text.setColor(i));
|
|
},
|
|
"data-test": "text-color-" + i,
|
|
"icon": /* @__PURE__ */ jsxRuntimeExports.jsx(Pe$1, { textColor: i, size: e2.iconSize }),
|
|
"checked": e2.text.color === i,
|
|
"children": n.color_picker.colors[i],
|
|
},
|
|
"text-color-" + i,
|
|
),
|
|
),
|
|
],
|
|
})
|
|
: null,
|
|
{},
|
|
),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
() =>
|
|
e2.background ?
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Label, { children: n.color_picker.background_title }),
|
|
ut$1.map((i) =>
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
t.Generic.Menu.Item,
|
|
{
|
|
"onClick": () => {
|
|
(e2.onClick && e2.onClick(), e2.background.setColor(i));
|
|
},
|
|
"data-test": "background-color-" + i,
|
|
"icon": /* @__PURE__ */ jsxRuntimeExports.jsx(Pe$1, { backgroundColor: i, size: e2.iconSize }),
|
|
"checked": e2.background.color === i,
|
|
"children": n.color_picker.colors[i],
|
|
},
|
|
"background-color-" + i,
|
|
),
|
|
),
|
|
],
|
|
})
|
|
: null,
|
|
{},
|
|
),
|
|
],
|
|
});
|
|
};
|
|
function ue(e2, t) {
|
|
return `${e2}Color` in t.schema.styleSchema && t.schema.styleSchema[`${e2}Color`].type === `${e2}Color` && t.schema.styleSchema[`${e2}Color`].propSchema === "string";
|
|
}
|
|
const sr = () => {
|
|
const e2 = w(),
|
|
t = S(),
|
|
n = v(),
|
|
o = ue("text", n),
|
|
r = ue("background", n),
|
|
i = R({
|
|
editor: n,
|
|
selector: ({ editor: a }) => {
|
|
var m;
|
|
if (
|
|
// The editor is read-only.
|
|
!a.isEditable || // None of the selected blocks have inline content
|
|
!(((m = a.getSelection()) == null ? void 0 : m.blocks) || [a.getTextCursorPosition().block]).find((f) => f.content !== void 0)
|
|
)
|
|
return;
|
|
const d = ue("text", a),
|
|
u = ue("background", a);
|
|
if (!(!d && !u))
|
|
return {
|
|
textColor: d ? a.getActiveStyles().textColor || "default" : void 0,
|
|
backgroundColor: u ? a.getActiveStyles().backgroundColor || "default" : void 0,
|
|
};
|
|
},
|
|
}),
|
|
c = H(
|
|
(a) => {
|
|
if (!o) throw Error("Tried to set text color, but style does not exist in editor schema.");
|
|
(a === "default" ? n.removeStyles({ textColor: a }) : n.addStyles({ textColor: a }),
|
|
setTimeout(() => {
|
|
n.focus();
|
|
}));
|
|
},
|
|
[n, o],
|
|
),
|
|
s = H(
|
|
(a) => {
|
|
if (!r) throw Error("Tried to set background color, but style does not exist in editor schema.");
|
|
(a === "default" ? n.removeStyles({ backgroundColor: a }) : n.addStyles({ backgroundColor: a }),
|
|
setTimeout(() => {
|
|
n.focus();
|
|
}));
|
|
},
|
|
[r, n],
|
|
);
|
|
return i === void 0 ? null : (
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(e2.Generic.Menu.Root, {
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(e2.Generic.Menu.Trigger, {
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(e2.FormattingToolbar.Button, {
|
|
"className": "bn-button",
|
|
"data-test": "colors",
|
|
"label": t.formatting_toolbar.colors.tooltip,
|
|
"mainTooltip": t.formatting_toolbar.colors.tooltip,
|
|
"icon": /* @__PURE__ */ jsxRuntimeExports.jsx(Pe$1, {
|
|
textColor: i.textColor,
|
|
backgroundColor: i.backgroundColor,
|
|
size: 20,
|
|
}),
|
|
}),
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(e2.Generic.Menu.Dropdown, {
|
|
className: "bn-menu-dropdown bn-color-picker-dropdown",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(xe$1, {
|
|
text:
|
|
i.textColor ?
|
|
{
|
|
color: i.textColor,
|
|
setColor: c,
|
|
}
|
|
: void 0,
|
|
background:
|
|
i.backgroundColor ?
|
|
{
|
|
color: i.backgroundColor,
|
|
setColor: s,
|
|
}
|
|
: void 0,
|
|
}),
|
|
}),
|
|
],
|
|
})
|
|
);
|
|
},
|
|
mt$1 = (e2) => {
|
|
for (const t of Ro$1) if (e2.startsWith(t)) return e2;
|
|
return `${Vo$1}://${e2}`;
|
|
},
|
|
Wt = (e2) => {
|
|
const t = w(),
|
|
n = S(),
|
|
{ editLink: o } = _(No$1),
|
|
{ url: r, text: i, showTextField: c } = e2,
|
|
[s, a] = T(r),
|
|
[d, u] = T(i);
|
|
M$1(() => {
|
|
(a(r), u(i));
|
|
}, [i, r]);
|
|
const m = H(
|
|
(b) => {
|
|
var p, C;
|
|
b.key === "Enter" &&
|
|
!b.nativeEvent.isComposing &&
|
|
(b.preventDefault(), o(mt$1(s), d, e2.range.from), (p = e2.setToolbarOpen) == null || p.call(e2, false), (C = e2.setToolbarPositionFrozen) == null || C.call(e2, false));
|
|
},
|
|
[o, s, d, e2],
|
|
),
|
|
f = H((b) => a(b.currentTarget.value), []),
|
|
g = H((b) => u(b.currentTarget.value), []),
|
|
h = H(() => {
|
|
var b, p;
|
|
(o(mt$1(s), d, e2.range.from), (b = e2.setToolbarOpen) == null || b.call(e2, false), (p = e2.setToolbarPositionFrozen) == null || p.call(e2, false));
|
|
}, [o, s, d, e2]);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(t.Generic.Form.Root, {
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Form.TextInput, {
|
|
className: "bn-text-input",
|
|
name: "url",
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Dt$1, {}),
|
|
autoFocus: true,
|
|
placeholder: n.link_toolbar.form.url_placeholder,
|
|
value: s,
|
|
onKeyDown: m,
|
|
onChange: f,
|
|
onSubmit: h,
|
|
}),
|
|
c !== false &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Form.TextInput, {
|
|
className: "bn-text-input",
|
|
name: "title",
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(je$1, {}),
|
|
placeholder: n.link_toolbar.form.title_placeholder,
|
|
value: d,
|
|
onKeyDown: m,
|
|
onChange: g,
|
|
onSubmit: h,
|
|
}),
|
|
],
|
|
});
|
|
};
|
|
function dr(e2) {
|
|
return "link" in e2.schema.inlineContentSchema && e2.schema.inlineContentSchema.link === "link";
|
|
}
|
|
const ur = () => {
|
|
const e2 = v(),
|
|
t = w(),
|
|
n = S(),
|
|
o = _(Ao$1),
|
|
{ showSelection: r } = _(b),
|
|
[i, c] = T(false);
|
|
M$1(() => (r(i, "createLinkButton"), () => r(false, "createLinkButton")), [i, r]);
|
|
const s = R({
|
|
editor: e2,
|
|
selector: ({ editor: a }) => {
|
|
var d;
|
|
if (
|
|
// The editor is read-only.
|
|
!(
|
|
!a.isEditable || // Links are not in the schema.
|
|
!dr(a) || // Table cells are selected.
|
|
Bo$1(a.prosemirrorState.selection) || // None of the selected blocks have inline content
|
|
!(((d = a.getSelection()) == null ? void 0 : d.blocks) || [a.getTextCursorPosition().block]).find((u) => u.content !== void 0)
|
|
)
|
|
)
|
|
return {
|
|
url: a.getSelectedLinkUrl(),
|
|
text: a.getSelectedText(),
|
|
range: {
|
|
from: a.prosemirrorState.selection.from,
|
|
to: a.prosemirrorState.selection.to,
|
|
},
|
|
};
|
|
},
|
|
});
|
|
return (
|
|
M$1(() => {
|
|
c(false);
|
|
}, [s]),
|
|
M$1(() => {
|
|
const a = (u) => {
|
|
(u.ctrlKey || u.metaKey) && u.key === "k" && (c(true), u.preventDefault());
|
|
},
|
|
d = e2.domElement;
|
|
return (
|
|
d == null || d.addEventListener("keydown", a),
|
|
() => {
|
|
d == null || d.removeEventListener("keydown", a);
|
|
}
|
|
);
|
|
}, [e2.domElement]),
|
|
s === void 0 ? null : (
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(t.Generic.Popover.Root, {
|
|
open: i,
|
|
onOpenChange: c,
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Popover.Trigger, {
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(t.FormattingToolbar.Button, {
|
|
"className": "bn-button",
|
|
"data-test": "createLink",
|
|
"label": n.formatting_toolbar.link.tooltip,
|
|
"mainTooltip": n.formatting_toolbar.link.tooltip,
|
|
"secondaryTooltip": L$1(n.formatting_toolbar.link.secondary_tooltip, n.generic.ctrl_shortcut),
|
|
"icon": /* @__PURE__ */ jsxRuntimeExports.jsx(Dt$1, {}),
|
|
"onClick": () => c((a) => !a),
|
|
}),
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Popover.Content, {
|
|
className: "bn-popover-content bn-form-popover",
|
|
variant: "form-popover",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Wt, {
|
|
url: s.url || "",
|
|
text: s.text,
|
|
range: s.range,
|
|
showTextField: false,
|
|
setToolbarOpen: (a) => o.store.setState(a),
|
|
}),
|
|
}),
|
|
],
|
|
})
|
|
)
|
|
);
|
|
},
|
|
mr = () => {
|
|
const e2 = S(),
|
|
t = w(),
|
|
n = v(),
|
|
o = R({
|
|
editor: n,
|
|
selector: ({ editor: a }) => {
|
|
var m;
|
|
if (!a.isEditable) return;
|
|
const d = ((m = a.getSelection()) == null ? void 0 : m.blocks) || [a.getTextCursorPosition().block];
|
|
if (d.length !== 1) return;
|
|
const u = d[0];
|
|
if (
|
|
To$1(u, a, u.type, {
|
|
url: "string",
|
|
caption: "string",
|
|
})
|
|
)
|
|
return u;
|
|
},
|
|
}),
|
|
[r, i] = T();
|
|
M$1(() => {
|
|
o !== void 0 && i(o.props.caption);
|
|
}, [o]);
|
|
const c = H((a) => i(a.currentTarget.value), []),
|
|
s = H(
|
|
(a) => {
|
|
o !== void 0 &&
|
|
b$1(n, o.type, {
|
|
caption: "string",
|
|
}) &&
|
|
a.key === "Enter" &&
|
|
!a.nativeEvent.isComposing &&
|
|
(a.preventDefault(),
|
|
n.updateBlock(o.id, {
|
|
props: {
|
|
caption: r,
|
|
},
|
|
}));
|
|
},
|
|
[o, r, n],
|
|
);
|
|
return o === void 0 ? null : (
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(t.Generic.Popover.Root, {
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Popover.Trigger, {
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(t.FormattingToolbar.Button, {
|
|
className: "bn-button",
|
|
label: e2.formatting_toolbar.file_caption.tooltip,
|
|
mainTooltip: e2.formatting_toolbar.file_caption.tooltip,
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(st$1, {}),
|
|
}),
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Popover.Content, {
|
|
className: "bn-popover-content bn-form-popover",
|
|
variant: "form-popover",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Form.Root, {
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Form.TextInput, {
|
|
name: "file-caption",
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(st$1, {}),
|
|
value: r || "",
|
|
autoFocus: true,
|
|
placeholder: e2.formatting_toolbar.file_caption.input_placeholder,
|
|
onKeyDown: s,
|
|
onChange: c,
|
|
}),
|
|
}),
|
|
}),
|
|
],
|
|
})
|
|
);
|
|
},
|
|
fr = () => {
|
|
const e2 = S(),
|
|
t = w(),
|
|
n = v(),
|
|
o = R({
|
|
editor: n,
|
|
selector: ({ editor: i }) => {
|
|
var a;
|
|
if (!i.isEditable) return;
|
|
const c = ((a = i.getSelection()) == null ? void 0 : a.blocks) || [i.getTextCursorPosition().block];
|
|
if (c.length !== 1) return;
|
|
const s = c[0];
|
|
if (
|
|
To$1(s, i, s.type, {
|
|
url: "string",
|
|
})
|
|
)
|
|
return s;
|
|
},
|
|
}),
|
|
r = H(() => {
|
|
o !== void 0 && (n.focus(), n.removeBlocks([o.id]));
|
|
}, [o, n]);
|
|
return o === void 0 ? null : (
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.FormattingToolbar.Button, {
|
|
className: "bn-button",
|
|
label: e2.formatting_toolbar.file_delete.tooltip[o.type] || e2.formatting_toolbar.file_delete.tooltip.file,
|
|
mainTooltip: e2.formatting_toolbar.file_delete.tooltip[o.type] || e2.formatting_toolbar.file_delete.tooltip.file,
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(er, {}),
|
|
onClick: r,
|
|
})
|
|
);
|
|
},
|
|
gr = () => {
|
|
const e2 = S(),
|
|
t = w(),
|
|
n = v(),
|
|
o = R({
|
|
editor: n,
|
|
selector: ({ editor: a }) => {
|
|
var m;
|
|
if (!a.isEditable) return;
|
|
const d = ((m = a.getSelection()) == null ? void 0 : m.blocks) || [a.getTextCursorPosition().block];
|
|
if (d.length !== 1) return;
|
|
const u = d[0];
|
|
if (
|
|
To$1(u, a, u.type, {
|
|
url: "string",
|
|
name: "string",
|
|
})
|
|
)
|
|
return u;
|
|
},
|
|
}),
|
|
[r, i] = T();
|
|
M$1(() => {
|
|
o !== void 0 && i(o.props.name);
|
|
}, [o]);
|
|
const c = H((a) => i(a.currentTarget.value), []),
|
|
s = H(
|
|
(a) => {
|
|
o !== void 0 &&
|
|
b$1(n, o.type, {
|
|
name: "string",
|
|
}) &&
|
|
a.key === "Enter" &&
|
|
!a.nativeEvent.isComposing &&
|
|
(a.preventDefault(),
|
|
n.updateBlock(o.id, {
|
|
props: {
|
|
name: r,
|
|
},
|
|
}));
|
|
},
|
|
[o, r, n],
|
|
);
|
|
return o === void 0 ? null : (
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(t.Generic.Popover.Root, {
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Popover.Trigger, {
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(t.FormattingToolbar.Button, {
|
|
className: "bn-button",
|
|
label: e2.formatting_toolbar.file_rename.tooltip[o.type] || e2.formatting_toolbar.file_rename.tooltip.file,
|
|
mainTooltip: e2.formatting_toolbar.file_rename.tooltip[o.type] || e2.formatting_toolbar.file_rename.tooltip.file,
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(at$1, {}),
|
|
}),
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Popover.Content, {
|
|
className: "bn-popover-content bn-form-popover",
|
|
variant: "form-popover",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Form.Root, {
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Form.TextInput, {
|
|
name: "file-name",
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(at$1, {}),
|
|
value: r || "",
|
|
autoFocus: true,
|
|
placeholder: e2.formatting_toolbar.file_rename.input_placeholder[o.type] || e2.formatting_toolbar.file_rename.input_placeholder.file,
|
|
onKeyDown: s,
|
|
onChange: c,
|
|
}),
|
|
}),
|
|
}),
|
|
],
|
|
})
|
|
);
|
|
},
|
|
hr = () => {
|
|
const e2 = S(),
|
|
t = w(),
|
|
n = v(),
|
|
o = R({
|
|
editor: n,
|
|
selector: ({ editor: r }) => {
|
|
var s;
|
|
if (!r.isEditable) return;
|
|
const i = ((s = r.getSelection()) == null ? void 0 : s.blocks) || [r.getTextCursorPosition().block];
|
|
if (i.length !== 1) return;
|
|
const c = i[0];
|
|
if (
|
|
To$1(c, r, c.type, {
|
|
url: "string",
|
|
})
|
|
)
|
|
return c;
|
|
},
|
|
});
|
|
return o === void 0 ? null : (
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(t.Generic.Popover.Root, {
|
|
position: "bottom",
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Popover.Trigger, {
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(t.FormattingToolbar.Button, {
|
|
className: "bn-button",
|
|
mainTooltip: e2.formatting_toolbar.file_replace.tooltip[o.type] || e2.formatting_toolbar.file_replace.tooltip.file,
|
|
label: e2.formatting_toolbar.file_replace.tooltip[o.type] || e2.formatting_toolbar.file_replace.tooltip.file,
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Xo, {}),
|
|
}),
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Popover.Content, {
|
|
className: "bn-popover-content bn-panel-popover",
|
|
variant: "panel-popover",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Lt$1, { blockId: o.id }),
|
|
}),
|
|
],
|
|
})
|
|
);
|
|
},
|
|
br = () => {
|
|
const e2 = S(),
|
|
t = w(),
|
|
n = v(),
|
|
o = R({
|
|
editor: n,
|
|
selector: ({ editor: i }) => {
|
|
var c;
|
|
if (
|
|
// The editor is read-only.
|
|
!(
|
|
!i.isEditable || // None of the selected blocks have inline content
|
|
!(((c = i.getSelection()) == null ? void 0 : c.blocks) || [i.getTextCursorPosition().block]).find((s) => s.content !== void 0)
|
|
)
|
|
)
|
|
return {
|
|
canNestBlock: i.canNestBlock(),
|
|
};
|
|
},
|
|
}),
|
|
r = H(() => {
|
|
o !== void 0 && o.canNestBlock && (n.focus(), n.nestBlock());
|
|
}, [n, o]);
|
|
return o === void 0 ? null : (
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.FormattingToolbar.Button, {
|
|
"className": "bn-button",
|
|
"data-test": "nestBlock",
|
|
"onClick": r,
|
|
"isDisabled": !o.canNestBlock,
|
|
"label": e2.formatting_toolbar.nest.tooltip,
|
|
"mainTooltip": e2.formatting_toolbar.nest.tooltip,
|
|
"secondaryTooltip": L$1(e2.formatting_toolbar.nest.secondary_tooltip, e2.generic.ctrl_shortcut),
|
|
"icon": /* @__PURE__ */ jsxRuntimeExports.jsx(Zo, {}),
|
|
})
|
|
);
|
|
},
|
|
pr = () => {
|
|
const e2 = S(),
|
|
t = w(),
|
|
n = v(),
|
|
o = R({
|
|
editor: n,
|
|
selector: ({ editor: i }) => {
|
|
var c;
|
|
if (
|
|
// The editor is read-only.
|
|
!(
|
|
!i.isEditable || // None of the selected blocks have inline content
|
|
!(((c = i.getSelection()) == null ? void 0 : c.blocks) || [i.getTextCursorPosition().block]).find((s) => s.content !== void 0)
|
|
)
|
|
)
|
|
return {
|
|
canUnnestBlock: i.canUnnestBlock(),
|
|
};
|
|
},
|
|
}),
|
|
r = H(() => {
|
|
o !== void 0 && o.canUnnestBlock && (n.focus(), n.unnestBlock());
|
|
}, [n, o]);
|
|
return o === void 0 ? null : (
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.FormattingToolbar.Button, {
|
|
"className": "bn-button",
|
|
"data-test": "unnestBlock",
|
|
"onClick": r,
|
|
"isDisabled": !o.canUnnestBlock,
|
|
"label": e2.formatting_toolbar.unnest.tooltip,
|
|
"mainTooltip": e2.formatting_toolbar.unnest.tooltip,
|
|
"secondaryTooltip": L$1(e2.formatting_toolbar.unnest.secondary_tooltip, e2.generic.ctrl_shortcut),
|
|
"icon": /* @__PURE__ */ jsxRuntimeExports.jsx(Do, {}),
|
|
})
|
|
);
|
|
},
|
|
Cr = (e2) => [
|
|
{
|
|
name: e2.slash_menu.paragraph.title,
|
|
type: "paragraph",
|
|
icon: je$1,
|
|
},
|
|
{
|
|
name: e2.slash_menu.heading.title,
|
|
type: "heading",
|
|
props: { level: 1, isToggleable: false },
|
|
icon: pe,
|
|
},
|
|
{
|
|
name: e2.slash_menu.heading_2.title,
|
|
type: "heading",
|
|
props: { level: 2, isToggleable: false },
|
|
icon: Ce$1,
|
|
},
|
|
{
|
|
name: e2.slash_menu.heading_3.title,
|
|
type: "heading",
|
|
props: { level: 3, isToggleable: false },
|
|
icon: ve$1,
|
|
},
|
|
{
|
|
name: e2.slash_menu.heading_4.title,
|
|
type: "heading",
|
|
props: { level: 4, isToggleable: false },
|
|
icon: Pt$1,
|
|
},
|
|
{
|
|
name: e2.slash_menu.heading_5.title,
|
|
type: "heading",
|
|
props: { level: 5, isToggleable: false },
|
|
icon: Nt$1,
|
|
},
|
|
{
|
|
name: e2.slash_menu.heading_6.title,
|
|
type: "heading",
|
|
props: { level: 6, isToggleable: false },
|
|
icon: At$1,
|
|
},
|
|
{
|
|
name: e2.slash_menu.toggle_heading.title,
|
|
type: "heading",
|
|
props: { level: 1, isToggleable: true },
|
|
icon: pe,
|
|
},
|
|
{
|
|
name: e2.slash_menu.toggle_heading_2.title,
|
|
type: "heading",
|
|
props: { level: 2, isToggleable: true },
|
|
icon: Ce$1,
|
|
},
|
|
{
|
|
name: e2.slash_menu.toggle_heading_3.title,
|
|
type: "heading",
|
|
props: { level: 3, isToggleable: true },
|
|
icon: ve$1,
|
|
},
|
|
{
|
|
name: e2.slash_menu.quote.title,
|
|
type: "quote",
|
|
icon: Gt$1,
|
|
},
|
|
{
|
|
name: e2.slash_menu.toggle_list.title,
|
|
type: "toggleListItem",
|
|
icon: jt$1,
|
|
},
|
|
{
|
|
name: e2.slash_menu.bullet_list.title,
|
|
type: "bulletListItem",
|
|
icon: Ut,
|
|
},
|
|
{
|
|
name: e2.slash_menu.numbered_list.title,
|
|
type: "numberedListItem",
|
|
icon: Ft$1,
|
|
},
|
|
{
|
|
name: e2.slash_menu.check_list.title,
|
|
type: "checkListItem",
|
|
icon: Zt,
|
|
},
|
|
],
|
|
vr = (e2) => {
|
|
const t = w(),
|
|
n = v(),
|
|
o = R({
|
|
editor: n,
|
|
selector: ({ editor: a }) => {
|
|
var d;
|
|
return ((d = a.getSelection()) == null ? void 0 : d.blocks) || [a.getTextCursorPosition().block];
|
|
},
|
|
}),
|
|
r = o[0],
|
|
i = V(() => (e2.items || Cr(n.dictionary)).filter((a) => b$1(n, a.type, Object.fromEntries(Object.entries(a.props || {}).map(([d, u]) => [d, typeof u])))), [n, e2.items]),
|
|
c = V(
|
|
() =>
|
|
i.map((a) => {
|
|
const d = a.icon,
|
|
u = a.type === r.type,
|
|
m = Object.entries(a.props || {}).filter(([f, g]) => g !== r.props[f]).length === 0;
|
|
return {
|
|
text: a.name,
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(d, { size: 16 }),
|
|
onClick: () => {
|
|
(n.focus(),
|
|
n.transact(() => {
|
|
for (const f of o)
|
|
n.updateBlock(f, {
|
|
type: a.type,
|
|
props: a.props,
|
|
});
|
|
}));
|
|
},
|
|
isSelected: u && m,
|
|
};
|
|
}),
|
|
[n, i, r.props, r.type, o],
|
|
);
|
|
return !V(() => c.find((a) => a.isSelected) !== void 0, [c]) || !n.isEditable ?
|
|
null
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsx(t.FormattingToolbar.Select, {
|
|
className: "bn-select",
|
|
items: c,
|
|
});
|
|
},
|
|
wr = () => {
|
|
const e2 = S(),
|
|
t = w(),
|
|
n = _("comments"),
|
|
{ store: o } = _(Ao$1),
|
|
r = H(() => {
|
|
(n.startPendingComment(), o.setState(false));
|
|
}, [n, o]);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(t.FormattingToolbar.Button, {
|
|
className: "bn-button",
|
|
label: e2.formatting_toolbar.comment.tooltip,
|
|
mainTooltip: e2.formatting_toolbar.comment.tooltip,
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(It$1, {}),
|
|
onClick: r,
|
|
});
|
|
},
|
|
kr = () => (v().getExtension("comments") ? /* @__PURE__ */ jsxRuntimeExports.jsx(wr, {}) : null),
|
|
Hr = () => {
|
|
const e2 = S(),
|
|
t = w(),
|
|
n = v(),
|
|
o = H(() => {
|
|
n._tiptapEditor.chain().focus().addPendingComment().run();
|
|
}, [n]);
|
|
return (
|
|
// We manually check if a comment extension (like liveblocks) is installed
|
|
// By adding default support for this, the user doesn't need to customize the formatting toolbar
|
|
!n._tiptapEditor.commands.addPendingComment || !n.isEditable ?
|
|
null
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsx(t.FormattingToolbar.Button, {
|
|
className: "bn-button",
|
|
label: e2.formatting_toolbar.comment.tooltip,
|
|
mainTooltip: e2.formatting_toolbar.comment.tooltip,
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(It$1, {}),
|
|
onClick: o,
|
|
})
|
|
);
|
|
};
|
|
function Ne$1(e2, t) {
|
|
try {
|
|
const n = new URL(e2, t);
|
|
if (n.protocol !== "javascript:") return n.href;
|
|
} catch {}
|
|
return "#";
|
|
}
|
|
const xr = () => {
|
|
const e2 = S(),
|
|
t = w(),
|
|
n = v(),
|
|
o = R({
|
|
editor: n,
|
|
selector: ({ editor: i }) => {
|
|
var a;
|
|
const c = ((a = i.getSelection()) == null ? void 0 : a.blocks) || [i.getTextCursorPosition().block];
|
|
if (c.length !== 1) return;
|
|
const s = c[0];
|
|
if (
|
|
To$1(s, i, s.type, {
|
|
url: "string",
|
|
})
|
|
)
|
|
return s;
|
|
},
|
|
}),
|
|
r = H(() => {
|
|
o !== void 0 &&
|
|
(n.focus(), n.resolveFileUrl ? n.resolveFileUrl(o.props.url).then((i) => window.open(Ne$1(i, window.location.href))) : window.open(Ne$1(o.props.url, window.location.href)));
|
|
}, [o, n]);
|
|
return o === void 0 ? null : (
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.FormattingToolbar.Button, {
|
|
className: "bn-button",
|
|
label: e2.formatting_toolbar.file_download.tooltip[o.type] || e2.formatting_toolbar.file_download.tooltip.file,
|
|
mainTooltip: e2.formatting_toolbar.file_download.tooltip[o.type] || e2.formatting_toolbar.file_download.tooltip.file,
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(nr, {}),
|
|
onClick: r,
|
|
})
|
|
);
|
|
},
|
|
yr = () => {
|
|
const e2 = S(),
|
|
t = w(),
|
|
n = v(),
|
|
o = R({
|
|
editor: n,
|
|
selector: ({ editor: i }) => {
|
|
var a;
|
|
if (!i.isEditable) return;
|
|
const c = ((a = i.getSelection()) == null ? void 0 : a.blocks) || [i.getTextCursorPosition().block];
|
|
if (c.length !== 1) return;
|
|
const s = c[0];
|
|
if (
|
|
To$1(s, i, s.type, {
|
|
url: "string",
|
|
showPreview: "boolean",
|
|
})
|
|
)
|
|
return s;
|
|
},
|
|
}),
|
|
r = H(() => {
|
|
o !== void 0 &&
|
|
b$1(n, o.type, {
|
|
showPreview: "boolean",
|
|
}) &&
|
|
n.updateBlock(o.id, {
|
|
props: {
|
|
showPreview: !o.props.showPreview,
|
|
},
|
|
});
|
|
}, [o, n]);
|
|
return o === void 0 ? null : (
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.FormattingToolbar.Button, {
|
|
className: "bn-button",
|
|
label: "Toggle preview",
|
|
mainTooltip: e2.formatting_toolbar.file_preview_toggle.tooltip,
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Ko, {}),
|
|
isSelected: o.props.showPreview,
|
|
onClick: r,
|
|
})
|
|
);
|
|
},
|
|
Mr = () => {
|
|
const e2 = S(),
|
|
t = w(),
|
|
n = v(),
|
|
o = _(Yo),
|
|
r = R({
|
|
editor: n,
|
|
selector: ({ editor: c }) => {
|
|
var d;
|
|
if (!c.isEditable || !c.settings.tables.splitCells) return;
|
|
const s = ((d = c.getSelection()) == null ? void 0 : d.blocks) || [c.getTextCursorPosition().block];
|
|
if (s.length !== 1) return;
|
|
const a = s[0];
|
|
if (a.type === "table")
|
|
return {
|
|
mergeDirection: o.getMergeDirection(a),
|
|
};
|
|
},
|
|
}),
|
|
i = H(() => {
|
|
o == null || o.mergeCells();
|
|
}, [o]);
|
|
return r === void 0 ? null : (
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.FormattingToolbar.Button, {
|
|
className: "bn-button",
|
|
label: e2.formatting_toolbar.table_cell_merge.tooltip,
|
|
mainTooltip: e2.formatting_toolbar.table_cell_merge.tooltip,
|
|
icon: r.mergeDirection === "horizontal" ? /* @__PURE__ */ jsxRuntimeExports.jsx(Go, {}) : /* @__PURE__ */ jsxRuntimeExports.jsx(zo, {}),
|
|
onClick: i,
|
|
})
|
|
);
|
|
},
|
|
Sr = () => (v().getExtension(Yo) ? /* @__PURE__ */ jsxRuntimeExports.jsx(Mr, {}) : null),
|
|
Vr = {
|
|
left: Io,
|
|
center: Ro,
|
|
right: Po,
|
|
justify: Oo,
|
|
},
|
|
Le$1 = (e2) => {
|
|
const t = w(),
|
|
n = S(),
|
|
o = v(),
|
|
r = R({
|
|
editor: o,
|
|
selector: ({ editor: s }) => {
|
|
var u, m$1;
|
|
if (!s.isEditable) return;
|
|
const a = ((u = s.getSelection()) == null ? void 0 : u.blocks) || [s.getTextCursorPosition().block],
|
|
d = a[0];
|
|
if (
|
|
To$1(d, s, d.type, {
|
|
textAlignment: m.textAlignment,
|
|
})
|
|
)
|
|
return {
|
|
textAlignment: d.props.textAlignment,
|
|
blocks: a,
|
|
};
|
|
if (a.length === 1 && To$1(d, s, "table"))
|
|
return (
|
|
(m$1 = s.getExtension(Yo)) == null ? void 0 : m$1.getCellSelection()
|
|
) ?
|
|
{
|
|
textAlignment: S$1(d.content.rows[0].cells[0]).props.textAlignment,
|
|
blocks: [d],
|
|
}
|
|
: void 0;
|
|
},
|
|
}),
|
|
i = H(
|
|
(s) => {
|
|
var a;
|
|
if (r !== void 0) {
|
|
o.focus();
|
|
for (const d of r.blocks)
|
|
if (
|
|
To$1(d, o, d.type, {
|
|
textAlignment: m.textAlignment,
|
|
}) &&
|
|
b$1(o, d.type, {
|
|
textAlignment: m.textAlignment,
|
|
})
|
|
)
|
|
o.updateBlock(d, {
|
|
props: { textAlignment: s },
|
|
});
|
|
else if (d.type === "table") {
|
|
const u = (a = o.getExtension(Yo)) == null ? void 0 : a.getCellSelection();
|
|
if (!u) continue;
|
|
const m = d.content.rows.map((f) => ({
|
|
...f,
|
|
cells: f.cells.map((g) => S$1(g)),
|
|
}));
|
|
(u.cells.forEach(({ row: f, col: g }) => {
|
|
m[f].cells[g].props.textAlignment = s;
|
|
}),
|
|
o.updateBlock(d, {
|
|
type: "table",
|
|
content: {
|
|
...d.content,
|
|
type: "tableContent",
|
|
rows: m,
|
|
},
|
|
}),
|
|
o.setTextCursorPosition(d));
|
|
}
|
|
}
|
|
},
|
|
[o, r],
|
|
);
|
|
if (r === void 0) return null;
|
|
const c = Vr[e2.textAlignment];
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(t.FormattingToolbar.Button, {
|
|
"className": "bn-button",
|
|
"data-test": `alignText${e2.textAlignment.slice(0, 1).toUpperCase() + e2.textAlignment.slice(1)}`,
|
|
"onClick": () => i(e2.textAlignment),
|
|
"isSelected": r.textAlignment === e2.textAlignment,
|
|
"label": n.formatting_toolbar[`align_${e2.textAlignment}`].tooltip,
|
|
"mainTooltip": n.formatting_toolbar[`align_${e2.textAlignment}`].tooltip,
|
|
"icon": /* @__PURE__ */ jsxRuntimeExports.jsx(c, {}),
|
|
});
|
|
},
|
|
Tr = (e2) => [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(vr, { items: e2 }, "blockTypeSelect"),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Sr, {}, "tableCellMergeButton"),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(mr, {}, "fileCaptionButton"),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(hr, {}, "replaceFileButton"),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(gr, {}, "fileRenameButton"),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(fr, {}, "fileDeleteButton"),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(xr, {}, "fileDownloadButton"),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(yr, {}, "filePreviewButton"),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(de, { basicTextStyle: "bold" }, "boldStyleButton"),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(de, { basicTextStyle: "italic" }, "italicStyleButton"),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
de,
|
|
{
|
|
basicTextStyle: "underline",
|
|
},
|
|
"underlineStyleButton",
|
|
),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(de, { basicTextStyle: "strike" }, "strikeStyleButton"),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Le$1, { textAlignment: "left" }, "textAlignLeftButton"),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Le$1, { textAlignment: "center" }, "textAlignCenterButton"),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Le$1, { textAlignment: "right" }, "textAlignRightButton"),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(sr, {}, "colorStyleButton"),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(br, {}, "nestBlockButton"),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(pr, {}, "unnestBlockButton"),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ur, {}, "createLinkButton"),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(kr, {}, "addCommentButton"),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Hr, {}, "addTiptapCommentButton"),
|
|
],
|
|
qt$1 = (e2) => {
|
|
const t = w();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(t.FormattingToolbar.Root, {
|
|
className: "bn-toolbar bn-formatting-toolbar",
|
|
children: e2.children || Tr(e2.blockTypeSelectItems),
|
|
});
|
|
},
|
|
_r = (e2) => {
|
|
switch (e2) {
|
|
case "left":
|
|
return "top-start";
|
|
case "center":
|
|
return "top";
|
|
case "right":
|
|
return "top-end";
|
|
default:
|
|
return "top-start";
|
|
}
|
|
},
|
|
Br = (e2) => {
|
|
const t = v(),
|
|
n = _(Ao$1, {
|
|
editor: t,
|
|
}),
|
|
o = B(Ao$1, {
|
|
editor: t,
|
|
}),
|
|
r = R({
|
|
editor: t,
|
|
selector: ({ editor: a }) =>
|
|
n.store.state ?
|
|
{
|
|
from: a.prosemirrorState.selection.from,
|
|
to: a.prosemirrorState.selection.to,
|
|
}
|
|
: void 0,
|
|
}),
|
|
i = R({
|
|
editor: t,
|
|
selector: ({ editor: a }) => {
|
|
const d = a.getTextCursorPosition().block;
|
|
return (
|
|
To$1(d, a, d.type, {
|
|
textAlignment: m.textAlignment,
|
|
})
|
|
) ?
|
|
_r(d.props.textAlignment)
|
|
: "top-start";
|
|
},
|
|
}),
|
|
c = V(() => {
|
|
var a, d, u;
|
|
return {
|
|
...e2.floatingUIOptions,
|
|
useFloatingOptions: {
|
|
open: o,
|
|
// Needed as hooks like `useDismiss` call `onOpenChange` to change the
|
|
// open state.
|
|
onOpenChange: (m, f, g) => {
|
|
(n.store.setState(m), g === "escape-key" && t.focus());
|
|
},
|
|
placement: i,
|
|
middleware: [offset(10), shift(), flip()],
|
|
...((a = e2.floatingUIOptions) == null ? void 0 : a.useFloatingOptions),
|
|
},
|
|
focusManagerProps: {
|
|
disabled: true,
|
|
...((d = e2.floatingUIOptions) == null ? void 0 : d.focusManagerProps),
|
|
},
|
|
elementProps: {
|
|
style: {
|
|
zIndex: 40,
|
|
},
|
|
...((u = e2.floatingUIOptions) == null ? void 0 : u.elementProps),
|
|
},
|
|
};
|
|
}, [o, i, e2.floatingUIOptions, n.store, t]),
|
|
s = e2.formattingToolbar || qt$1;
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Ge$1, { position: r, ...c, children: o && /* @__PURE__ */ jsxRuntimeExports.jsx(s, {}) });
|
|
},
|
|
Lr = (e2) => {
|
|
const t = w(),
|
|
n = S(),
|
|
{ deleteLink: o } = _(No$1);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(t.LinkToolbar.Button, {
|
|
className: "bn-button",
|
|
label: n.link_toolbar.delete.tooltip,
|
|
mainTooltip: n.link_toolbar.delete.tooltip,
|
|
isSelected: false,
|
|
onClick: () => {
|
|
var r;
|
|
(o(e2.range.from), (r = e2.setToolbarOpen) == null || r.call(e2, false));
|
|
},
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Uo, {}),
|
|
});
|
|
},
|
|
Er = (e2) => {
|
|
const t = w(),
|
|
n = S();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(t.Generic.Popover.Root, {
|
|
onOpenChange: e2.setToolbarPositionFrozen,
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Popover.Trigger, {
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(t.LinkToolbar.Button, {
|
|
className: "bn-button",
|
|
mainTooltip: n.link_toolbar.edit.tooltip,
|
|
isSelected: false,
|
|
children: n.link_toolbar.edit.text,
|
|
}),
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Popover.Content, {
|
|
className: "bn-popover-content bn-form-popover",
|
|
variant: "form-popover",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Wt, {
|
|
url: e2.url,
|
|
text: e2.text,
|
|
range: e2.range,
|
|
setToolbarOpen: e2.setToolbarOpen,
|
|
setToolbarPositionFrozen: e2.setToolbarPositionFrozen,
|
|
}),
|
|
}),
|
|
],
|
|
});
|
|
},
|
|
Rr = (e2) => {
|
|
const t = w(),
|
|
n = S();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(t.LinkToolbar.Button, {
|
|
className: "bn-button",
|
|
mainTooltip: n.link_toolbar.open.tooltip,
|
|
label: n.link_toolbar.open.tooltip,
|
|
isSelected: false,
|
|
onClick: () => {
|
|
window.open(Ne$1(e2.url, window.location.href), "_blank");
|
|
},
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(or, {}),
|
|
});
|
|
},
|
|
Or = (e2) => {
|
|
const t = w();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(t.LinkToolbar.Root, {
|
|
className: "bn-toolbar bn-link-toolbar",
|
|
children:
|
|
e2.children ||
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Er, {
|
|
url: e2.url,
|
|
text: e2.text,
|
|
range: e2.range,
|
|
setToolbarOpen: e2.setToolbarOpen,
|
|
setToolbarPositionFrozen: e2.setToolbarPositionFrozen,
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Rr, { url: e2.url }),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Lr, {
|
|
range: e2.range,
|
|
setToolbarOpen: e2.setToolbarOpen,
|
|
}),
|
|
],
|
|
}),
|
|
});
|
|
},
|
|
Ir = (e2) => {
|
|
const t = v(),
|
|
[n, o] = T(false),
|
|
[r, i] = T(false),
|
|
c = _(No$1),
|
|
[s, a] = T(void 0);
|
|
M$1(() => {
|
|
const f = () => {
|
|
const C = c.getLinkAtSelection();
|
|
if (!C) {
|
|
(a(void 0), r || o(false));
|
|
return;
|
|
}
|
|
(a({
|
|
cursorType: "text",
|
|
url: C.mark.attrs.href,
|
|
text: C.text,
|
|
range: C.range,
|
|
element: c.getLinkElementAtPos(C.range.from),
|
|
}),
|
|
r || o(true));
|
|
},
|
|
g = (C) => {
|
|
if ((s !== void 0 && s.cursorType === "text") || !(C.target instanceof HTMLElement)) return;
|
|
const x = c.getLinkAtElement(C.target);
|
|
x &&
|
|
a({
|
|
cursorType: "mouse",
|
|
url: x.mark.attrs.href,
|
|
text: x.text,
|
|
range: x.range,
|
|
element: c.getLinkElementAtPos(x.range.from),
|
|
});
|
|
},
|
|
h = t.onChange(f),
|
|
b = t.onSelectionChange(f),
|
|
p = t.domElement;
|
|
return (
|
|
p == null || p.addEventListener("mouseover", g),
|
|
() => {
|
|
(h(), b(), p == null || p.removeEventListener("mouseover", g));
|
|
}
|
|
);
|
|
}, [t, t.domElement, c, s, r]);
|
|
const d = V(() => {
|
|
var f, g, h, b;
|
|
return {
|
|
...e2.floatingUIOptions,
|
|
useFloatingOptions: {
|
|
open: n,
|
|
onOpenChange: (p, C, x) => {
|
|
r || (s !== void 0 && s.cursorType === "text" && x === "hover") || (x === "escape-key" && t.focus(), o(p));
|
|
},
|
|
placement: "top-start",
|
|
middleware: [offset(10), flip()],
|
|
...((f = e2.floatingUIOptions) == null ? void 0 : f.useFloatingOptions),
|
|
},
|
|
useHoverProps: {
|
|
// `useHover` hook only enabled when a link is hovered with the
|
|
// mouse.
|
|
enabled: s !== void 0 && s.cursorType === "mouse",
|
|
delay: {
|
|
open: 250,
|
|
close: 250,
|
|
},
|
|
handleClose: safePolygon(),
|
|
...((g = e2.floatingUIOptions) == null ? void 0 : g.useHoverProps),
|
|
},
|
|
focusManagerProps: {
|
|
disabled: true,
|
|
...((h = e2.floatingUIOptions) == null ? void 0 : h.focusManagerProps),
|
|
},
|
|
elementProps: {
|
|
style: {
|
|
zIndex: 50,
|
|
},
|
|
...((b = e2.floatingUIOptions) == null ? void 0 : b.elementProps),
|
|
},
|
|
};
|
|
}, [t, s, e2.floatingUIOptions, n, r]),
|
|
u = V(() => (s != null && s.element ? { element: s.element } : void 0), [s == null ? void 0 : s.element]);
|
|
if (!t.isEditable) return null;
|
|
const m = e2.linkToolbar || Or;
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx($$1, {
|
|
reference: u,
|
|
...d,
|
|
children:
|
|
s &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(m, {
|
|
url: s.url,
|
|
text: s.text,
|
|
range: s.range,
|
|
setToolbarOpen: o,
|
|
setToolbarPositionFrozen: i,
|
|
}),
|
|
});
|
|
};
|
|
function Pr(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 1024 1024" },
|
|
child: [
|
|
{ tag: "path", attr: { d: "M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8Z" }, child: [] },
|
|
{ tag: "path", attr: { d: "M192 474h672q8 0 8 8v60q0 8-8 8H160q-8 0-8-8v-60q0-8 8-8Z" }, child: [] },
|
|
],
|
|
})(e2);
|
|
}
|
|
const Nr = () => {
|
|
const e2 = w(),
|
|
t = S(),
|
|
n = v(),
|
|
o = _(Vn),
|
|
r = B(_o$1, {
|
|
editor: n,
|
|
selector: (c) => (c == null ? void 0 : c.block),
|
|
}),
|
|
i = H(() => {
|
|
if (r === void 0) return;
|
|
const c = r.content;
|
|
if (c !== void 0 && Array.isArray(c) && c.length === 0) (n.setTextCursorPosition(r), o.openSuggestionMenu("/"));
|
|
else {
|
|
const a = n.insertBlocks([{ type: "paragraph" }], r, "after")[0];
|
|
(n.setTextCursorPosition(a), o.openSuggestionMenu("/"));
|
|
}
|
|
}, [r, n, o]);
|
|
return r === void 0 ? null : (
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(e2.SideMenu.Button, {
|
|
className: "bn-button",
|
|
label: t.side_menu.add_block_label,
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Pr, { "size": 24, "onClick": i, "data-test": "dragHandleAdd" }),
|
|
})
|
|
);
|
|
};
|
|
function Kt(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24" },
|
|
child: [
|
|
{ tag: "path", attr: { fill: "none", d: "M0 0h24v24H0V0z" }, child: [] },
|
|
{
|
|
tag: "path",
|
|
attr: {
|
|
d: "M11 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm-2-8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 4c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z",
|
|
},
|
|
child: [],
|
|
},
|
|
],
|
|
})(e2);
|
|
}
|
|
function Ar(e2) {
|
|
return k$1({
|
|
attr: { viewBox: "0 0 24 24" },
|
|
child: [
|
|
{ tag: "path", attr: { fill: "none", d: "M0 0h24v24H0z" }, child: [] },
|
|
{ tag: "path", attr: { d: "m7 10 5 5 5-5z" }, child: [] },
|
|
],
|
|
})(e2);
|
|
}
|
|
const Dr = (e2) => {
|
|
const t = w(),
|
|
n = v(),
|
|
o = B(_o$1, {
|
|
editor: n,
|
|
selector: (r) => (r == null ? void 0 : r.block),
|
|
});
|
|
return (
|
|
o === void 0 ||
|
|
(!To$1(o, n, o.type, {
|
|
textColor: "string",
|
|
}) &&
|
|
!To$1(o, n, o.type, {
|
|
backgroundColor: "string",
|
|
}))
|
|
) ?
|
|
null
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsxs(t.Generic.Menu.Root, {
|
|
position: "right",
|
|
sub: true,
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Trigger, {
|
|
sub: true,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Item, {
|
|
className: "bn-menu-item",
|
|
subTrigger: true,
|
|
children: e2.children,
|
|
}),
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Dropdown, {
|
|
sub: true,
|
|
className: "bn-menu-dropdown bn-color-picker-dropdown",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(xe$1, {
|
|
iconSize: 18,
|
|
text:
|
|
(
|
|
To$1(o, n, o.type, {
|
|
textColor: "string",
|
|
}) &&
|
|
b$1(n, o.type, {
|
|
textColor: "string",
|
|
})
|
|
) ?
|
|
{
|
|
color: o.props.textColor,
|
|
setColor: (r) =>
|
|
n.updateBlock(o, {
|
|
type: o.type,
|
|
props: { textColor: r },
|
|
}),
|
|
}
|
|
: void 0,
|
|
background:
|
|
(
|
|
To$1(o, n, o.type, {
|
|
backgroundColor: "string",
|
|
}) &&
|
|
b$1(n, o.type, {
|
|
backgroundColor: "string",
|
|
})
|
|
) ?
|
|
{
|
|
color: o.props.backgroundColor,
|
|
setColor: (r) =>
|
|
n.updateBlock(o, {
|
|
props: { backgroundColor: r },
|
|
}),
|
|
}
|
|
: void 0,
|
|
}),
|
|
}),
|
|
],
|
|
});
|
|
},
|
|
Zr = (e2) => {
|
|
const t = w(),
|
|
n = v(),
|
|
o = B(_o$1, {
|
|
editor: n,
|
|
selector: (r) => (r == null ? void 0 : r.block),
|
|
});
|
|
return o === void 0 ? null : (
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Item, {
|
|
className: "bn-menu-item",
|
|
onClick: () => n.removeBlocks([o]),
|
|
children: e2.children,
|
|
})
|
|
);
|
|
},
|
|
Fr = (e2) => {
|
|
const t = w(),
|
|
n = v(),
|
|
o = B(_o$1, {
|
|
editor: n,
|
|
selector: (i) => (i == null ? void 0 : i.block),
|
|
});
|
|
if (o === void 0 || o.type !== "table" || !n.settings.tables.headers) return null;
|
|
const r = !!o.content.headerRows;
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Item, {
|
|
className: "bn-menu-item",
|
|
checked: r,
|
|
onClick: () => {
|
|
n.updateBlock(o, {
|
|
content: {
|
|
...o.content,
|
|
headerRows: r ? void 0 : 1,
|
|
},
|
|
});
|
|
},
|
|
children: e2.children,
|
|
});
|
|
},
|
|
Ur = (e2) => {
|
|
const t = w(),
|
|
n = v(),
|
|
o = B(_o$1, {
|
|
editor: n,
|
|
selector: (i) => (i == null ? void 0 : i.block),
|
|
});
|
|
if (o === void 0 || o.type !== "table" || !n.settings.tables.headers) return null;
|
|
const r = !!o.content.headerCols;
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Item, {
|
|
className: "bn-menu-item",
|
|
checked: r,
|
|
onClick: () => {
|
|
n.updateBlock(o, {
|
|
content: {
|
|
...o.content,
|
|
headerCols: r ? void 0 : 1,
|
|
},
|
|
});
|
|
},
|
|
children: e2.children,
|
|
});
|
|
},
|
|
Gr = (e2) => {
|
|
const t = w(),
|
|
n = S();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Dropdown, {
|
|
className: "bn-menu-dropdown bn-drag-handle-menu",
|
|
children:
|
|
e2.children ||
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Zr, { children: n.drag_handle.delete_menuitem }),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Dr, { children: n.drag_handle.colors_menuitem }),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Fr, { children: n.drag_handle.header_row_menuitem }),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Ur, { children: n.drag_handle.header_column_menuitem }),
|
|
],
|
|
}),
|
|
});
|
|
},
|
|
zr = (e2) => {
|
|
const t = w(),
|
|
n = S(),
|
|
o = _(_o$1),
|
|
r = B(_o$1, {
|
|
selector: (c) => (c == null ? void 0 : c.block),
|
|
});
|
|
if (r === void 0) return null;
|
|
const i = e2.dragHandleMenu || Gr;
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(t.Generic.Menu.Root, {
|
|
onOpenChange: (c) => {
|
|
c ? o.freezeMenu() : o.unfreezeMenu();
|
|
},
|
|
position: "left",
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Trigger, {
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(t.SideMenu.Button, {
|
|
label: n.side_menu.drag_handle_label,
|
|
draggable: true,
|
|
onDragStart: (c) => o.blockDragStart(c, r),
|
|
onDragEnd: o.blockDragEnd,
|
|
className: "bn-button",
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Kt, { "size": 24, "data-test": "dragHandle" }),
|
|
}),
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(i, { children: e2.children }),
|
|
],
|
|
});
|
|
},
|
|
jr = (e2) => {
|
|
const t = w(),
|
|
n = v(),
|
|
o = B(_o$1, {
|
|
editor: n,
|
|
selector: (i) => (i == null ? void 0 : i.block),
|
|
}),
|
|
r = V(() => {
|
|
var c;
|
|
if (o === void 0) return {};
|
|
const i = {
|
|
"data-block-type": o.type,
|
|
};
|
|
return (
|
|
o.type === "heading" && (i["data-level"] = o.props.level.toString()),
|
|
(c = n.schema.blockSpecs[o.type].implementation.meta) != null && c.fileBlockAccept && (o.props.url ? (i["data-url"] = "true") : (i["data-url"] = "false")),
|
|
i
|
|
);
|
|
}, [o, n.schema.blockSpecs]);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(t.SideMenu.Root, {
|
|
className: "bn-side-menu",
|
|
...r,
|
|
children:
|
|
e2.children ||
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
|
|
children: [/* @__PURE__ */ jsxRuntimeExports.jsx(Nr, {}), /* @__PURE__ */ jsxRuntimeExports.jsx(zr, { dragHandleMenu: e2.dragHandleMenu })],
|
|
}),
|
|
});
|
|
},
|
|
$r = (e2) => {
|
|
const t = B(_o$1, {
|
|
selector: (c) =>
|
|
c !== void 0 ?
|
|
{
|
|
show: c.show,
|
|
block: c.block,
|
|
}
|
|
: void 0,
|
|
}),
|
|
{ show: n, block: o } = t || {},
|
|
r = V(() => {
|
|
var c, s, a, d;
|
|
return {
|
|
...e2.floatingUIOptions,
|
|
useFloatingOptions: {
|
|
open: n,
|
|
placement: "left-start",
|
|
...((c = e2.floatingUIOptions) == null ? void 0 : c.useFloatingOptions),
|
|
},
|
|
useDismissProps: {
|
|
enabled: false,
|
|
...((s = e2.floatingUIOptions) == null ? void 0 : s.useDismissProps),
|
|
},
|
|
focusManagerProps: {
|
|
disabled: true,
|
|
...((a = e2.floatingUIOptions) == null ? void 0 : a.focusManagerProps),
|
|
},
|
|
elementProps: {
|
|
style: {
|
|
zIndex: 20,
|
|
},
|
|
...((d = e2.floatingUIOptions) == null ? void 0 : d.elementProps),
|
|
},
|
|
};
|
|
}, [e2.floatingUIOptions, n]),
|
|
i = e2.sideMenu || jr;
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Bt$1, {
|
|
blockId:
|
|
n ?
|
|
o == null ?
|
|
void 0
|
|
: o.id
|
|
: void 0,
|
|
...r,
|
|
children: (o == null ? void 0 : o.id) && /* @__PURE__ */ jsxRuntimeExports.jsx(i, {}),
|
|
});
|
|
};
|
|
async function Wr(e2, t) {
|
|
return (await zo$1(e2, t)).map(({ id: n, onItemClick: o }) => ({
|
|
id: n,
|
|
onItemClick: o,
|
|
icon: n,
|
|
}));
|
|
}
|
|
function qr(e2) {
|
|
const t = w(),
|
|
n = S(),
|
|
{ items: o, loadingState: r, selectedIndex: i, onItemClick: c, columns: s } = e2,
|
|
a =
|
|
r === "loading-initial" || r === "loading" ?
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.GridSuggestionMenu.Loader, {
|
|
className: "bn-grid-suggestion-menu-loader",
|
|
columns: s,
|
|
})
|
|
: null,
|
|
d = V(() => {
|
|
const u = [];
|
|
for (let m = 0; m < o.length; m++) {
|
|
const f = o[m];
|
|
u.push(
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
t.GridSuggestionMenu.Item,
|
|
{
|
|
className: "bn-grid-suggestion-menu-item",
|
|
item: f,
|
|
id: `bn-grid-suggestion-menu-item-${m}`,
|
|
isSelected: m === i,
|
|
onClick: () => (c == null ? void 0 : c(f)),
|
|
},
|
|
f.id,
|
|
),
|
|
);
|
|
}
|
|
return u;
|
|
}, [t, o, c, i]);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(t.GridSuggestionMenu.Root, {
|
|
id: "bn-grid-suggestion-menu",
|
|
columns: s,
|
|
className: "bn-grid-suggestion-menu",
|
|
children: [
|
|
a,
|
|
d,
|
|
d.length === 0 &&
|
|
e2.loadingState === "loaded" &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.GridSuggestionMenu.EmptyItem, {
|
|
className: "bn-grid-suggestion-menu-empty-item",
|
|
columns: s,
|
|
children: n.suggestion_menu.no_items_title,
|
|
}),
|
|
],
|
|
});
|
|
}
|
|
function Xt(e2, t, n, o = 3) {
|
|
const r = F$1(0);
|
|
M$1(() => {
|
|
t !== void 0 && (e2.length > 0 ? (r.current = t.length) : t.length - r.current > o && n());
|
|
}, [n, o, e2.length, t]);
|
|
}
|
|
function Yt(e2, t) {
|
|
const [n, o] = T([]),
|
|
[r, i] = T(false),
|
|
c = F$1(void 0),
|
|
s = F$1(void 0);
|
|
return (
|
|
M$1(() => {
|
|
const a = e2;
|
|
((c.current = e2),
|
|
i(true),
|
|
t(e2).then((d) => {
|
|
c.current === a && (o(d), i(false), (s.current = a));
|
|
}));
|
|
}, [e2, t]),
|
|
{
|
|
items: n || [],
|
|
// The query that was used to retrieve the last set of items may not be the
|
|
// same as the current query as the items from the current query may not
|
|
// have been retrieved yet. This is useful when using the returns of this
|
|
// hook in other hooks.
|
|
usedQuery: s.current,
|
|
loadingState:
|
|
s.current === void 0 ? "loading-initial"
|
|
: r ? "loading"
|
|
: "loaded",
|
|
}
|
|
);
|
|
}
|
|
function Kr(e2, t, n, o, r) {
|
|
const [i, c] = T(0),
|
|
s = o !== void 0 && o > 1;
|
|
return (
|
|
M$1(() => {
|
|
const a = (u) => (
|
|
u.key === "ArrowLeft" && (u.preventDefault(), n.length && c((i - 1 + n.length) % n.length)),
|
|
u.key === "ArrowRight" && (u.preventDefault(), n.length && c((i + 1 + n.length) % n.length)),
|
|
u.key === "ArrowUp" ? (u.preventDefault(), n.length && c((i - o + n.length) % n.length), true)
|
|
: u.key === "ArrowDown" ? (u.preventDefault(), n.length && c((i + o) % n.length), true)
|
|
: u.key === "Enter" && !u.isComposing ? (u.stopPropagation(), u.preventDefault(), n.length && (r == null || r(n[i])), true)
|
|
: false
|
|
),
|
|
d = e2.domElement;
|
|
return (
|
|
d == null || d.addEventListener("keydown", a, true),
|
|
() => {
|
|
d == null || d.removeEventListener("keydown", a, true);
|
|
}
|
|
);
|
|
}, [e2.domElement, n, i, r, o, s]),
|
|
M$1(() => {
|
|
c(0);
|
|
}, [t]),
|
|
{
|
|
selectedIndex: n.length === 0 ? void 0 : i,
|
|
}
|
|
);
|
|
}
|
|
function Xr(e2) {
|
|
const n = q().setContentEditableProps,
|
|
o = v(),
|
|
{ getItems: r, gridSuggestionMenuComponent: i, query: c, clearQuery: s, closeMenu: a, onItemClick: d, columns: u } = e2,
|
|
m = H(
|
|
(C) => {
|
|
(a(), s(), d == null || d(C));
|
|
},
|
|
[d, a, s],
|
|
),
|
|
{ items: f, usedQuery: g, loadingState: h } = Yt(c, r);
|
|
Xt(f, g, a);
|
|
const { selectedIndex: b } = Kr(o, c, f, u, m);
|
|
return (
|
|
M$1(
|
|
() => (
|
|
n((C) => ({
|
|
...C,
|
|
"aria-expanded": true,
|
|
"aria-controls": "bn-suggestion-menu",
|
|
})),
|
|
() => {
|
|
n((C) => ({
|
|
...C,
|
|
"aria-expanded": false,
|
|
"aria-controls": void 0,
|
|
}));
|
|
}
|
|
),
|
|
[n],
|
|
),
|
|
M$1(
|
|
() => (
|
|
n((C) => ({
|
|
...C,
|
|
"aria-activedescendant": b ? "bn-suggestion-menu-item-" + b : void 0,
|
|
})),
|
|
() => {
|
|
n((C) => ({
|
|
...C,
|
|
"aria-activedescendant": void 0,
|
|
}));
|
|
}
|
|
),
|
|
[n, b],
|
|
),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(i, {
|
|
items: f,
|
|
onItemClick: m,
|
|
loadingState: h,
|
|
selectedIndex: b,
|
|
columns: u,
|
|
})
|
|
);
|
|
}
|
|
function Yr(e2) {
|
|
const t = v(),
|
|
{ triggerCharacter: n, gridSuggestionMenuComponent: o, columns: r, shouldOpen: i, minQueryLength: c, onItemClick: s, getItems: a } = e2,
|
|
d = V(
|
|
() =>
|
|
s ||
|
|
((b) => {
|
|
b.onItemClick(t);
|
|
}),
|
|
[t, s],
|
|
),
|
|
u = V(() => a || (async (b) => await Wr(t, b)), [t, a]),
|
|
m = _(Vn);
|
|
M$1(() => {
|
|
m.addSuggestionMenu({ triggerCharacter: n, shouldOpen: i });
|
|
}, [m, n, i]);
|
|
const f = B(Vn),
|
|
g = B(Vn, {
|
|
selector: (b) => {
|
|
var p;
|
|
return {
|
|
// Use first child as the editor DOM element may itself be scrollable.
|
|
// For FloatingUI to auto-update the position during scrolling, the
|
|
// `contextElement` must be a descendant of the scroll container.
|
|
element: ((p = t.domElement) == null ? void 0 : p.firstChild) || void 0,
|
|
getBoundingClientRect: () => (b == null ? void 0 : b.referencePos) || new DOMRect(),
|
|
};
|
|
},
|
|
}),
|
|
h = V(() => {
|
|
var b, p, C;
|
|
return {
|
|
...e2.floatingUIOptions,
|
|
useFloatingOptions: {
|
|
open: (f == null ? void 0 : f.show) && (f == null ? void 0 : f.triggerCharacter) === n,
|
|
onOpenChange: (x) => {
|
|
x || m.closeMenu();
|
|
},
|
|
placement: "bottom-start",
|
|
middleware: [
|
|
offset(10),
|
|
// Flips the menu placement to maximize the space available, and prevents
|
|
// the menu from being cut off by the confines of the screen.
|
|
autoPlacement({
|
|
allowedPlacements: ["bottom-start", "top-start"],
|
|
padding: 10,
|
|
}),
|
|
shift(),
|
|
size({
|
|
apply({ elements: x, availableHeight: O }) {
|
|
x.floating.style.maxHeight = `${Math.max(0, O)}px`;
|
|
},
|
|
padding: 10,
|
|
}),
|
|
],
|
|
...((b = e2.floatingUIOptions) == null ? void 0 : b.useFloatingOptions),
|
|
},
|
|
focusManagerProps: {
|
|
disabled: true,
|
|
...((p = e2.floatingUIOptions) == null ? void 0 : p.focusManagerProps),
|
|
},
|
|
elementProps: {
|
|
// Prevents editor blurring when clicking the scroll bar.
|
|
onMouseDownCapture: (x) => x.preventDefault(),
|
|
style: {
|
|
zIndex: 70,
|
|
},
|
|
...((C = e2.floatingUIOptions) == null ? void 0 : C.elementProps),
|
|
},
|
|
};
|
|
}, [e2.floatingUIOptions, f == null ? void 0 : f.show, f == null ? void 0 : f.triggerCharacter, m, n]);
|
|
return !f || (!f.ignoreQueryLength && c && (f.query.startsWith(" ") || f.query.length < c)) ?
|
|
null
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsx($$1, {
|
|
reference: g,
|
|
...h,
|
|
children:
|
|
n &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Xr, {
|
|
query: f.query,
|
|
closeMenu: m.closeMenu,
|
|
clearQuery: m.clearQuery,
|
|
getItems: u,
|
|
columns: r,
|
|
gridSuggestionMenuComponent: o || qr,
|
|
onItemClick: d,
|
|
}),
|
|
});
|
|
}
|
|
function Jr(e2) {
|
|
const t = w(),
|
|
n = S(),
|
|
{ items: o, loadingState: r, selectedIndex: i, onItemClick: c } = e2,
|
|
s =
|
|
r === "loading-initial" || r === "loading" ?
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.SuggestionMenu.Loader, {
|
|
className: "bn-suggestion-menu-loader",
|
|
})
|
|
: null,
|
|
a = V(() => {
|
|
let d;
|
|
const u = [];
|
|
for (let m = 0; m < o.length; m++) {
|
|
const f = o[m];
|
|
(f.group !== d &&
|
|
((d = f.group),
|
|
u.push(
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
t.SuggestionMenu.Label,
|
|
{
|
|
className: "bn-suggestion-menu-label",
|
|
children: d,
|
|
},
|
|
d,
|
|
),
|
|
)),
|
|
u.push(
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
t.SuggestionMenu.Item,
|
|
{
|
|
className: D("bn-suggestion-menu-item", f.size === "small" ? "bn-suggestion-menu-item-small" : ""),
|
|
item: f,
|
|
id: `bn-suggestion-menu-item-${m}`,
|
|
isSelected: m === i,
|
|
onClick: () => (c == null ? void 0 : c(f)),
|
|
},
|
|
f.title,
|
|
),
|
|
));
|
|
}
|
|
return u;
|
|
}, [t, o, c, i]);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(t.SuggestionMenu.Root, {
|
|
id: "bn-suggestion-menu",
|
|
className: "bn-suggestion-menu",
|
|
children: [
|
|
a,
|
|
a.length === 0 &&
|
|
(e2.loadingState === "loading" || e2.loadingState === "loaded") &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.SuggestionMenu.EmptyItem, {
|
|
className: "bn-suggestion-menu-item",
|
|
children: n.suggestion_menu.no_items_title,
|
|
}),
|
|
s,
|
|
],
|
|
});
|
|
}
|
|
function Qr(e2, t) {
|
|
const [n, o] = T(0);
|
|
return {
|
|
selectedIndex: n,
|
|
setSelectedIndex: o,
|
|
handler: (r) => {
|
|
if (r.key === "ArrowUp") return (r.preventDefault(), e2.length && o((n - 1 + e2.length) % e2.length), true);
|
|
if (r.key === "ArrowDown") return (r.preventDefault(), e2.length && o((n + 1) % e2.length), true);
|
|
if (r.key === "PageUp") return (r.preventDefault(), e2.length && o(0), true);
|
|
if (r.key === "PageDown") return (r.preventDefault(), e2.length && o(e2.length - 1), true);
|
|
const i = ei(r) ? r.nativeEvent.isComposing : r.isComposing;
|
|
return r.key === "Enter" && !i ? (r.preventDefault(), r.stopPropagation(), e2.length && (t == null || t(e2[n])), true) : false;
|
|
},
|
|
};
|
|
}
|
|
function ei(e2) {
|
|
return e2.nativeEvent !== void 0;
|
|
}
|
|
function ti(e2, t, n, o, r) {
|
|
const { selectedIndex: i, setSelectedIndex: c, handler: s } = Qr(n, o);
|
|
return (
|
|
M$1(() => {
|
|
const a = e2.domElement;
|
|
return (
|
|
a == null || a.addEventListener("keydown", s, true),
|
|
() => {
|
|
a == null || a.removeEventListener("keydown", s, true);
|
|
}
|
|
);
|
|
}, [e2.domElement, n, i, o, r, s]),
|
|
M$1(() => {
|
|
c(0);
|
|
}, [t, c]),
|
|
{
|
|
selectedIndex: n.length === 0 ? void 0 : i,
|
|
}
|
|
);
|
|
}
|
|
function ni(e2) {
|
|
const n = q().setContentEditableProps,
|
|
o = v(),
|
|
{ getItems: r, suggestionMenuComponent: i, query: c, clearQuery: s, closeMenu: a, onItemClick: d } = e2,
|
|
u = H(
|
|
(p) => {
|
|
(a(), s(), d == null || d(p));
|
|
},
|
|
[d, a, s],
|
|
),
|
|
{ items: m, usedQuery: f, loadingState: g } = Yt(c, r);
|
|
Xt(m, f, a);
|
|
const { selectedIndex: h } = ti(o, c, m, u);
|
|
return (
|
|
M$1(
|
|
() => (
|
|
n((p) => ({
|
|
...p,
|
|
"aria-expanded": true,
|
|
"aria-controls": "bn-suggestion-menu",
|
|
})),
|
|
() => {
|
|
n((p) => ({
|
|
...p,
|
|
"aria-expanded": false,
|
|
"aria-controls": void 0,
|
|
}));
|
|
}
|
|
),
|
|
[n],
|
|
),
|
|
M$1(
|
|
() => (
|
|
n((p) => ({
|
|
...p,
|
|
"aria-activedescendant": h ? "bn-suggestion-menu-item-" + h : void 0,
|
|
})),
|
|
() => {
|
|
n((p) => ({
|
|
...p,
|
|
"aria-activedescendant": void 0,
|
|
}));
|
|
}
|
|
),
|
|
[n, h],
|
|
),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(i, {
|
|
items: m,
|
|
onItemClick: u,
|
|
loadingState: g,
|
|
selectedIndex: h,
|
|
})
|
|
);
|
|
}
|
|
const oi = {
|
|
heading: pe,
|
|
heading_2: Ce$1,
|
|
heading_3: ve$1,
|
|
heading_4: Pt$1,
|
|
heading_5: Nt$1,
|
|
heading_6: At$1,
|
|
toggle_heading: pe,
|
|
toggle_heading_2: Ce$1,
|
|
toggle_heading_3: ve$1,
|
|
quote: Gt$1,
|
|
toggle_list: jt$1,
|
|
numbered_list: Ft$1,
|
|
bullet_list: Ut,
|
|
check_list: Zt,
|
|
paragraph: je$1,
|
|
table: $o,
|
|
image: zt$1,
|
|
video: qo,
|
|
audio: $t$1,
|
|
file: ze$1,
|
|
emoji: lr,
|
|
code_block: Ao,
|
|
divider: ir,
|
|
};
|
|
function ri(e2) {
|
|
return Ao$2(e2).map((t) => {
|
|
const n = oi[t.key];
|
|
return {
|
|
...t,
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(n, { size: 18 }),
|
|
};
|
|
});
|
|
}
|
|
function ii(e2) {
|
|
const t = v(),
|
|
{ triggerCharacter: n, suggestionMenuComponent: o, shouldOpen: r, minQueryLength: i, onItemClick: c, getItems: s } = e2,
|
|
a = V(
|
|
() =>
|
|
c ||
|
|
((h) => {
|
|
h.onItemClick(t);
|
|
}),
|
|
[t, c],
|
|
),
|
|
d = V(() => s || (async (h) => No$2(ri(t), h)), [t, s]),
|
|
u = _(Vn);
|
|
M$1(() => {
|
|
u.addSuggestionMenu({ triggerCharacter: n, shouldOpen: r });
|
|
}, [u, n, r]);
|
|
const m = B(Vn),
|
|
f = B(Vn, {
|
|
selector: (h) => {
|
|
var b;
|
|
return {
|
|
// Use first child as the editor DOM element may itself be scrollable.
|
|
// For FloatingUI to auto-update the position during scrolling, the
|
|
// `contextElement` must be a descendant of the scroll container.
|
|
element: ((b = t.domElement) == null ? void 0 : b.firstChild) || void 0,
|
|
getBoundingClientRect: () => (h == null ? void 0 : h.referencePos) || new DOMRect(),
|
|
};
|
|
},
|
|
}),
|
|
g = V(() => {
|
|
var h, b, p;
|
|
return {
|
|
...e2.floatingUIOptions,
|
|
useFloatingOptions: {
|
|
open: (m == null ? void 0 : m.show) && (m == null ? void 0 : m.triggerCharacter) === n,
|
|
onOpenChange: (C) => {
|
|
C || u.closeMenu();
|
|
},
|
|
placement: "bottom-start",
|
|
middleware: [
|
|
offset(10),
|
|
// Flips the menu placement to maximize the space available, and prevents
|
|
// the menu from being cut off by the confines of the screen.
|
|
autoPlacement({
|
|
allowedPlacements: ["bottom-start", "top-start"],
|
|
padding: 10,
|
|
}),
|
|
shift(),
|
|
size({
|
|
apply({ elements: C, availableHeight: x }) {
|
|
C.floating.style.maxHeight = `${Math.max(0, x)}px`;
|
|
},
|
|
padding: 10,
|
|
}),
|
|
],
|
|
...((h = e2.floatingUIOptions) == null ? void 0 : h.useFloatingOptions),
|
|
},
|
|
focusManagerProps: {
|
|
disabled: true,
|
|
...((b = e2.floatingUIOptions) == null ? void 0 : b.focusManagerProps),
|
|
},
|
|
elementProps: {
|
|
// Prevents editor blurring when clicking the scroll bar.
|
|
onMouseDownCapture: (C) => C.preventDefault(),
|
|
style: {
|
|
zIndex: 80,
|
|
},
|
|
...((p = e2.floatingUIOptions) == null ? void 0 : p.elementProps),
|
|
},
|
|
};
|
|
}, [e2.floatingUIOptions, m == null ? void 0 : m.show, m == null ? void 0 : m.triggerCharacter, u, n]);
|
|
return !m || (!m.ignoreQueryLength && i && (m.query.startsWith(" ") || m.query.length < i)) ?
|
|
null
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsx($$1, {
|
|
reference: f,
|
|
...g,
|
|
children:
|
|
n &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ni, {
|
|
query: m.query,
|
|
closeMenu: u.closeMenu,
|
|
clearQuery: u.clearQuery,
|
|
getItems: d,
|
|
suggestionMenuComponent: o || Jr,
|
|
onItemClick: a,
|
|
}),
|
|
});
|
|
}
|
|
const li = (e2, t = 0.3) => {
|
|
const n = Math.floor(e2) + t,
|
|
o = Math.ceil(e2) - t;
|
|
return (
|
|
e2 >= n && e2 <= o ? Math.round(e2)
|
|
: e2 < n ? Math.floor(e2)
|
|
: Math.ceil(e2)
|
|
);
|
|
},
|
|
ci = (e2) => {
|
|
const t = w(),
|
|
n = v(),
|
|
o = _(Yo),
|
|
r = B(Yo, {
|
|
selector: (u) => (u == null ? void 0 : u.block),
|
|
}),
|
|
i = F$1(false),
|
|
[c, s] = T(),
|
|
a = H(
|
|
(u) => {
|
|
(o.freezeHandles(),
|
|
e2.hideOtherElements(true),
|
|
r &&
|
|
(s({
|
|
originalContent: r.content,
|
|
originalCroppedContent: {
|
|
rows: o.cropEmptyRowsOrColumns(r, e2.orientation === "addOrRemoveColumns" ? "columns" : "rows"),
|
|
},
|
|
startPos: e2.orientation === "addOrRemoveColumns" ? u.clientX : u.clientY,
|
|
}),
|
|
(i.current = false),
|
|
u.preventDefault()));
|
|
},
|
|
[r, e2, o],
|
|
),
|
|
d = H(() => {
|
|
!r ||
|
|
i.current ||
|
|
n.updateBlock(r, {
|
|
type: "table",
|
|
content: {
|
|
...r.content,
|
|
rows: e2.orientation === "addOrRemoveColumns" ? o.addRowsOrColumns(r, "columns", 1) : o.addRowsOrColumns(r, "rows", 1),
|
|
},
|
|
});
|
|
}, [r, n, e2.orientation, o]);
|
|
return (
|
|
M$1(() => {
|
|
const u = (m) => {
|
|
var C, x;
|
|
if (!r) return;
|
|
if (!c) throw new Error("editingState is undefined");
|
|
i.current = true;
|
|
const f = (e2.orientation === "addOrRemoveColumns" ? m.clientX : m.clientY) - c.startPos,
|
|
g = e2.orientation === "addOrRemoveColumns" ? (((C = c.originalCroppedContent.rows[0]) == null ? void 0 : C.cells.length) ?? 0) : c.originalCroppedContent.rows.length,
|
|
h = e2.orientation === "addOrRemoveColumns" ? (((x = c.originalContent.rows[0]) == null ? void 0 : x.cells.length) ?? 0) : c.originalContent.rows.length,
|
|
b = e2.orientation === "addOrRemoveColumns" ? r.content.rows[0].cells.length : r.content.rows.length,
|
|
p = h + li(f / (e2.orientation === "addOrRemoveColumns" ? Oe$1 : Lo$1), 0.3);
|
|
p >= g &&
|
|
p > 0 &&
|
|
p !== b &&
|
|
(n.updateBlock(r, {
|
|
type: "table",
|
|
content: {
|
|
...r.content,
|
|
rows:
|
|
e2.orientation === "addOrRemoveColumns" ?
|
|
o.addRowsOrColumns(
|
|
{
|
|
type: "table",
|
|
content: c.originalCroppedContent,
|
|
},
|
|
"columns",
|
|
p - g,
|
|
)
|
|
: o.addRowsOrColumns(
|
|
{
|
|
type: "table",
|
|
content: c.originalCroppedContent,
|
|
},
|
|
"rows",
|
|
p - g,
|
|
),
|
|
},
|
|
}),
|
|
r.content && n.setTextCursorPosition(r));
|
|
};
|
|
return (
|
|
c && window.addEventListener("mousemove", u),
|
|
() => {
|
|
window.removeEventListener("mousemove", u);
|
|
}
|
|
);
|
|
}, [r, c, n, e2.orientation, o]),
|
|
M$1(() => {
|
|
const u = () => {
|
|
(e2.hideOtherElements(false), o.unfreezeHandles(), s(void 0));
|
|
};
|
|
return (
|
|
c && window.addEventListener("mouseup", u),
|
|
() => {
|
|
window.removeEventListener("mouseup", u);
|
|
}
|
|
);
|
|
}, [c, e2, o]),
|
|
n.isEditable ?
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.TableHandle.ExtendButton, {
|
|
className: D(
|
|
"bn-extend-button",
|
|
e2.orientation === "addOrRemoveColumns" ? "bn-extend-button-add-remove-columns" : "bn-extend-button-add-remove-rows",
|
|
c !== null ? "bn-extend-button-editing" : "",
|
|
),
|
|
onClick: d,
|
|
onMouseDown: a,
|
|
children: e2.children || /* @__PURE__ */ jsxRuntimeExports.jsx(Jo, { "size": 18, "data-test": "extendButton" }),
|
|
})
|
|
: null
|
|
);
|
|
},
|
|
ai = (e2) => {
|
|
var d, u;
|
|
const t = w(),
|
|
n = S(),
|
|
o = v(),
|
|
{
|
|
block: r,
|
|
colIndex: i,
|
|
rowIndex: c,
|
|
} = B(Yo, {
|
|
selector: (m) => ({
|
|
block: m == null ? void 0 : m.block,
|
|
colIndex: m == null ? void 0 : m.colIndex,
|
|
rowIndex: m == null ? void 0 : m.rowIndex,
|
|
}),
|
|
}),
|
|
s = (m, f) => {
|
|
if (r === void 0 || i === void 0 || c === void 0) return;
|
|
const g = r.content.rows.map((h) => ({
|
|
...h,
|
|
cells: h.cells.map((b) => S$1(b)),
|
|
}));
|
|
(f === "text" ? (g[c].cells[i].props.textColor = m) : (g[c].cells[i].props.backgroundColor = m),
|
|
o.updateBlock(r, {
|
|
type: "table",
|
|
content: {
|
|
...r.content,
|
|
rows: g,
|
|
},
|
|
}),
|
|
o.setTextCursorPosition(r));
|
|
};
|
|
if (r === void 0 || i === void 0 || c === void 0) return null;
|
|
const a = (u = (d = r.content.rows[c]) == null ? void 0 : d.cells) == null ? void 0 : u[i];
|
|
return !a || (o.settings.tables.cellTextColor === false && o.settings.tables.cellBackgroundColor === false) ?
|
|
null
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsxs(t.Generic.Menu.Root, {
|
|
position: "right",
|
|
sub: true,
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Trigger, {
|
|
sub: true,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Item, {
|
|
className: "bn-menu-item",
|
|
subTrigger: true,
|
|
children: e2.children || n.drag_handle.colors_menuitem,
|
|
}),
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Dropdown, {
|
|
sub: true,
|
|
className: "bn-menu-dropdown bn-color-picker-dropdown",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(xe$1, {
|
|
iconSize: 18,
|
|
text:
|
|
o.settings.tables.cellTextColor ?
|
|
{
|
|
color: R$1(a) ? a.props.textColor : "default",
|
|
setColor: (m) => s(m, "text"),
|
|
}
|
|
: void 0,
|
|
background:
|
|
o.settings.tables.cellBackgroundColor ?
|
|
{
|
|
color: R$1(a) ? a.props.backgroundColor : "default",
|
|
setColor: (m) => s(m, "background"),
|
|
}
|
|
: void 0,
|
|
}),
|
|
}),
|
|
],
|
|
});
|
|
},
|
|
si = () => {
|
|
var a, d;
|
|
const e2 = w(),
|
|
t = S(),
|
|
n = v(),
|
|
o = _(Yo),
|
|
{
|
|
block: r,
|
|
colIndex: i,
|
|
rowIndex: c,
|
|
} = B(Yo, {
|
|
selector: (u) => ({
|
|
block: u == null ? void 0 : u.block,
|
|
colIndex: u == null ? void 0 : u.colIndex,
|
|
rowIndex: u == null ? void 0 : u.rowIndex,
|
|
}),
|
|
});
|
|
if (r === void 0 || i === void 0 || c === void 0) return null;
|
|
const s = (d = (a = r.content.rows[c]) == null ? void 0 : a.cells) == null ? void 0 : d[i];
|
|
return !s || !R$1(s) || (D$1(s) === 1 && A$1(s) === 1) || !n.settings.tables.splitCells ?
|
|
null
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsx(e2.Generic.Menu.Item, {
|
|
onClick: () => {
|
|
o.splitCell({
|
|
row: c,
|
|
col: i,
|
|
});
|
|
},
|
|
children: t.table_handle.split_cell_menuitem,
|
|
});
|
|
},
|
|
di = (e2) => {
|
|
const t = w();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Dropdown, {
|
|
className: "bn-menu-dropdown bn-table-handle-menu",
|
|
children:
|
|
e2.children ||
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [/* @__PURE__ */ jsxRuntimeExports.jsx(si, {}), /* @__PURE__ */ jsxRuntimeExports.jsx(ai, {})] }),
|
|
});
|
|
},
|
|
ui = (e2) => {
|
|
const t = w(),
|
|
n = v(),
|
|
o = _(Yo),
|
|
r = e2.tableCellMenu || di;
|
|
return !n.settings.tables.splitCells && !n.settings.tables.cellBackgroundColor && !n.settings.tables.cellTextColor ?
|
|
null
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsxs(t.Generic.Menu.Root, {
|
|
onOpenChange: (i) => {
|
|
i ? (o.freezeHandles(), e2.hideOtherElements(true)) : (o.unfreezeHandles(), e2.hideOtherElements(false), n.focus());
|
|
},
|
|
position: "right",
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Trigger, {
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Button, {
|
|
className: "bn-table-cell-handle",
|
|
children: e2.children || /* @__PURE__ */ jsxRuntimeExports.jsx(Ar, { "size": 12, "data-test": "tableCellHandle" }),
|
|
}),
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(r, {}),
|
|
],
|
|
});
|
|
},
|
|
ft$1 = (e2) => {
|
|
const t = w(),
|
|
n = S(),
|
|
o = _(Yo),
|
|
r = B(Yo, {
|
|
selector: (i) =>
|
|
e2.orientation === "column" ?
|
|
i == null ?
|
|
void 0
|
|
: i.colIndex
|
|
: i == null ? void 0
|
|
: i.rowIndex,
|
|
});
|
|
return o === void 0 || r === void 0 ?
|
|
null
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Item, {
|
|
onClick: () => {
|
|
o.addRowOrColumn(r, e2.orientation === "row" ? { orientation: "row", side: e2.side } : { orientation: "column", side: e2.side });
|
|
},
|
|
children: n.table_handle[`add_${e2.side}_menuitem`],
|
|
});
|
|
},
|
|
mi = (e2) => {
|
|
const t = w(),
|
|
n = S(),
|
|
o = _(Yo),
|
|
r = B(Yo, {
|
|
selector: (i) =>
|
|
e2.orientation === "column" ?
|
|
i == null ?
|
|
void 0
|
|
: i.colIndex
|
|
: i == null ? void 0
|
|
: i.rowIndex,
|
|
});
|
|
return o === void 0 || r === void 0 ?
|
|
null
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Item, {
|
|
onClick: () => o.removeRowOrColumn(r, e2.orientation),
|
|
children: e2.orientation === "row" ? n.table_handle.delete_row_menuitem : n.table_handle.delete_column_menuitem,
|
|
});
|
|
},
|
|
fi = (e2) => {
|
|
const t = w(),
|
|
n = S(),
|
|
o = v(),
|
|
r = _(Yo),
|
|
{ block: i, index: c } = B(Yo, {
|
|
selector: (u) => ({
|
|
block: u == null ? void 0 : u.block,
|
|
index:
|
|
e2.orientation === "column" ?
|
|
u == null ?
|
|
void 0
|
|
: u.colIndex
|
|
: u == null ? void 0
|
|
: u.rowIndex,
|
|
}),
|
|
}),
|
|
s = V(
|
|
() =>
|
|
r === void 0 || i === void 0 || c === void 0 ? []
|
|
: e2.orientation === "row" ? r.getCellsAtRowHandle(i, c)
|
|
: r.getCellsAtColumnHandle(i, c),
|
|
[i, c, e2.orientation, r],
|
|
),
|
|
a = (u, m) => {
|
|
if (i === void 0) return;
|
|
const f = i.content.rows.map((g) => ({
|
|
...g,
|
|
cells: g.cells.map((h) => S$1(h)),
|
|
}));
|
|
(s.forEach(({ row: g, col: h }) => {
|
|
m === "text" ? (f[g].cells[h].props.textColor = u) : (f[g].cells[h].props.backgroundColor = u);
|
|
}),
|
|
o.updateBlock(i, {
|
|
type: "table",
|
|
content: {
|
|
...i.content,
|
|
rows: f,
|
|
},
|
|
}),
|
|
o.setTextCursorPosition(i));
|
|
};
|
|
if (!s || !s[0] || !r || (o.settings.tables.cellTextColor === false && o.settings.tables.cellBackgroundColor === false)) return null;
|
|
const d = S$1(s[0].cell);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(t.Generic.Menu.Root, {
|
|
position: "right",
|
|
sub: true,
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Trigger, {
|
|
sub: true,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Item, {
|
|
className: "bn-menu-item",
|
|
subTrigger: true,
|
|
children: e2.children || n.drag_handle.colors_menuitem,
|
|
}),
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Dropdown, {
|
|
sub: true,
|
|
className: "bn-menu-dropdown bn-color-picker-dropdown",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(xe$1, {
|
|
iconSize: 18,
|
|
text:
|
|
o.settings.tables.cellTextColor ?
|
|
{
|
|
// All cells have the same text color
|
|
color: s.every(({ cell: u }) => R$1(u) && u.props.textColor === d.props.textColor) ? d.props.textColor : "default",
|
|
setColor: (u) => {
|
|
a(u, "text");
|
|
},
|
|
}
|
|
: void 0,
|
|
background:
|
|
o.settings.tables.cellBackgroundColor ?
|
|
{
|
|
color: s.every(({ cell: u }) => R$1(u) && u.props.backgroundColor === d.props.backgroundColor) ? d.props.backgroundColor : "default",
|
|
setColor: (u) => a(u, "background"),
|
|
}
|
|
: void 0,
|
|
}),
|
|
}),
|
|
],
|
|
});
|
|
},
|
|
gi = (e2) => {
|
|
const t = w(),
|
|
n = S(),
|
|
o = v(),
|
|
r = _(Yo),
|
|
{ block: i, index: c } = B(Yo, {
|
|
selector: (a) => ({
|
|
block: a == null ? void 0 : a.block,
|
|
index:
|
|
e2.orientation === "column" ?
|
|
a == null ?
|
|
void 0
|
|
: a.colIndex
|
|
: a == null ? void 0
|
|
: a.rowIndex,
|
|
}),
|
|
});
|
|
if (r === void 0 || i === void 0 || c !== 0 || e2.orientation !== "row" || !o.settings.tables.headers) return null;
|
|
const s = !!i.content.headerRows;
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Item, {
|
|
className: "bn-menu-item",
|
|
checked: s,
|
|
onClick: () => {
|
|
o.updateBlock(i, {
|
|
...i,
|
|
content: {
|
|
...i.content,
|
|
headerRows: s ? void 0 : 1,
|
|
},
|
|
});
|
|
},
|
|
children: n.drag_handle.header_row_menuitem,
|
|
});
|
|
},
|
|
hi = (e2) => {
|
|
const t = w(),
|
|
n = S(),
|
|
o = v(),
|
|
r = _(Yo),
|
|
i = B(Yo, {
|
|
selector: (a) => (a == null ? void 0 : a.block),
|
|
}),
|
|
c = B(Yo, {
|
|
selector: (a) =>
|
|
e2.orientation === "column" ?
|
|
a == null ?
|
|
void 0
|
|
: a.colIndex
|
|
: a == null ? void 0
|
|
: a.rowIndex,
|
|
});
|
|
if (!r || c !== 0 || !i || e2.orientation !== "column" || !o.settings.tables.headers) return null;
|
|
const s = !!i.content.headerCols;
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Item, {
|
|
className: "bn-menu-item",
|
|
checked: s,
|
|
onClick: () => {
|
|
o.updateBlock(i, {
|
|
...i,
|
|
content: {
|
|
...i.content,
|
|
headerCols: s ? void 0 : 1,
|
|
},
|
|
});
|
|
},
|
|
children: n.drag_handle.header_column_menuitem,
|
|
});
|
|
},
|
|
bi = (e2) => {
|
|
const t = w();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Menu.Dropdown, {
|
|
className: "bn-table-handle-menu",
|
|
children:
|
|
e2.children ||
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(mi, { orientation: e2.orientation }),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ft$1, {
|
|
orientation: e2.orientation,
|
|
side: e2.orientation === "row" ? "above" : "left",
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ft$1, {
|
|
orientation: e2.orientation,
|
|
side: e2.orientation === "row" ? "below" : "right",
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(gi, { orientation: e2.orientation }),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(hi, { orientation: e2.orientation }),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(fi, { orientation: e2.orientation }),
|
|
],
|
|
}),
|
|
});
|
|
},
|
|
pi = (e2) => {
|
|
const t = v(),
|
|
n = w(),
|
|
[o, r] = T(false),
|
|
i = e2.tableHandleMenu || bi,
|
|
c = _(Yo),
|
|
s = B(Yo),
|
|
a = V(
|
|
() =>
|
|
!c || !s || !s.block || s.block.type !== "table" ? false
|
|
: e2.orientation === "column" ? c.getCellsAtColumnHandle(s.block, s.colIndex).every(({ cell: d }) => A$1(d) === 1)
|
|
: c.getCellsAtRowHandle(s.block, s.rowIndex).every(({ cell: d }) => D$1(d) === 1),
|
|
[e2.orientation, s, c],
|
|
);
|
|
return s ?
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(n.Generic.Menu.Root, {
|
|
onOpenChange: (d) => {
|
|
d ? (c.freezeHandles(), e2.hideOtherElements(true)) : (c.unfreezeHandles(), e2.hideOtherElements(false), t.focus());
|
|
},
|
|
position: "right",
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(n.Generic.Menu.Trigger, {
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(n.TableHandle.Root, {
|
|
className: D("bn-table-handle", o ? "bn-table-handle-dragging" : "", a ? "" : "bn-table-handle-not-draggable"),
|
|
draggable: a,
|
|
onDragStart: (d) => {
|
|
(r(true), e2.hideOtherElements(true), e2.orientation === "column" ? c.colDragStart(d) : c.rowDragStart(d));
|
|
},
|
|
onDragEnd: () => {
|
|
(c.dragEnd(), e2.hideOtherElements(false), r(false));
|
|
},
|
|
style: e2.orientation === "column" ? { transform: "rotate(0.25turn)" } : void 0,
|
|
children: e2.children || /* @__PURE__ */ jsxRuntimeExports.jsx(Kt, { "size": 24, "data-test": "tableHandle" }),
|
|
}),
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(i, { orientation: e2.orientation }),
|
|
],
|
|
})
|
|
: null;
|
|
},
|
|
Ci = (e2) => {
|
|
const t = v(),
|
|
[n, o] = T(),
|
|
r = B(Yo),
|
|
i = V(() => {
|
|
const u = {};
|
|
if (r === void 0) return {};
|
|
const m = Bt$2(r.block.id, t.prosemirrorState.doc);
|
|
if (!m) return {};
|
|
const f = m.posBeforeNode + 1,
|
|
g = t.prosemirrorView.domAtPos(f + 1).node;
|
|
if (!(g instanceof Element)) return {};
|
|
if (((u.tableReference = { element: g }), r.rowIndex === void 0 || r.colIndex === void 0)) return u;
|
|
const h = t.prosemirrorState.doc.resolve(f + 1).posAtIndex(r.rowIndex),
|
|
b = t.prosemirrorState.doc.resolve(h + 1).posAtIndex(r.colIndex),
|
|
p = t.prosemirrorView.domAtPos(b + 1).node;
|
|
return p instanceof Element ?
|
|
((u.cellReference = { element: p }),
|
|
(u.rowReference = {
|
|
element: g,
|
|
getBoundingClientRect: () => {
|
|
const C = g.getBoundingClientRect(),
|
|
x = p.getBoundingClientRect();
|
|
return new DOMRect(C.x, r.draggingState && r.draggingState.draggedCellOrientation === "row" ? r.draggingState.mousePos - x.height / 2 : x.y, C.width, x.height);
|
|
},
|
|
}),
|
|
(u.columnReference = {
|
|
element: g,
|
|
getBoundingClientRect: () => {
|
|
const C = g.getBoundingClientRect(),
|
|
x = p.getBoundingClientRect();
|
|
return new DOMRect(r.draggingState && r.draggingState.draggedCellOrientation === "col" ? r.draggingState.mousePos - x.width / 2 : x.x, C.y, x.width, C.height);
|
|
},
|
|
}),
|
|
u)
|
|
: {};
|
|
}, [t, r]),
|
|
c = V(
|
|
() =>
|
|
r !== void 0 ?
|
|
{
|
|
rowTableHandle: {
|
|
useFloatingOptions: {
|
|
open: r.show && r.rowIndex !== void 0 && (!n || n === "rowTableHandle"),
|
|
placement: "left",
|
|
middleware: [offset(-10)],
|
|
},
|
|
focusManagerProps: {
|
|
disabled: true,
|
|
},
|
|
elementProps: {
|
|
style: {
|
|
zIndex: 10,
|
|
},
|
|
},
|
|
},
|
|
columnTableHandle: {
|
|
useFloatingOptions: {
|
|
open: r.show && r.colIndex !== void 0 && (!n || n === "columnTableHandle"),
|
|
placement: "top",
|
|
middleware: [offset(-12)],
|
|
},
|
|
focusManagerProps: {
|
|
disabled: true,
|
|
},
|
|
elementProps: {
|
|
style: {
|
|
zIndex: 10,
|
|
},
|
|
},
|
|
},
|
|
tableCellHandle: {
|
|
useFloatingOptions: {
|
|
open: r.show && r.rowIndex !== void 0 && r.colIndex !== void 0 && (!n || n === "tableCellHandle"),
|
|
placement: "top-end",
|
|
middleware: [offset({ mainAxis: -15, crossAxis: -1 })],
|
|
},
|
|
focusManagerProps: {
|
|
disabled: true,
|
|
},
|
|
elementProps: {
|
|
style: {
|
|
zIndex: 10,
|
|
},
|
|
},
|
|
},
|
|
extendRowsButton: {
|
|
useFloatingOptions: {
|
|
open: r.show && r.showAddOrRemoveRowsButton && (!n || n === "extendRowsButton"),
|
|
placement: "bottom",
|
|
middleware: [
|
|
size({
|
|
apply({ rects: u, elements: m }) {
|
|
Object.assign(m.floating.style, {
|
|
width: `${u.reference.width}px`,
|
|
});
|
|
},
|
|
}),
|
|
],
|
|
},
|
|
focusManagerProps: {
|
|
disabled: true,
|
|
},
|
|
elementProps: {
|
|
style: {
|
|
zIndex: 10,
|
|
},
|
|
},
|
|
},
|
|
extendColumnsButton: {
|
|
useFloatingOptions: {
|
|
open: r.show && r.showAddOrRemoveColumnsButton && (!n || n === "extendColumnsButton"),
|
|
placement: "right",
|
|
middleware: [
|
|
size({
|
|
apply({ rects: u, elements: m }) {
|
|
Object.assign(m.floating.style, {
|
|
height: `${u.reference.height}px`,
|
|
});
|
|
},
|
|
}),
|
|
],
|
|
},
|
|
focusManagerProps: {
|
|
disabled: true,
|
|
},
|
|
elementProps: {
|
|
style: {
|
|
zIndex: 10,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
: void 0,
|
|
[n, r],
|
|
);
|
|
if (!r) return null;
|
|
const s = e2.tableHandle || pi,
|
|
a = e2.extendButton || ci,
|
|
d = e2.tableCellHandle || ui;
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx($$1, {
|
|
reference: i == null ? void 0 : i.rowReference,
|
|
...(c == null ? void 0 : c.rowTableHandle),
|
|
children:
|
|
r.show &&
|
|
r.rowIndex !== void 0 &&
|
|
(!n || n === "rowTableHandle") &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(s, {
|
|
orientation: "row",
|
|
hideOtherElements: (u) => o(u ? "rowTableHandle" : void 0),
|
|
}),
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx($$1, {
|
|
reference: i == null ? void 0 : i.columnReference,
|
|
...(c == null ? void 0 : c.columnTableHandle),
|
|
children:
|
|
r.show &&
|
|
r.colIndex !== void 0 &&
|
|
(!n || n === "columnTableHandle") &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(s, {
|
|
orientation: "column",
|
|
hideOtherElements: (u) => o(u ? "columnTableHandle" : void 0),
|
|
}),
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx($$1, {
|
|
reference: i == null ? void 0 : i.cellReference,
|
|
...(c == null ? void 0 : c.tableCellHandle),
|
|
children:
|
|
r.show &&
|
|
r.rowIndex !== void 0 &&
|
|
r.colIndex !== void 0 &&
|
|
(!n || n === "tableCellHandle") &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(d, {
|
|
hideOtherElements: (u) => o(u ? "tableCellHandle" : void 0),
|
|
}),
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx($$1, {
|
|
reference: i == null ? void 0 : i.tableReference,
|
|
...(c == null ? void 0 : c.extendRowsButton),
|
|
children:
|
|
r.show &&
|
|
r.showAddOrRemoveRowsButton &&
|
|
(!n || n === "extendRowsButton") &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(a, {
|
|
orientation: "addOrRemoveRows",
|
|
hideOtherElements: (u) => o(u ? "extendRowsButton" : void 0),
|
|
}),
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx($$1, {
|
|
reference: i == null ? void 0 : i.tableReference,
|
|
...(c == null ? void 0 : c.extendColumnsButton),
|
|
children:
|
|
r.show &&
|
|
r.showAddOrRemoveColumnsButton &&
|
|
(!n || n === "extendColumnsButton") &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(a, {
|
|
orientation: "addOrRemoveColumns",
|
|
hideOtherElements: (u) => o(u ? "extendColumnsButton" : void 0),
|
|
}),
|
|
}),
|
|
],
|
|
});
|
|
},
|
|
vi = Ct$1(() => Promise.resolve().then(() => cl)),
|
|
wi = Ct$1(() => Promise.resolve().then(() => sl));
|
|
function ki(e2) {
|
|
const t = v();
|
|
if (!t) throw new Error("BlockNoteDefaultUI must be used within a BlockNoteContext.Provider");
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
|
|
children: [
|
|
t.getExtension(Ao$1) && e2.formattingToolbar !== false && /* @__PURE__ */ jsxRuntimeExports.jsx(Br, {}),
|
|
t.getExtension(No$1) && e2.linkToolbar !== false && /* @__PURE__ */ jsxRuntimeExports.jsx(Ir, {}),
|
|
t.getExtension(Vn) &&
|
|
e2.slashMenu !== false &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ii, {
|
|
triggerCharacter: "/",
|
|
shouldOpen: (n) => !n.selection.$from.parent.type.isInGroup("tableContent"),
|
|
}),
|
|
t.getExtension(Vn) &&
|
|
e2.emojiPicker !== false &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Yr, {
|
|
triggerCharacter: ":",
|
|
columns: 10,
|
|
minQueryLength: 2,
|
|
}),
|
|
t.getExtension(_o$1) && e2.sideMenu !== false && /* @__PURE__ */ jsxRuntimeExports.jsx($r, {}),
|
|
t.getExtension(H$1) && e2.filePanel !== false && /* @__PURE__ */ jsxRuntimeExports.jsx(mo, {}),
|
|
t.getExtension(Yo) && e2.tableHandles !== false && /* @__PURE__ */ jsxRuntimeExports.jsx(Ci, {}),
|
|
t.getExtension(ne$1) &&
|
|
e2.comments !== false &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(dn, { children: [/* @__PURE__ */ jsxRuntimeExports.jsx(vi, {}), /* @__PURE__ */ jsxRuntimeExports.jsx(wi, {})] }),
|
|
],
|
|
});
|
|
}
|
|
function Hi(e2, t) {
|
|
const n = q();
|
|
(t || (t = n == null ? void 0 : n.editor),
|
|
M$1(() => {
|
|
if (!t) throw new Error("'editor' is required, either from BlockNoteContext or as a function argument");
|
|
return t.onChange(e2);
|
|
}, [e2, t]));
|
|
}
|
|
function xi(e2, t, n) {
|
|
const o = q();
|
|
(t || (t = o == null ? void 0 : o.editor),
|
|
M$1(() => {
|
|
if (!t) throw new Error("'editor' is required, either from BlockNoteContext or as a function argument");
|
|
return t.onSelectionChange(e2, n);
|
|
}, [e2, t, n]));
|
|
}
|
|
const yi = () => {
|
|
const e2 = V(() => {
|
|
var c;
|
|
return (c = window.matchMedia) == null ? void 0 : c.call(window, "(prefers-color-scheme: dark)");
|
|
}, []),
|
|
t = V(() => {
|
|
var c;
|
|
return (c = window.matchMedia) == null ? void 0 : c.call(window, "(prefers-color-scheme: light)");
|
|
}, []),
|
|
n = e2 == null ? void 0 : e2.matches,
|
|
o = t == null ? void 0 : t.matches,
|
|
[r, i] = T(
|
|
n ? "dark"
|
|
: o ? "light"
|
|
: "no-preference",
|
|
);
|
|
return (
|
|
M$1(() => {
|
|
i(
|
|
n ? "dark"
|
|
: o ? "light"
|
|
: "no-preference",
|
|
);
|
|
}, [n, o]),
|
|
M$1(() => {
|
|
if (typeof (e2 == null ? void 0 : e2.addEventListener) == "function") {
|
|
const c = ({ matches: a }) => a && i("dark"),
|
|
s = ({ matches: a }) => a && i("light");
|
|
return (
|
|
e2 == null || e2.addEventListener("change", c),
|
|
t == null || t.addEventListener("change", s),
|
|
() => {
|
|
(e2 == null || e2.removeEventListener("change", c), t == null || t.removeEventListener("change", s));
|
|
}
|
|
);
|
|
} else {
|
|
const c = () =>
|
|
i(
|
|
e2.matches ? "dark"
|
|
: t.matches ? "light"
|
|
: "no-preference",
|
|
);
|
|
return (
|
|
e2 == null || e2.addEventListener("change", c),
|
|
t == null || t.addEventListener("change", c),
|
|
() => {
|
|
(e2 == null || e2.removeEventListener("change", c), t == null || t.removeEventListener("change", c));
|
|
}
|
|
);
|
|
}
|
|
}, [e2, t]),
|
|
r
|
|
);
|
|
},
|
|
Jt = Ae$1(void 0);
|
|
function Mi() {
|
|
return we$1(Jt);
|
|
}
|
|
function Si() {
|
|
const e2 = /* @__PURE__ */ new Set();
|
|
let t = {};
|
|
return {
|
|
/**
|
|
* Subscribe to the editor instance's changes.
|
|
*/
|
|
subscribe(n) {
|
|
return (
|
|
e2.add(n),
|
|
() => {
|
|
e2.delete(n);
|
|
}
|
|
);
|
|
},
|
|
getSnapshot() {
|
|
return t;
|
|
},
|
|
getServerSnapshot() {
|
|
return t;
|
|
},
|
|
/**
|
|
* Adds a new NodeView Renderer to the editor.
|
|
*/
|
|
setRenderer(n, o) {
|
|
((t = {
|
|
...t,
|
|
[n]: Ue$1(o.reactElement, o.element, n),
|
|
}),
|
|
e2.forEach((r) => r()));
|
|
},
|
|
/**
|
|
* Removes a NodeView Renderer from the editor.
|
|
*/
|
|
removeRenderer(n) {
|
|
const o = { ...t };
|
|
(delete o[n], (t = o), e2.forEach((r) => r()));
|
|
},
|
|
};
|
|
}
|
|
const Vi = ({ contentComponent: e2 }) => {
|
|
const t = De$1(e2.subscribe, e2.getSnapshot, e2.getServerSnapshot);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: Object.values(t) });
|
|
},
|
|
Ti = un((e2, t) => {
|
|
const [n, o] = T();
|
|
return (
|
|
mn(
|
|
t,
|
|
() => (r, i) => {
|
|
(Mt$1(() => {
|
|
o({ node: r, container: i });
|
|
}),
|
|
o(void 0));
|
|
},
|
|
[],
|
|
),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: n && Ue$1(n.node, n.container) })
|
|
);
|
|
}),
|
|
gt$1 = () => {};
|
|
function _i(e2, t) {
|
|
const {
|
|
editor: n,
|
|
className: o,
|
|
theme: r,
|
|
children: i,
|
|
editable: c,
|
|
onSelectionChange: s,
|
|
onChange: a,
|
|
formattingToolbar: d,
|
|
linkToolbar: u,
|
|
slashMenu: m,
|
|
emojiPicker: f,
|
|
sideMenu: g,
|
|
filePanel: h,
|
|
tableHandles: b,
|
|
comments: p,
|
|
autoFocus: C,
|
|
renderEditor: x = true,
|
|
...O
|
|
} = e2,
|
|
[I, j] = T(),
|
|
L = q(),
|
|
P = yi(),
|
|
K = (L == null ? void 0 : L.colorSchemePreference) || P,
|
|
ne = r || (K === "dark" ? "dark" : "light");
|
|
(Hi(a || gt$1, n), xi(s || gt$1, n));
|
|
const G = H(
|
|
(rn) => {
|
|
n.elementRenderer = rn;
|
|
},
|
|
[n],
|
|
),
|
|
Q = V(
|
|
() => ({
|
|
...L,
|
|
editor: n,
|
|
setContentEditableProps: j,
|
|
colorSchemePreference: ne,
|
|
}),
|
|
[L, n, ne],
|
|
),
|
|
on = V(
|
|
() => ({
|
|
editorProps: {
|
|
autoFocus: C,
|
|
contentEditableProps: I,
|
|
editable: c,
|
|
},
|
|
defaultUIProps: {
|
|
formattingToolbar: d,
|
|
linkToolbar: u,
|
|
slashMenu: m,
|
|
emojiPicker: f,
|
|
sideMenu: g,
|
|
filePanel: h,
|
|
tableHandles: b,
|
|
comments: p,
|
|
},
|
|
}),
|
|
[C, I, c, d, u, m, f, g, h, b, p],
|
|
);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(_t$1.Provider, {
|
|
value: Q,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Jt.Provider, {
|
|
value: on,
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Ti, { ref: G }),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Bi, {
|
|
className: o,
|
|
renderEditor: x,
|
|
editorColorScheme: ne,
|
|
ref: t,
|
|
...O,
|
|
children: i,
|
|
}),
|
|
],
|
|
}),
|
|
});
|
|
}
|
|
const Bi = Z.forwardRef(({ className: e2, renderEditor: t, editorColorScheme: n, children: o, ...r }, i) =>
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
"className": D("bn-container", n, e2),
|
|
"data-color-scheme": n,
|
|
...r,
|
|
"ref": i,
|
|
"children": t ? /* @__PURE__ */ jsxRuntimeExports.jsx(Li, { children: o }) : o,
|
|
}),
|
|
),
|
|
Ml = Z.forwardRef(_i),
|
|
Li = (e2) => {
|
|
const t = Mi(),
|
|
n = v(),
|
|
o = V(() => Si(), []),
|
|
r = H(
|
|
(i) => {
|
|
((n.isEditable = t.editorProps.editable !== false), (n._tiptapEditor.contentComponent = o), i ? n.mount(i) : n.unmount());
|
|
},
|
|
[t.editorProps.editable, n, o],
|
|
);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Vi, { contentComponent: o }),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Ei, { ...t.editorProps, ...e2, mount: r }),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ki, { ...t.defaultUIProps }),
|
|
e2.children,
|
|
],
|
|
});
|
|
},
|
|
Ei = (e2) => {
|
|
const { autoFocus: t, mount: n, contentEditableProps: o } = e2;
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
"aria-autocomplete": "list",
|
|
"aria-haspopup": "listbox",
|
|
"data-bn-autofocus": t,
|
|
"ref": n,
|
|
...o,
|
|
});
|
|
};
|
|
const Ke$1 = (e2 = {}, t = []) =>
|
|
V(() => {
|
|
const n = $e$1.create(e2);
|
|
return (window && (window.ProseMirror = n._tiptapEditor), n);
|
|
}, t),
|
|
Xe$1 = (e2) => {
|
|
const [t, n] = T(false),
|
|
o = R({
|
|
editor: e2.editor,
|
|
selector: ({ editor: s }) => s.isEmpty,
|
|
}),
|
|
r = w(),
|
|
i = H(() => {
|
|
n(true);
|
|
}, []),
|
|
c = H(() => {
|
|
n(false);
|
|
}, []);
|
|
return (
|
|
M$1(() => {
|
|
e2.editable && e2.autoFocus && e2.editor.focus();
|
|
}, [e2.autoFocus, e2.editable, e2.editor]),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(r.Comments.Editor, {
|
|
autoFocus: e2.autoFocus,
|
|
className: "bn-comment-editor",
|
|
editor: e2.editor,
|
|
onFocus: i,
|
|
onBlur: c,
|
|
editable: e2.editable,
|
|
}),
|
|
e2.actions &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
className: "bn-comment-actions-wrapper",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(e2.actions, { isFocused: t, isEmpty: o }),
|
|
}),
|
|
],
|
|
})
|
|
);
|
|
};
|
|
let me;
|
|
async function Ji() {
|
|
return (
|
|
me ||
|
|
((me = (async () => {
|
|
const [e2, t] = await Promise.all([
|
|
__vitePreload(() => import("./module-CfopjtOo.js"), true ? [] : void 0),
|
|
// use a dynamic import to encourage bundle-splitting
|
|
// and a smaller initial client bundle size
|
|
__vitePreload(() => import("./native-DB2Z31Rx.js"), true ? [] : void 0),
|
|
]),
|
|
n = "default" in e2 ? e2.default : e2,
|
|
o = "default" in t ? t.default : t;
|
|
return (await n.init({ data: o }), { emojiMart: n, emojiData: o });
|
|
})()),
|
|
me)
|
|
);
|
|
}
|
|
function Qi(e2) {
|
|
const t = F$1(null),
|
|
n = F$1(null);
|
|
return (
|
|
n.current && n.current.update(e2),
|
|
M$1(
|
|
() => (
|
|
(async () => {
|
|
const { emojiMart: o } = await Ji();
|
|
n.current = new o.Picker({ ...e2, ref: t });
|
|
})(),
|
|
() => {
|
|
n.current = null;
|
|
}
|
|
),
|
|
[],
|
|
),
|
|
Z.createElement("div", { ref: t })
|
|
);
|
|
}
|
|
const bt$1 = (e2) => {
|
|
var c;
|
|
const [t, n] = T(false),
|
|
o = w(),
|
|
r = v(),
|
|
i = q();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(o.Generic.Popover.Root, {
|
|
open: t,
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(o.Generic.Popover.Trigger, {
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
onClick: (s) => {
|
|
var a;
|
|
(s.preventDefault(), s.stopPropagation(), n(!t), (a = e2.onOpenChange) == null || a.call(e2, !t));
|
|
},
|
|
style: {
|
|
display: "flex",
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
},
|
|
children: e2.children,
|
|
}),
|
|
}),
|
|
((c = r.domElement) == null ? void 0 : c.parentElement) &&
|
|
Ue$1(
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(o.Generic.Popover.Content, {
|
|
className: "bn-emoji-picker-popover",
|
|
variant: "panel-popover",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Qi, {
|
|
perLine: 7,
|
|
onClickOutside: () => {
|
|
var s;
|
|
(n(false), (s = e2.onOpenChange) == null || s.call(e2, false));
|
|
},
|
|
onEmojiSelect: (s) => {
|
|
var a;
|
|
(e2.onEmojiSelect(s), n(false), (a = e2.onOpenChange) == null || a.call(e2, false));
|
|
},
|
|
theme: i == null ? void 0 : i.colorSchemePreference,
|
|
}),
|
|
}),
|
|
r.domElement.parentElement,
|
|
),
|
|
],
|
|
});
|
|
};
|
|
function el(e2) {
|
|
return Ye$1([e2]).get(e2);
|
|
}
|
|
function Ye$1(e2) {
|
|
const n = _(ne$1).userStore,
|
|
o = H(() => {
|
|
const c = /* @__PURE__ */ new Map();
|
|
for (const s of e2) {
|
|
const a = n.getUser(s);
|
|
a && c.set(s, a);
|
|
}
|
|
return c;
|
|
}, [n, e2]),
|
|
r = V(
|
|
() => ({
|
|
current: o(),
|
|
}),
|
|
[o],
|
|
),
|
|
i = H(
|
|
(c) => {
|
|
const s = n.subscribe((a) => {
|
|
((r.current = o()), c());
|
|
});
|
|
return (n.loadUsers(e2), s);
|
|
},
|
|
[n, o, e2, r],
|
|
);
|
|
return De$1(i, () => r.current);
|
|
}
|
|
const tl = (e2) => {
|
|
const t = w(),
|
|
n = S(),
|
|
o = _(ne$1),
|
|
r = e2.comment.reactions.find((a) => a.emoji === e2.emoji);
|
|
if (!r) throw new Error("Trying to render reaction badge for non-existing reaction");
|
|
const [i, c] = T([]),
|
|
s = Ye$1(i);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
t.Generic.Badge.Root,
|
|
{
|
|
className: D("bn-badge", "bn-comment-reaction"),
|
|
text: r.userIds.length.toString(),
|
|
icon: r.emoji,
|
|
isSelected: o.threadStore.auth.canDeleteReaction(e2.comment, r.emoji),
|
|
onClick: () => e2.onReactionSelect(r.emoji),
|
|
onMouseEnter: () => c(r.userIds),
|
|
mainTooltip: n.comments.reactions.reacted_by,
|
|
secondaryTooltip: `${Array.from(s.values()).map((a) => a.username).join(`
|
|
`)}`,
|
|
},
|
|
r.emoji,
|
|
);
|
|
},
|
|
{ textColor: Il, backgroundColor: Pl, ...nl } = $n,
|
|
Je$1 = h.create({
|
|
blockSpecs: {
|
|
paragraph: Cn(),
|
|
},
|
|
styleSpecs: nl,
|
|
}),
|
|
ol = ({ comment: e2, thread: t, showResolveButton: n }) => {
|
|
const o = _(ne$1),
|
|
r = S(),
|
|
i = Ke$1({
|
|
initialContent: e2.body,
|
|
trailingBlock: false,
|
|
dictionary: {
|
|
...r,
|
|
placeholders: {
|
|
emptyDocument: r.placeholders.edit_comment,
|
|
},
|
|
},
|
|
schema: o.commentEditorSchema || Je$1,
|
|
}),
|
|
c = w(),
|
|
[s, a] = T(false),
|
|
[d, u] = T(false),
|
|
m = o.threadStore,
|
|
f = H(() => {
|
|
a(true);
|
|
}, []),
|
|
g = H(() => {
|
|
(i.replaceBlocks(i.document, e2.body), a(false));
|
|
}, [i, e2.body]),
|
|
h = H(
|
|
async (G) => {
|
|
(await m.updateComment({
|
|
commentId: e2.id,
|
|
comment: {
|
|
body: i.document,
|
|
},
|
|
threadId: t.id,
|
|
}),
|
|
a(false));
|
|
},
|
|
[e2, t.id, i, m],
|
|
),
|
|
b = H(async () => {
|
|
await m.deleteComment({
|
|
commentId: e2.id,
|
|
threadId: t.id,
|
|
});
|
|
}, [e2, t.id, m]),
|
|
p = H(
|
|
async (G) => {
|
|
m.auth.canAddReaction(e2, G) ?
|
|
await m.addReaction({
|
|
threadId: t.id,
|
|
commentId: e2.id,
|
|
emoji: G,
|
|
})
|
|
: m.auth.canDeleteReaction(e2, G) &&
|
|
(await m.deleteReaction({
|
|
threadId: t.id,
|
|
commentId: e2.id,
|
|
emoji: G,
|
|
}));
|
|
},
|
|
[m, e2, t.id],
|
|
),
|
|
C = H(async () => {
|
|
await m.resolveThread({
|
|
threadId: t.id,
|
|
});
|
|
}, [t.id, m]),
|
|
x = H(async () => {
|
|
await m.unresolveThread({
|
|
threadId: t.id,
|
|
});
|
|
}, [t.id, m]),
|
|
O = el(e2.userId);
|
|
if (!e2.body) return null;
|
|
let I;
|
|
const j = m.auth.canAddReaction(e2),
|
|
L = m.auth.canDeleteComment(e2),
|
|
P = m.auth.canUpdateComment(e2),
|
|
K = n && (t.resolved ? m.auth.canUnresolveThread(t) : m.auth.canResolveThread(t));
|
|
s ||
|
|
(I = /* @__PURE__ */ jsxRuntimeExports.jsxs(c.Generic.Toolbar.Root, {
|
|
className: D("bn-action-toolbar", "bn-comment-actions"),
|
|
variant: "action-toolbar",
|
|
children: [
|
|
j &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(bt$1, {
|
|
onEmojiSelect: (G) => p(G.native),
|
|
onOpenChange: u,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
c.Generic.Toolbar.Button,
|
|
{
|
|
mainTooltip: r.comments.actions.add_reaction,
|
|
variant: "compact",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(dt$1, { size: 16 }),
|
|
},
|
|
"add-reaction",
|
|
),
|
|
}),
|
|
K &&
|
|
(t.resolved ?
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
c.Generic.Toolbar.Button,
|
|
{
|
|
mainTooltip: "Re-open",
|
|
variant: "compact",
|
|
onClick: x,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Bo, { size: 16 }),
|
|
},
|
|
"reopen",
|
|
)
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
c.Generic.Toolbar.Button,
|
|
{
|
|
mainTooltip: r.comments.actions.resolve,
|
|
variant: "compact",
|
|
onClick: C,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Qo, { size: 16 }),
|
|
},
|
|
"resolve",
|
|
)),
|
|
(L || P) &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(c.Generic.Menu.Root, {
|
|
position: "bottom-start",
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(c.Generic.Menu.Trigger, {
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
c.Generic.Toolbar.Button,
|
|
{
|
|
mainTooltip: r.comments.actions.more_actions,
|
|
variant: "compact",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(rr, { size: 16 }),
|
|
},
|
|
"more-actions",
|
|
),
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(c.Generic.Menu.Dropdown, {
|
|
className: "bn-menu-dropdown",
|
|
children: [
|
|
P &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
c.Generic.Menu.Item,
|
|
{
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Lo, {}),
|
|
onClick: f,
|
|
children: r.comments.actions.edit_comment,
|
|
},
|
|
"edit-comment",
|
|
),
|
|
L &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
c.Generic.Menu.Item,
|
|
{
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(tr, {}),
|
|
onClick: b,
|
|
children: r.comments.actions.delete_comment,
|
|
},
|
|
"delete-comment",
|
|
),
|
|
],
|
|
}),
|
|
],
|
|
}),
|
|
],
|
|
}));
|
|
const ne = e2.createdAt.toLocaleDateString(void 0, {
|
|
month: "short",
|
|
day: "numeric",
|
|
});
|
|
if (!e2.body) throw new Error("soft deletes are not yet supported");
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(c.Comments.Comment, {
|
|
authorInfo: O ?? "loading",
|
|
timeString: ne,
|
|
edited: e2.updatedAt.getTime() !== e2.createdAt.getTime(),
|
|
showActions: "hover",
|
|
actions: I,
|
|
className: "bn-thread-comment",
|
|
emojiPickerOpen: d,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Xe$1, {
|
|
autoFocus: s,
|
|
editor: i,
|
|
editable: s,
|
|
actions:
|
|
e2.reactions.length > 0 || s ?
|
|
({ isEmpty: G }) =>
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
|
|
children: [
|
|
e2.reactions.length > 0 &&
|
|
!s &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(c.Generic.Badge.Group, {
|
|
className: D("bn-badge-group", "bn-comment-reactions"),
|
|
children: [
|
|
e2.reactions.map((Q) =>
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
tl,
|
|
{
|
|
comment: e2,
|
|
emoji: Q.emoji,
|
|
onReactionSelect: p,
|
|
},
|
|
Q.emoji,
|
|
),
|
|
),
|
|
j &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(bt$1, {
|
|
onEmojiSelect: (Q) => p(Q.native),
|
|
onOpenChange: u,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(c.Generic.Badge.Root, {
|
|
className: D("bn-badge", "bn-comment-add-reaction"),
|
|
text: "+",
|
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(dt$1, { size: 16 }),
|
|
mainTooltip: r.comments.actions.add_reaction,
|
|
}),
|
|
}),
|
|
],
|
|
}),
|
|
s &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(c.Generic.Toolbar.Root, {
|
|
variant: "action-toolbar",
|
|
className: D("bn-action-toolbar", "bn-comment-actions"),
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(c.Generic.Toolbar.Button, {
|
|
mainTooltip: r.comments.save_button_text,
|
|
variant: "compact",
|
|
onClick: h,
|
|
isDisabled: G,
|
|
children: r.comments.save_button_text,
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(c.Generic.Toolbar.Button, {
|
|
className: "bn-button",
|
|
mainTooltip: r.comments.cancel_button_text,
|
|
variant: "compact",
|
|
onClick: g,
|
|
children: r.comments.cancel_button_text,
|
|
}),
|
|
],
|
|
}),
|
|
],
|
|
})
|
|
: void 0,
|
|
}),
|
|
});
|
|
},
|
|
rl = ({ thread: e2, maxCommentsBeforeCollapse: t }) => {
|
|
const n = w(),
|
|
o = S(),
|
|
r = Ye$1(e2.resolvedBy ? [e2.resolvedBy] : []),
|
|
i = e2.comments.map((c, s) =>
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
ol,
|
|
{
|
|
thread: e2,
|
|
comment: c,
|
|
showResolveButton: s === 0,
|
|
},
|
|
c.id + JSON.stringify(c.body || "{}"),
|
|
),
|
|
);
|
|
if (e2.resolved && e2.resolvedUpdatedAt && e2.resolvedBy) {
|
|
if (!r.get(e2.resolvedBy)) throw new Error(`User ${e2.resolvedBy} resolved thread ${e2.id}, but their data could not be found.`);
|
|
const s = e2.comments.findLastIndex((a) => e2.resolvedUpdatedAt.getTime() > a.createdAt.getTime()) + 1;
|
|
i.splice(
|
|
s,
|
|
0,
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
n.Comments.Comment,
|
|
{
|
|
className: "bn-thread-comment",
|
|
authorInfo: (e2.resolvedBy && r.get(e2.resolvedBy)) || "loading",
|
|
timeString: e2.resolvedUpdatedAt.toLocaleDateString(void 0, {
|
|
month: "short",
|
|
day: "numeric",
|
|
}),
|
|
edited: false,
|
|
showActions: false,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bn-resolved-text", children: o.comments.sidebar.marked_as_resolved }),
|
|
},
|
|
"resolved-comment",
|
|
),
|
|
);
|
|
}
|
|
return (
|
|
t &&
|
|
i.length > t &&
|
|
i.splice(
|
|
1,
|
|
i.length - 2,
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
n.Comments.ExpandSectionsPrompt,
|
|
{
|
|
className: "bn-thread-expand-prompt",
|
|
children: o.comments.sidebar.more_replies(e2.comments.length - 2),
|
|
},
|
|
"expand-prompt",
|
|
),
|
|
),
|
|
i
|
|
);
|
|
};
|
|
function il() {
|
|
const e2 = _(ne$1),
|
|
t = w(),
|
|
n = S(),
|
|
o = Ke$1({
|
|
trailingBlock: false,
|
|
dictionary: {
|
|
...n,
|
|
placeholders: {
|
|
emptyDocument: n.placeholders.new_comment,
|
|
},
|
|
},
|
|
schema: e2.commentEditorSchema || Je$1,
|
|
});
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(t.Comments.Card, {
|
|
className: "bn-thread",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Xe$1, {
|
|
autoFocus: true,
|
|
editable: true,
|
|
editor: o,
|
|
actions: ({ isEmpty: r }) =>
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Toolbar.Root, {
|
|
className: D("bn-action-toolbar", "bn-comment-actions"),
|
|
variant: "action-toolbar",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(t.Generic.Toolbar.Button, {
|
|
className: "bn-button",
|
|
mainTooltip: "Save",
|
|
variant: "compact",
|
|
isDisabled: r,
|
|
onClick: async () => {
|
|
(await e2.createThread({
|
|
initialComment: {
|
|
body: o.document,
|
|
},
|
|
}),
|
|
e2.stopPendingComment());
|
|
},
|
|
children: "Save",
|
|
}),
|
|
}),
|
|
}),
|
|
});
|
|
}
|
|
function ll(e2) {
|
|
const t = v(),
|
|
n = _(ne$1),
|
|
o = B(ne$1, {
|
|
editor: t,
|
|
selector: (s) => s.pendingComment,
|
|
}),
|
|
r = R({
|
|
editor: t,
|
|
selector: ({ editor: s }) =>
|
|
o ?
|
|
{
|
|
from: s.prosemirrorState.selection.from,
|
|
to: s.prosemirrorState.selection.to,
|
|
}
|
|
: void 0,
|
|
}),
|
|
i = V(() => {
|
|
var s, a;
|
|
return {
|
|
...e2.floatingUIOptions,
|
|
useFloatingOptions: {
|
|
open: !!o,
|
|
// Needed as hooks like `useDismiss` call `onOpenChange` to change the
|
|
// open state.
|
|
onOpenChange: (d) => {
|
|
d || (n.stopPendingComment(), t.focus());
|
|
},
|
|
placement: "bottom",
|
|
middleware: [offset(10), shift(), flip()],
|
|
...((s = e2.floatingUIOptions) == null ? void 0 : s.useFloatingOptions),
|
|
},
|
|
focusManagerProps: {
|
|
disabled: false,
|
|
},
|
|
elementProps: {
|
|
style: {
|
|
zIndex: 60,
|
|
},
|
|
...((a = e2.floatingUIOptions) == null ? void 0 : a.elementProps),
|
|
},
|
|
};
|
|
}, [n, t, o, e2.floatingUIOptions]),
|
|
c = e2.floatingComposer || il;
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Ge$1, { position: r, ...i, children: /* @__PURE__ */ jsxRuntimeExports.jsx(c, {}) });
|
|
}
|
|
const cl = /* @__PURE__ */ Object.freeze(
|
|
/* @__PURE__ */ Object.defineProperty(
|
|
{
|
|
__proto__: null,
|
|
default: ll,
|
|
},
|
|
Symbol.toStringTag,
|
|
{ value: "Module" },
|
|
),
|
|
),
|
|
tn = ({ thread: e2, selected: t, referenceText: n, maxCommentsBeforeCollapse: o, onFocus: r, onBlur: i, tabIndex: c }) => {
|
|
const s = w(),
|
|
a = S(),
|
|
d = _(ne$1),
|
|
u = Ke$1({
|
|
trailingBlock: false,
|
|
dictionary: {
|
|
...a,
|
|
placeholders: {
|
|
emptyDocument: a.placeholders.comment_reply,
|
|
},
|
|
},
|
|
schema: d.commentEditorSchema || Je$1,
|
|
}),
|
|
m = H(async () => {
|
|
(await d.threadStore.addComment({
|
|
comment: {
|
|
body: u.document,
|
|
},
|
|
threadId: e2.id,
|
|
}),
|
|
u.removeBlocks(u.document));
|
|
}, [d, u, e2.id]);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(s.Comments.Card, {
|
|
className: "bn-thread",
|
|
headerText: n,
|
|
onFocus: r,
|
|
onBlur: i,
|
|
selected: t,
|
|
tabIndex: c,
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(s.Comments.CardSection, {
|
|
className: "bn-thread-comments",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(rl, {
|
|
thread: e2,
|
|
maxCommentsBeforeCollapse: t ? void 0 : o || 5,
|
|
}),
|
|
}),
|
|
t &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(s.Comments.CardSection, {
|
|
className: "bn-thread-composer",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Xe$1, {
|
|
autoFocus: false,
|
|
editable: true,
|
|
editor: u,
|
|
actions: ({ isEmpty: f }) =>
|
|
f ? null : (
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(s.Generic.Toolbar.Root, {
|
|
variant: "action-toolbar",
|
|
className: D("bn-action-toolbar", "bn-comment-actions"),
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(s.Generic.Toolbar.Button, {
|
|
mainTooltip: a.comments.save_button_text,
|
|
variant: "compact",
|
|
isDisabled: f,
|
|
onClick: m,
|
|
children: a.comments.save_button_text,
|
|
}),
|
|
})
|
|
),
|
|
}),
|
|
}),
|
|
],
|
|
});
|
|
};
|
|
function nn() {
|
|
const t = _(ne$1).threadStore,
|
|
n = F$1(void 0);
|
|
n.current || (n.current = t.getThreads());
|
|
const o = H(
|
|
(r) =>
|
|
t.subscribe((i) => {
|
|
((n.current = i), r());
|
|
}),
|
|
[t],
|
|
);
|
|
return De$1(o, () => n.current);
|
|
}
|
|
function al(e2) {
|
|
const t = v(),
|
|
n = _(ne$1),
|
|
o = B(ne$1, {
|
|
editor: t,
|
|
selector: (a) =>
|
|
a.selectedThreadId ?
|
|
{
|
|
id: a.selectedThreadId,
|
|
position: a.threadPositions.get(a.selectedThreadId),
|
|
}
|
|
: void 0,
|
|
}),
|
|
r = nn(),
|
|
i = V(() => (o ? r.get(o.id) : void 0), [o, r]),
|
|
c = V(() => {
|
|
var a, d, u;
|
|
return {
|
|
...e2.floatingUIOptions,
|
|
useFloatingOptions: {
|
|
open: !!o,
|
|
// Needed as hooks like `useDismiss` call `onOpenChange` to change the
|
|
// open state.
|
|
onOpenChange: (m, f, g) => {
|
|
(g === "escape-key" && t.focus(), m || n.selectThread(void 0));
|
|
},
|
|
placement: "bottom",
|
|
middleware: [offset(10), shift(), flip()],
|
|
...((a = e2.floatingUIOptions) == null ? void 0 : a.useFloatingOptions),
|
|
},
|
|
focusManagerProps: {
|
|
disabled: true,
|
|
...((d = e2.floatingUIOptions) == null ? void 0 : d.focusManagerProps),
|
|
},
|
|
elementProps: {
|
|
style: {
|
|
zIndex: 30,
|
|
},
|
|
...((u = e2.floatingUIOptions) == null ? void 0 : u.elementProps),
|
|
},
|
|
};
|
|
}, [n, t, e2.floatingUIOptions, o]),
|
|
s = e2.floatingThread || tn;
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Ge$1, { position: o == null ? void 0 : o.position, ...c, children: i && /* @__PURE__ */ jsxRuntimeExports.jsx(s, { thread: i, selected: true }) });
|
|
}
|
|
const sl = /* @__PURE__ */ Object.freeze(
|
|
/* @__PURE__ */ Object.defineProperty(
|
|
{
|
|
__proto__: null,
|
|
default: al,
|
|
},
|
|
Symbol.toStringTag,
|
|
{ value: "Module" },
|
|
),
|
|
);
|
|
Z.memo(({ thread: e2, selectedThreadId: t, maxCommentsBeforeCollapse: n, referenceText: o }) => {
|
|
const r = _(ne$1),
|
|
i = H(
|
|
(s) => {
|
|
s.target.closest(".bn-action-toolbar") || r.selectThread(e2.id);
|
|
},
|
|
[r, e2.id],
|
|
),
|
|
c = H(
|
|
(s) => {
|
|
if (!s.relatedTarget || s.relatedTarget.closest(".bn-action-toolbar")) return;
|
|
const a = s.target instanceof Node ? s.target : null,
|
|
d = s.relatedTarget instanceof Node ? s.relatedTarget.closest(".bn-thread") : null;
|
|
(!a || !d || !d.contains(a)) && r.selectThread(void 0);
|
|
},
|
|
[r],
|
|
);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(tn, {
|
|
thread: e2,
|
|
selected: e2.id === t,
|
|
referenceText: o,
|
|
maxCommentsBeforeCollapse: n,
|
|
onFocus: i,
|
|
onBlur: c,
|
|
tabIndex: 0,
|
|
});
|
|
});
|
|
function ml(e2) {
|
|
return e2.currentTarget instanceof HTMLElement && e2.relatedTarget instanceof HTMLElement ? e2.currentTarget.contains(e2.relatedTarget) : false;
|
|
}
|
|
function Zl({ onBlur: e2, onFocus: t } = {}) {
|
|
const n = F$1(null),
|
|
[o, r] = T(false),
|
|
i = F$1(false),
|
|
c = (d) => {
|
|
(r(d), (i.current = d));
|
|
},
|
|
s = (d) => {
|
|
i.current || (c(true), t == null || t(d));
|
|
},
|
|
a = (d) => {
|
|
i.current && !ml(d) && (c(false), e2 == null || e2(d));
|
|
};
|
|
return (
|
|
M$1(() => {
|
|
const d = n.current;
|
|
if (d)
|
|
return (
|
|
d.addEventListener("focusin", s),
|
|
d.addEventListener("focusout", a),
|
|
() => {
|
|
(d == null || d.removeEventListener("focusin", s), d == null || d.removeEventListener("focusout", a));
|
|
}
|
|
);
|
|
}, [s, a]),
|
|
{ ref: n, focused: o }
|
|
);
|
|
}
|
|
function zl(e2, t) {
|
|
const n = e2.getBoundingClientRect(),
|
|
o = t.getBoundingClientRect(),
|
|
r = n.top < o.top,
|
|
i = n.bottom > o.bottom;
|
|
return (
|
|
r && i ? "both"
|
|
: r ? "top"
|
|
: i ? "bottom"
|
|
: "none"
|
|
);
|
|
}
|
|
function jl(e2) {
|
|
return (t) => {
|
|
e2.forEach((n) => {
|
|
typeof n == "function" ? n(t) : n != null && (n.current = t);
|
|
});
|
|
};
|
|
}
|
|
|
|
const React$6 = await importShared("react");
|
|
|
|
var isCheckBoxInput = (element) => element.type === "checkbox";
|
|
|
|
var isDateObject = (value) => value instanceof Date;
|
|
|
|
var isNullOrUndefined = (value) => value == null;
|
|
|
|
const isObjectType = (value) => typeof value === "object";
|
|
var isObject = (value) => !isNullOrUndefined(value) && !Array.isArray(value) && isObjectType(value) && !isDateObject(value);
|
|
|
|
var getEventValue = (event) =>
|
|
isObject(event) && event.target ?
|
|
isCheckBoxInput(event.target) ? event.target.checked
|
|
: event.target.value
|
|
: event;
|
|
|
|
var isNameInFieldArray = (names, name) => name.split(".").some((part, index, arr) => !isNaN(Number(part)) && names.has(arr.slice(0, index).join(".")));
|
|
|
|
var isPlainObject = (tempObject) => {
|
|
const prototypeCopy = tempObject.constructor && tempObject.constructor.prototype;
|
|
return isObject(prototypeCopy) && prototypeCopy.hasOwnProperty("isPrototypeOf");
|
|
};
|
|
|
|
var isWeb = typeof window !== "undefined" && typeof window.HTMLElement !== "undefined" && typeof document !== "undefined";
|
|
|
|
function cloneObject(data) {
|
|
if (data instanceof Date) {
|
|
return new Date(data);
|
|
}
|
|
const isFileListInstance = typeof FileList !== "undefined" && data instanceof FileList;
|
|
if (isWeb && (data instanceof Blob || isFileListInstance)) {
|
|
return data;
|
|
}
|
|
const isArray = Array.isArray(data);
|
|
if (!isArray && !(isObject(data) && isPlainObject(data))) {
|
|
return data;
|
|
}
|
|
const copy = isArray ? [] : Object.create(Object.getPrototypeOf(data));
|
|
for (const key in data) {
|
|
if (Object.prototype.hasOwnProperty.call(data, key)) {
|
|
copy[key] = cloneObject(data[key]);
|
|
}
|
|
}
|
|
return copy;
|
|
}
|
|
|
|
const EVENTS = {
|
|
BLUR: "blur",
|
|
FOCUS_OUT: "focusout",
|
|
SUBMIT: "submit",
|
|
TRIGGER: "trigger",
|
|
VALID: "valid",
|
|
};
|
|
const VALIDATION_MODE = {
|
|
onBlur: "onBlur",
|
|
onChange: "onChange",
|
|
onSubmit: "onSubmit",
|
|
onTouched: "onTouched",
|
|
all: "all",
|
|
};
|
|
const INPUT_VALIDATION_RULES = {
|
|
max: "max",
|
|
min: "min",
|
|
maxLength: "maxLength",
|
|
minLength: "minLength",
|
|
pattern: "pattern",
|
|
required: "required",
|
|
validate: "validate",
|
|
};
|
|
const ROOT_ERROR_TYPE = "root";
|
|
const PROTOTYPE_KEYWORDS = ["__proto__", "constructor", "prototype"];
|
|
|
|
const IS_KEY_RE = /^\w*$/;
|
|
var isKey = (value) => IS_KEY_RE.test(value);
|
|
|
|
var isUndefined = (val) => val === undefined;
|
|
|
|
const FIELD_PATH_RE = /[.[\]'"]/;
|
|
var stringToPath = (input) => input.split(FIELD_PATH_RE).filter(Boolean);
|
|
|
|
var get = (object, path, defaultValue) => {
|
|
if (!path || !isObject(object)) {
|
|
return defaultValue;
|
|
}
|
|
const paths = isKey(path) ? [path] : stringToPath(path);
|
|
if (paths.some((key) => PROTOTYPE_KEYWORDS.includes(key))) {
|
|
return defaultValue;
|
|
}
|
|
const result = paths.reduce((result, key) => {
|
|
return isNullOrUndefined(result) ? undefined : result[key];
|
|
}, object);
|
|
return (
|
|
isUndefined(result) || result === object ?
|
|
isUndefined(object[path]) ? defaultValue
|
|
: object[path]
|
|
: result
|
|
);
|
|
};
|
|
|
|
var isBoolean = (value) => typeof value === "boolean";
|
|
|
|
var isFunction = (value) => typeof value === "function";
|
|
|
|
var set = (object, path, value) => {
|
|
let index = -1;
|
|
const tempPath = isKey(path) ? [path] : stringToPath(path);
|
|
const length = tempPath.length;
|
|
const lastIndex = length - 1;
|
|
while (++index < length) {
|
|
const key = tempPath[index];
|
|
let newValue = value;
|
|
if (index !== lastIndex) {
|
|
const objValue = object[key];
|
|
newValue =
|
|
isObject(objValue) || Array.isArray(objValue) ? objValue
|
|
: !isNaN(+tempPath[index + 1]) ? []
|
|
: {};
|
|
}
|
|
if (PROTOTYPE_KEYWORDS.includes(key)) {
|
|
return;
|
|
}
|
|
object[key] = newValue;
|
|
object = object[key];
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Separate context for `control` to prevent unnecessary rerenders.
|
|
* Internal hooks that only need control use this instead of full form context.
|
|
*/
|
|
const HookFormControlContext = React$6.createContext(null);
|
|
HookFormControlContext.displayName = "HookFormControlContext";
|
|
|
|
var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => {
|
|
const result = {};
|
|
for (const key in formState) {
|
|
Object.defineProperty(result, key, {
|
|
get: () => {
|
|
const _key = key;
|
|
if (control._proxyFormState[_key] !== VALIDATION_MODE.all) {
|
|
control._proxyFormState[_key] = !isRoot || VALIDATION_MODE.all;
|
|
}
|
|
return formState[_key];
|
|
},
|
|
});
|
|
}
|
|
return result;
|
|
};
|
|
|
|
const useIsomorphicLayoutEffect = isWeb ? React$6.useLayoutEffect : React$6.useEffect;
|
|
|
|
var isString = (value) => typeof value === "string";
|
|
|
|
var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) => {
|
|
if (isString(names)) {
|
|
isGlobal && _names.watch.add(names);
|
|
return get(formValues, names, defaultValue);
|
|
}
|
|
if (Array.isArray(names)) {
|
|
return names.map((fieldName) => (isGlobal && _names.watch.add(fieldName), get(formValues, fieldName)));
|
|
}
|
|
isGlobal && (_names.watchAll = true);
|
|
return formValues;
|
|
};
|
|
|
|
var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
|
|
|
|
const isEmptyObjectWithCustomPrototype = (object, keys) => keys.length === 0 && !Array.isArray(object) && !isPlainObject(object);
|
|
function deepEqual(object1, object2, visited = new WeakMap()) {
|
|
if (object1 === object2) {
|
|
return true;
|
|
}
|
|
if (isPrimitive(object1) || isPrimitive(object2)) {
|
|
return Object.is(object1, object2);
|
|
}
|
|
if (isDateObject(object1) && isDateObject(object2)) {
|
|
return Object.is(object1.getTime(), object2.getTime());
|
|
}
|
|
const keys1 = Object.keys(object1);
|
|
const keys2 = Object.keys(object2);
|
|
if (keys1.length !== keys2.length) {
|
|
return false;
|
|
}
|
|
if (isEmptyObjectWithCustomPrototype(object1, keys1) || isEmptyObjectWithCustomPrototype(object2, keys2)) {
|
|
return Object.is(object1, object2);
|
|
}
|
|
if (!keys1.length && Array.isArray(object1) !== Array.isArray(object2)) {
|
|
return false;
|
|
}
|
|
const visitedPairs = visited.get(object1);
|
|
if (visitedPairs && visitedPairs.has(object2)) {
|
|
return true;
|
|
}
|
|
if (visitedPairs) {
|
|
visitedPairs.add(object2);
|
|
} else {
|
|
const ws = new WeakSet();
|
|
ws.add(object2);
|
|
visited.set(object1, ws);
|
|
}
|
|
for (const key of keys1) {
|
|
const val1 = object1[key];
|
|
if (!(key in object2)) {
|
|
return false;
|
|
}
|
|
if (key !== "ref") {
|
|
const val2 = object2[key];
|
|
if (
|
|
(isDateObject(val1) && isDateObject(val2)) || ((isObject(val1) || Array.isArray(val1)) && (isObject(val2) || Array.isArray(val2))) ?
|
|
!deepEqual(val1, val2, visited)
|
|
: !Object.is(val1, val2)
|
|
) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
const HookFormContext = React$6.createContext(null);
|
|
HookFormContext.displayName = "HookFormContext";
|
|
/**
|
|
* A provider component that propagates the `useForm` methods to all children components via [React Context](https://react.dev/reference/react/useContext) API. To be used with {@link useFormContext}.
|
|
*
|
|
* @remarks
|
|
* [API](https://react-hook-form.com/docs/useformcontext) • [Demo](https://codesandbox.io/s/react-hook-form-v7-form-context-ytudi)
|
|
*
|
|
* @param props - all useForm methods
|
|
*
|
|
* @example
|
|
* ```tsx
|
|
* function App() {
|
|
* const methods = useForm();
|
|
* const onSubmit = data => console.log(data);
|
|
*
|
|
* return (
|
|
* <FormProvider {...methods} >
|
|
* <form onSubmit={methods.handleSubmit(onSubmit)}>
|
|
* <NestedInput />
|
|
* <input type="submit" />
|
|
* </form>
|
|
* </FormProvider>
|
|
* );
|
|
* }
|
|
*
|
|
* function NestedInput() {
|
|
* const { register } = useFormContext(); // retrieve all hook methods
|
|
* return <input {...register("test")} />;
|
|
* }
|
|
* ```
|
|
*/
|
|
const FormProvider = ({
|
|
children,
|
|
watch,
|
|
getValues,
|
|
getFieldState,
|
|
setError,
|
|
clearErrors,
|
|
setValue,
|
|
setValues,
|
|
trigger,
|
|
formState,
|
|
resetField,
|
|
reset,
|
|
handleSubmit,
|
|
unregister,
|
|
control,
|
|
register,
|
|
setFocus,
|
|
subscribe,
|
|
}) => {
|
|
const memoizedValue = React$6.useMemo(
|
|
() => ({
|
|
watch,
|
|
getValues,
|
|
getFieldState,
|
|
setError,
|
|
clearErrors,
|
|
setValue,
|
|
setValues,
|
|
trigger,
|
|
formState,
|
|
resetField,
|
|
reset,
|
|
handleSubmit,
|
|
unregister,
|
|
control,
|
|
register,
|
|
setFocus,
|
|
subscribe,
|
|
}),
|
|
[clearErrors, control, formState, getFieldState, getValues, handleSubmit, register, reset, resetField, setError, setFocus, setValue, setValues, subscribe, trigger, unregister, watch],
|
|
);
|
|
return React$6.createElement(HookFormContext.Provider, { value: memoizedValue }, React$6.createElement(HookFormControlContext.Provider, { value: memoizedValue.control }, children));
|
|
};
|
|
|
|
var appendErrors = (name, validateAllFieldCriteria, errors, type, message) =>
|
|
validateAllFieldCriteria ?
|
|
{
|
|
...errors[name],
|
|
types: {
|
|
...(errors[name] && errors[name].types ? errors[name].types : {}),
|
|
[type]: message || true,
|
|
},
|
|
}
|
|
: {};
|
|
|
|
var compact = (value) => (Array.isArray(value) ? value.filter(Boolean) : []);
|
|
|
|
var convertToArrayPayload = (value) => (Array.isArray(value) ? value : [value]);
|
|
|
|
var createSubject = () => {
|
|
let _observers = [];
|
|
const next = (value) => {
|
|
for (const observer of _observers) {
|
|
observer.next && observer.next(value);
|
|
}
|
|
};
|
|
const subscribe = (observer) => {
|
|
_observers.push(observer);
|
|
return {
|
|
unsubscribe: () => {
|
|
_observers = _observers.filter((o) => o !== observer);
|
|
},
|
|
};
|
|
};
|
|
const unsubscribe = () => {
|
|
_observers = [];
|
|
};
|
|
return {
|
|
get observers() {
|
|
return _observers;
|
|
},
|
|
next,
|
|
subscribe,
|
|
unsubscribe,
|
|
};
|
|
};
|
|
|
|
function extractFormValues(fieldsState, formValues) {
|
|
const values = {};
|
|
for (const key in fieldsState) {
|
|
if (fieldsState.hasOwnProperty(key)) {
|
|
const fieldState = fieldsState[key];
|
|
const fieldValue = formValues[key];
|
|
if (fieldState && isObject(fieldState) && fieldValue) {
|
|
const nestedFieldsState = extractFormValues(fieldState, fieldValue);
|
|
if (isObject(nestedFieldsState)) {
|
|
values[key] = nestedFieldsState;
|
|
}
|
|
} else if (fieldsState[key]) {
|
|
values[key] = fieldValue;
|
|
}
|
|
}
|
|
}
|
|
return values;
|
|
}
|
|
|
|
var isEmptyObject = (value) => isObject(value) && !Object.keys(value).length;
|
|
|
|
var isFileInput = (element) => element.type === "file";
|
|
|
|
var isHTMLElement = (value) => {
|
|
if (!isWeb) {
|
|
return false;
|
|
}
|
|
const owner = value ? value.ownerDocument : 0;
|
|
return value instanceof (owner && owner.defaultView ? owner.defaultView.HTMLElement : HTMLElement);
|
|
};
|
|
|
|
var isMultipleSelect = (element) => element.type === `select-multiple`;
|
|
|
|
var isRadioInput = (element) => element.type === "radio";
|
|
|
|
var isRadioOrCheckbox = (ref) => isRadioInput(ref) || isCheckBoxInput(ref);
|
|
|
|
var live = (ref) => isHTMLElement(ref) && ref.isConnected;
|
|
|
|
function baseGet(object, updatePath) {
|
|
const length = updatePath.slice(0, -1).length;
|
|
let index = 0;
|
|
while (index < length) {
|
|
if (isNullOrUndefined(object)) {
|
|
object = undefined;
|
|
break;
|
|
}
|
|
object = object[updatePath[index]];
|
|
index++;
|
|
}
|
|
return object;
|
|
}
|
|
function isEmptyArray(obj) {
|
|
for (const key in obj) {
|
|
if (obj.hasOwnProperty(key) && !isUndefined(obj[key])) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
function unset(object, path) {
|
|
if (isString(path) && Object.prototype.hasOwnProperty.call(object, path)) {
|
|
delete object[path];
|
|
return object;
|
|
}
|
|
const paths =
|
|
Array.isArray(path) ? path
|
|
: isKey(path) ? [path]
|
|
: stringToPath(path);
|
|
const childObject = paths.length === 1 ? object : baseGet(object, paths);
|
|
const index = paths.length - 1;
|
|
const key = paths[index];
|
|
if (childObject) {
|
|
delete childObject[key];
|
|
}
|
|
if (index !== 0 && ((isObject(childObject) && isEmptyObject(childObject)) || (Array.isArray(childObject) && isEmptyArray(childObject)))) {
|
|
unset(object, paths.slice(0, -1));
|
|
}
|
|
return object;
|
|
}
|
|
|
|
var objectHasFunction = (data) => {
|
|
for (const key in data) {
|
|
if (isFunction(data[key])) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
function isTraversable(value) {
|
|
return Array.isArray(value) || (isObject(value) && !objectHasFunction(value));
|
|
}
|
|
function markFieldsDirty(data, fields = {}) {
|
|
for (const key in data) {
|
|
const value = data[key];
|
|
if (isTraversable(value)) {
|
|
fields[key] = Array.isArray(value) ? [] : {};
|
|
markFieldsDirty(value, fields[key]);
|
|
} else if (!isUndefined(value)) {
|
|
fields[key] = true;
|
|
}
|
|
}
|
|
return fields;
|
|
}
|
|
function pruneDirtyFields(value) {
|
|
if (value === false) {
|
|
return undefined;
|
|
}
|
|
if (value === true) {
|
|
return true;
|
|
}
|
|
if (Array.isArray(value)) {
|
|
const result = value.map((value) => pruneDirtyFields(value));
|
|
return result.some((value) => value !== undefined) ? result : undefined;
|
|
}
|
|
if (isObject(value)) {
|
|
const result = {};
|
|
for (const key in value) {
|
|
const pruned = pruneDirtyFields(value[key]);
|
|
if (!isUndefined(pruned)) {
|
|
result[key] = pruned;
|
|
}
|
|
}
|
|
return Object.keys(result).length ? result : undefined;
|
|
}
|
|
return undefined;
|
|
}
|
|
function getDirtyFields(data, formValues, dirtyFieldsFromValues) {
|
|
if (!dirtyFieldsFromValues) {
|
|
dirtyFieldsFromValues = markFieldsDirty(formValues);
|
|
}
|
|
for (const key in data) {
|
|
const value = data[key];
|
|
if (isTraversable(value)) {
|
|
if (isUndefined(formValues) || isPrimitive(dirtyFieldsFromValues[key])) {
|
|
dirtyFieldsFromValues[key] = markFieldsDirty(value, Array.isArray(value) ? [] : {});
|
|
} else {
|
|
getDirtyFields(value, isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key]);
|
|
}
|
|
} else {
|
|
const formValue = formValues[key];
|
|
dirtyFieldsFromValues[key] = !deepEqual(value, formValue);
|
|
}
|
|
}
|
|
return pruneDirtyFields(dirtyFieldsFromValues) || {};
|
|
}
|
|
|
|
const defaultResult = {
|
|
value: false,
|
|
isValid: false,
|
|
};
|
|
const validResult = { value: true, isValid: true };
|
|
var getCheckboxValue = (options) => {
|
|
if (Array.isArray(options)) {
|
|
if (options.length > 1) {
|
|
const values = options.filter((option) => option && option.checked && !option.disabled).map((option) => option.value);
|
|
return { value: values, isValid: !!values.length };
|
|
}
|
|
return (
|
|
options[0].checked && !options[0].disabled ?
|
|
// @ts-expect-error expected to work in the browser
|
|
options[0].attributes && !isUndefined(options[0].attributes.value) ?
|
|
isUndefined(options[0].value) || options[0].value === "" ?
|
|
validResult
|
|
: { value: options[0].value, isValid: true }
|
|
: validResult
|
|
: defaultResult
|
|
);
|
|
}
|
|
return defaultResult;
|
|
};
|
|
|
|
var getFieldValueAs = (value, { valueAsNumber, valueAsDate, setValueAs }) =>
|
|
isUndefined(value) ? value
|
|
: valueAsNumber ?
|
|
value === "" ? NaN
|
|
: value ? +value
|
|
: value
|
|
: valueAsDate && isString(value) ? new Date(value)
|
|
: setValueAs ? setValueAs(value)
|
|
: value;
|
|
|
|
const defaultReturn = {
|
|
isValid: false,
|
|
value: null,
|
|
};
|
|
var getRadioValue = (options) =>
|
|
Array.isArray(options) ?
|
|
options.reduce(
|
|
(previous, option) =>
|
|
option && option.checked && !option.disabled ?
|
|
{
|
|
isValid: true,
|
|
value: option.value,
|
|
}
|
|
: previous,
|
|
defaultReturn,
|
|
)
|
|
: defaultReturn;
|
|
|
|
function getFieldValue(_f) {
|
|
const ref = _f.ref;
|
|
if (isFileInput(ref)) {
|
|
return ref.files;
|
|
}
|
|
if (isRadioInput(ref)) {
|
|
return getRadioValue(_f.refs).value;
|
|
}
|
|
if (isMultipleSelect(ref)) {
|
|
return [...ref.selectedOptions].map(({ value }) => value);
|
|
}
|
|
if (isCheckBoxInput(ref)) {
|
|
return getCheckboxValue(_f.refs).value;
|
|
}
|
|
return getFieldValueAs(isUndefined(ref.value) ? _f.ref.value : ref.value, _f);
|
|
}
|
|
|
|
var getResolverOptions = (fieldsNames, _fields, criteriaMode, shouldUseNativeValidation) => {
|
|
const fields = {};
|
|
for (const name of fieldsNames) {
|
|
const field = get(_fields, name);
|
|
field && set(fields, name, field._f);
|
|
}
|
|
return {
|
|
criteriaMode,
|
|
names: [...fieldsNames],
|
|
fields,
|
|
shouldUseNativeValidation,
|
|
};
|
|
};
|
|
|
|
var isRegex = (value) => value instanceof RegExp;
|
|
|
|
var getRuleValue = (rule) =>
|
|
isUndefined(rule) ? rule
|
|
: isRegex(rule) ? rule.source
|
|
: isObject(rule) ?
|
|
isRegex(rule.value) ? rule.value.source
|
|
: rule.value
|
|
: rule;
|
|
|
|
var getValidationModes = (mode) => ({
|
|
isOnSubmit: !mode || mode === VALIDATION_MODE.onSubmit,
|
|
isOnBlur: mode === VALIDATION_MODE.onBlur,
|
|
isOnChange: mode === VALIDATION_MODE.onChange,
|
|
isOnAll: mode === VALIDATION_MODE.all,
|
|
isOnTouch: mode === VALIDATION_MODE.onTouched,
|
|
});
|
|
|
|
const ASYNC_FUNCTION = "AsyncFunction";
|
|
var hasPromiseValidation = (fieldReference) => {
|
|
if (!fieldReference || !fieldReference.validate) return false;
|
|
if (isFunction(fieldReference.validate)) {
|
|
return fieldReference.validate.constructor.name === ASYNC_FUNCTION;
|
|
}
|
|
if (isObject(fieldReference.validate)) {
|
|
for (const key in fieldReference.validate) {
|
|
if (fieldReference.validate[key].constructor.name === ASYNC_FUNCTION) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
var hasValidation = (options) => options.mount && (options.required || options.min || options.max || options.maxLength || options.minLength || options.pattern || options.validate);
|
|
|
|
var isWatched = (name, _names, isBlurEvent) => {
|
|
if (isBlurEvent) return false;
|
|
if (_names.watchAll || _names.watch.has(name)) return true;
|
|
for (const watchName of _names.watch) {
|
|
if (name.startsWith(watchName) && name.charAt(watchName.length) === ".") return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
const iterateFieldsByAction = (fields, action, fieldsNames, abortEarly) => {
|
|
for (const key of fieldsNames || Object.keys(fields)) {
|
|
const field = get(fields, key);
|
|
if (field) {
|
|
const { _f, ...currentField } = field;
|
|
if (_f) {
|
|
if (_f.refs && _f.refs[0] && action(_f.refs[0], key) && !abortEarly) {
|
|
return true;
|
|
} else if (_f.ref && action(_f.ref, _f.name) && !abortEarly) {
|
|
return true;
|
|
} else {
|
|
if (iterateFieldsByAction(currentField, action)) {
|
|
break;
|
|
}
|
|
}
|
|
} else if (isObject(currentField)) {
|
|
if (iterateFieldsByAction(currentField, action)) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
};
|
|
|
|
function schemaErrorLookup(errors, _fields, name) {
|
|
const error = get(errors, name);
|
|
if (error || isKey(name)) {
|
|
return {
|
|
error,
|
|
name,
|
|
};
|
|
}
|
|
const names = name.split(".");
|
|
while (names.length) {
|
|
const fieldName = names.join(".");
|
|
const field = get(_fields, fieldName);
|
|
const foundError = get(errors, fieldName);
|
|
if (field && !Array.isArray(field) && name !== fieldName) {
|
|
return { name };
|
|
}
|
|
if (foundError && foundError.type) {
|
|
return {
|
|
name: fieldName,
|
|
error: foundError,
|
|
};
|
|
}
|
|
if (foundError && foundError.root && foundError.root.type) {
|
|
return {
|
|
name: `${fieldName}.root`,
|
|
error: foundError.root,
|
|
};
|
|
}
|
|
names.pop();
|
|
}
|
|
return {
|
|
name,
|
|
};
|
|
}
|
|
|
|
var shouldRenderFormState = (formStateData, _proxyFormState, updateFormState, isRoot) => {
|
|
updateFormState(formStateData);
|
|
const { name, ...formState } = formStateData;
|
|
const keys = Object.keys(formState);
|
|
return !keys.length || (isRoot && keys.length >= Object.keys(_proxyFormState).length) || keys.find((key) => _proxyFormState[key] === (!isRoot || VALIDATION_MODE.all));
|
|
};
|
|
|
|
var shouldSubscribeByName = (name, signalName, exact) =>
|
|
!name ||
|
|
!signalName ||
|
|
name === signalName ||
|
|
convertToArrayPayload(name).some((currentName) => currentName && (exact ? currentName === signalName : currentName.startsWith(signalName) || signalName.startsWith(currentName)));
|
|
|
|
var skipValidation = (isBlurEvent, isTouched, isSubmitted, reValidateMode, mode) => {
|
|
if (mode.isOnAll) {
|
|
return false;
|
|
} else if (!isSubmitted && mode.isOnTouch) {
|
|
return !(isTouched || isBlurEvent);
|
|
} else if (isSubmitted ? reValidateMode.isOnBlur : mode.isOnBlur) {
|
|
return !isBlurEvent;
|
|
} else if (isSubmitted ? reValidateMode.isOnChange : mode.isOnChange) {
|
|
return isBlurEvent;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
var unsetEmptyArray = (ref, name) => !compact(get(ref, name)).length && unset(ref, name);
|
|
|
|
var updateFieldArrayRootError = (errors, error, name) => {
|
|
const existingErrors = get(errors, name);
|
|
const fieldArrayErrors = Array.isArray(existingErrors) ? existingErrors : [];
|
|
set(fieldArrayErrors, ROOT_ERROR_TYPE, error[name]);
|
|
set(errors, name, fieldArrayErrors);
|
|
return errors;
|
|
};
|
|
|
|
function getValidateError(result, ref, type = "validate") {
|
|
if (isString(result) || (Array.isArray(result) && result.every(isString)) || (isBoolean(result) && !result)) {
|
|
return {
|
|
type,
|
|
message: isString(result) ? result : "",
|
|
ref,
|
|
};
|
|
}
|
|
}
|
|
|
|
var getValueAndMessage = (validationData) =>
|
|
isObject(validationData) && !isRegex(validationData) ?
|
|
validationData
|
|
: {
|
|
value: validationData,
|
|
message: "",
|
|
};
|
|
|
|
var validateField = async (field, disabledFieldNames, formValues, validateAllFieldCriteria, shouldUseNativeValidation, isFieldArray) => {
|
|
const { ref, refs, required, maxLength, minLength, min, max, pattern, validate, name, valueAsNumber, mount } = field._f;
|
|
const inputValue = get(formValues, name);
|
|
if (!mount || disabledFieldNames.has(name)) {
|
|
return {};
|
|
}
|
|
const inputRef = refs ? refs[0] : ref;
|
|
const setCustomValidity = (message) => {
|
|
if (shouldUseNativeValidation && inputRef.reportValidity) {
|
|
const validityMessage = isBoolean(message) ? "" : message || "";
|
|
if (refs) {
|
|
refs.forEach((ref) => ref.setCustomValidity(validityMessage));
|
|
} else {
|
|
inputRef.setCustomValidity(validityMessage);
|
|
}
|
|
inputRef.reportValidity();
|
|
}
|
|
};
|
|
const error = {};
|
|
const isRadio = isRadioInput(ref);
|
|
const isCheckBox = isCheckBoxInput(ref);
|
|
const isRadioOrCheckbox = isRadio || isCheckBox;
|
|
const isEmpty =
|
|
((valueAsNumber || isFileInput(ref)) && isUndefined(ref.value) && isUndefined(inputValue)) ||
|
|
(isHTMLElement(ref) && ref.value === "") ||
|
|
inputValue === "" ||
|
|
(Array.isArray(inputValue) && !inputValue.length);
|
|
const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
|
|
const getMinMaxMessage = (exceedMax, maxLengthMessage, minLengthMessage, maxType = INPUT_VALIDATION_RULES.maxLength, minType = INPUT_VALIDATION_RULES.minLength) => {
|
|
const message = exceedMax ? maxLengthMessage : minLengthMessage;
|
|
error[name] = {
|
|
type: exceedMax ? maxType : minType,
|
|
message,
|
|
ref,
|
|
...appendErrorsCurry(exceedMax ? maxType : minType, message),
|
|
};
|
|
};
|
|
if (
|
|
isFieldArray ?
|
|
!Array.isArray(inputValue) || !inputValue.length
|
|
: required &&
|
|
((!isRadioOrCheckbox && (isEmpty || isNullOrUndefined(inputValue))) ||
|
|
(isBoolean(inputValue) && !inputValue) ||
|
|
(isCheckBox && !getCheckboxValue(refs).isValid) ||
|
|
(isRadio && !getRadioValue(refs).isValid))
|
|
) {
|
|
const { value, message } = isString(required) ? { value: !!required, message: required } : getValueAndMessage(required);
|
|
if (value) {
|
|
error[name] = {
|
|
type: INPUT_VALIDATION_RULES.required,
|
|
message,
|
|
ref: inputRef,
|
|
...appendErrorsCurry(INPUT_VALIDATION_RULES.required, message),
|
|
};
|
|
if (!validateAllFieldCriteria) {
|
|
setCustomValidity(message);
|
|
return error;
|
|
}
|
|
}
|
|
}
|
|
if (!isEmpty && (!isNullOrUndefined(min) || !isNullOrUndefined(max))) {
|
|
let exceedMax;
|
|
let exceedMin;
|
|
const maxOutput = getValueAndMessage(max);
|
|
const minOutput = getValueAndMessage(min);
|
|
if (!isNullOrUndefined(inputValue) && !isNaN(inputValue)) {
|
|
const valueNumber = ref.valueAsNumber || (inputValue ? +inputValue : inputValue);
|
|
if (!isNullOrUndefined(maxOutput.value)) {
|
|
exceedMax = valueNumber > maxOutput.value;
|
|
}
|
|
if (!isNullOrUndefined(minOutput.value)) {
|
|
exceedMin = valueNumber < minOutput.value;
|
|
}
|
|
} else {
|
|
const valueDate = ref.valueAsDate || new Date(inputValue);
|
|
const convertTimeToDate = (time) => new Date(new Date().toDateString() + " " + time);
|
|
const isTime = ref.type == "time";
|
|
const isWeek = ref.type == "week";
|
|
if (isString(maxOutput.value) && inputValue) {
|
|
exceedMax =
|
|
isTime ? convertTimeToDate(inputValue) > convertTimeToDate(maxOutput.value)
|
|
: isWeek ? inputValue > maxOutput.value
|
|
: valueDate > new Date(maxOutput.value);
|
|
}
|
|
if (isString(minOutput.value) && inputValue) {
|
|
exceedMin =
|
|
isTime ? convertTimeToDate(inputValue) < convertTimeToDate(minOutput.value)
|
|
: isWeek ? inputValue < minOutput.value
|
|
: valueDate < new Date(minOutput.value);
|
|
}
|
|
}
|
|
if (exceedMax || exceedMin) {
|
|
getMinMaxMessage(!!exceedMax, maxOutput.message, minOutput.message, INPUT_VALIDATION_RULES.max, INPUT_VALIDATION_RULES.min);
|
|
if (!validateAllFieldCriteria) {
|
|
setCustomValidity(error[name].message);
|
|
return error;
|
|
}
|
|
}
|
|
}
|
|
if ((maxLength || minLength) && !isEmpty && (isString(inputValue) || (isFieldArray && Array.isArray(inputValue)))) {
|
|
const maxLengthOutput = getValueAndMessage(maxLength);
|
|
const minLengthOutput = getValueAndMessage(minLength);
|
|
const exceedMax = !isNullOrUndefined(maxLengthOutput.value) && inputValue.length > +maxLengthOutput.value;
|
|
const exceedMin = !isNullOrUndefined(minLengthOutput.value) && inputValue.length < +minLengthOutput.value;
|
|
if (exceedMax || exceedMin) {
|
|
getMinMaxMessage(exceedMax, maxLengthOutput.message, minLengthOutput.message);
|
|
if (!validateAllFieldCriteria) {
|
|
setCustomValidity(error[name].message);
|
|
return error;
|
|
}
|
|
}
|
|
}
|
|
if (pattern && !isEmpty && isString(inputValue)) {
|
|
const { value: patternValue, message } = getValueAndMessage(pattern);
|
|
if (isRegex(patternValue) && !inputValue.match(patternValue)) {
|
|
error[name] = {
|
|
type: INPUT_VALIDATION_RULES.pattern,
|
|
message,
|
|
ref,
|
|
...appendErrorsCurry(INPUT_VALIDATION_RULES.pattern, message),
|
|
};
|
|
if (!validateAllFieldCriteria) {
|
|
setCustomValidity(message);
|
|
return error;
|
|
}
|
|
}
|
|
}
|
|
if (validate) {
|
|
if (isFunction(validate)) {
|
|
const result = await validate(inputValue, formValues);
|
|
const validateError = getValidateError(result, inputRef);
|
|
if (validateError) {
|
|
error[name] = {
|
|
...validateError,
|
|
...appendErrorsCurry(INPUT_VALIDATION_RULES.validate, validateError.message),
|
|
};
|
|
if (!validateAllFieldCriteria) {
|
|
setCustomValidity(validateError.message);
|
|
return error;
|
|
}
|
|
}
|
|
} else if (isObject(validate)) {
|
|
let validationResult = {};
|
|
for (const key in validate) {
|
|
if (!isEmptyObject(validationResult) && !validateAllFieldCriteria) {
|
|
break;
|
|
}
|
|
const validateError = getValidateError(await validate[key](inputValue, formValues), inputRef, key);
|
|
if (validateError) {
|
|
validationResult = {
|
|
...validateError,
|
|
...appendErrorsCurry(key, validateError.message),
|
|
};
|
|
setCustomValidity(validateError.message);
|
|
if (validateAllFieldCriteria) {
|
|
error[name] = validationResult;
|
|
}
|
|
}
|
|
}
|
|
if (!isEmptyObject(validationResult)) {
|
|
error[name] = {
|
|
ref: inputRef,
|
|
...validationResult,
|
|
};
|
|
if (!validateAllFieldCriteria) {
|
|
return error;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
setCustomValidity(true);
|
|
return error;
|
|
};
|
|
|
|
const defaultOptions = {
|
|
mode: VALIDATION_MODE.onSubmit,
|
|
reValidateMode: VALIDATION_MODE.onChange,
|
|
shouldFocusError: true,
|
|
};
|
|
const FORM_ERROR_TYPE = "form";
|
|
const DEFAULT_FORM_STATE = {
|
|
submitCount: 0,
|
|
isDirty: false,
|
|
isReady: false,
|
|
isValidating: false,
|
|
isSubmitted: false,
|
|
isSubmitting: false,
|
|
isSubmitSuccessful: false,
|
|
isValid: false,
|
|
touchedFields: {},
|
|
dirtyFields: {},
|
|
validatingFields: {},
|
|
};
|
|
function createFormControl(props = {}) {
|
|
let _options = {
|
|
...defaultOptions,
|
|
...props,
|
|
};
|
|
let _formState = {
|
|
...cloneObject(DEFAULT_FORM_STATE),
|
|
isLoading: isFunction(_options.defaultValues),
|
|
errors: _options.errors || {},
|
|
disabled: _options.disabled || false,
|
|
};
|
|
let _fields = {};
|
|
let _defaultValues = isObject(_options.defaultValues) || isObject(_options.values) ? cloneObject(_options.defaultValues || _options.values) || {} : {};
|
|
let _formValues = _options.shouldUnregister ? {} : cloneObject(_defaultValues);
|
|
let _state = {
|
|
action: false,
|
|
mount: false,
|
|
watch: false,
|
|
keepIsValid: false,
|
|
};
|
|
let _names = {
|
|
mount: new Set(),
|
|
disabled: new Set(),
|
|
unMount: new Set(),
|
|
array: new Set(),
|
|
watch: new Set(),
|
|
registerName: new Set(),
|
|
};
|
|
let delayErrorCallback;
|
|
let timer = 0;
|
|
let _valuesSubscriberCount = 0;
|
|
let _validationModeBeforeSubmit = getValidationModes(_options.mode);
|
|
let _validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
|
|
const defaultProxyFormState = {
|
|
isDirty: false,
|
|
dirtyFields: false,
|
|
validatingFields: false,
|
|
touchedFields: false,
|
|
isValidating: false,
|
|
isValid: false,
|
|
errors: false,
|
|
};
|
|
const _proxyFormState = {
|
|
...defaultProxyFormState,
|
|
};
|
|
let _proxySubscribeFormState = {
|
|
..._proxyFormState,
|
|
};
|
|
const _subjects = {
|
|
array: createSubject(),
|
|
state: createSubject(),
|
|
};
|
|
const shouldDisplayAllAssociatedErrors = _options.criteriaMode === VALIDATION_MODE.all;
|
|
const debounce = (callback) => (wait) => {
|
|
clearTimeout(timer);
|
|
timer = setTimeout(callback, wait);
|
|
};
|
|
const _setValid = async (shouldUpdateValid) => {
|
|
if (_state.keepIsValid) {
|
|
return;
|
|
}
|
|
if (!_options.disabled && (_proxyFormState.isValid || _proxySubscribeFormState.isValid || shouldUpdateValid)) {
|
|
let isValid;
|
|
if (_options.resolver) {
|
|
isValid = isEmptyObject((await _runSchema()).errors);
|
|
_updateIsValidating();
|
|
} else {
|
|
isValid = await executeBuiltInValidation({
|
|
fields: _fields,
|
|
onlyCheckValid: true,
|
|
eventType: EVENTS.VALID,
|
|
});
|
|
}
|
|
if (isValid !== _formState.isValid) {
|
|
_subjects.state.next({
|
|
isValid,
|
|
});
|
|
}
|
|
}
|
|
};
|
|
const _updateIsValidating = (names, isValidating) => {
|
|
if (!_options.disabled && (_proxyFormState.isValidating || _proxyFormState.validatingFields || _proxySubscribeFormState.isValidating || _proxySubscribeFormState.validatingFields)) {
|
|
(names || Array.from(_names.mount)).forEach((name) => {
|
|
if (name) {
|
|
isValidating ? set(_formState.validatingFields, name, isValidating) : unset(_formState.validatingFields, name);
|
|
}
|
|
});
|
|
_subjects.state.next({
|
|
validatingFields: _formState.validatingFields,
|
|
isValidating: !isEmptyObject(_formState.validatingFields),
|
|
});
|
|
}
|
|
};
|
|
const _updateDirtyFields = () => {
|
|
_formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
|
|
};
|
|
const _setFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
|
|
if (args && method && !_options.disabled) {
|
|
_state.action = true;
|
|
if (shouldUpdateFieldsAndState && Array.isArray(get(_fields, name))) {
|
|
const fieldValues = method(get(_fields, name), args.argA, args.argB);
|
|
shouldSetValues && set(_fields, name, fieldValues);
|
|
}
|
|
if (shouldUpdateFieldsAndState && Array.isArray(get(_formState.errors, name))) {
|
|
const errors = method(get(_formState.errors, name), args.argA, args.argB);
|
|
shouldSetValues && set(_formState.errors, name, errors);
|
|
unsetEmptyArray(_formState.errors, name);
|
|
}
|
|
if ((_proxyFormState.touchedFields || _proxySubscribeFormState.touchedFields) && shouldUpdateFieldsAndState && Array.isArray(get(_formState.touchedFields, name))) {
|
|
const touchedFields = method(get(_formState.touchedFields, name), args.argA, args.argB);
|
|
shouldSetValues && set(_formState.touchedFields, name, touchedFields);
|
|
}
|
|
if (_proxyFormState.dirtyFields || _proxySubscribeFormState.dirtyFields) {
|
|
_updateDirtyFields();
|
|
}
|
|
_subjects.state.next({
|
|
name,
|
|
isDirty: _getDirty(name, values),
|
|
dirtyFields: _formState.dirtyFields,
|
|
errors: _formState.errors,
|
|
isValid: _formState.isValid,
|
|
});
|
|
} else {
|
|
set(_formValues, name, values);
|
|
}
|
|
};
|
|
const updateErrors = (name, error) => {
|
|
set(_formState.errors, name, error);
|
|
_formState.errors = { ..._formState.errors };
|
|
_subjects.state.next({
|
|
errors: _formState.errors,
|
|
});
|
|
};
|
|
const _setErrors = (errors) => {
|
|
_formState.errors = errors;
|
|
_subjects.state.next({
|
|
errors: _formState.errors,
|
|
isValid: false,
|
|
});
|
|
};
|
|
const hasExplicitNullIntermediate = (name) => {
|
|
const segments = isKey(name) ? [name] : stringToPath(name);
|
|
let formValues = _formValues;
|
|
let defaultValues = _defaultValues;
|
|
for (let i = 0; i < segments.length - 1; i++) {
|
|
const key = segments[i];
|
|
formValues = isNullOrUndefined(formValues) ? formValues : formValues[key];
|
|
defaultValues = isNullOrUndefined(defaultValues) ? defaultValues : defaultValues[key];
|
|
if (formValues === null && defaultValues !== null) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
const updateValidAndValue = (name, shouldSkipSetValueAs, value, ref) => {
|
|
const field = get(_fields, name);
|
|
if (field) {
|
|
if (hasExplicitNullIntermediate(name)) {
|
|
return;
|
|
}
|
|
const wasUnsetInFormValues = isUndefined(get(_formValues, name));
|
|
const defaultValue = get(_formValues, name, isUndefined(value) ? get(_defaultValues, name) : value);
|
|
isUndefined(defaultValue) || (ref && ref.defaultChecked) || shouldSkipSetValueAs ?
|
|
set(_formValues, name, shouldSkipSetValueAs ? defaultValue : getFieldValue(field._f))
|
|
: setFieldValue(name, defaultValue);
|
|
if (_state.mount && !_state.action) {
|
|
_setValid();
|
|
if (wasUnsetInFormValues && _formState.isDirty && (_proxyFormState.isDirty || _proxySubscribeFormState.isDirty)) {
|
|
const isDirty = _getDirty();
|
|
if (!isDirty) {
|
|
_formState.isDirty = false;
|
|
_subjects.state.next({ ..._formState });
|
|
}
|
|
}
|
|
if (props.shouldUnregister && wasUnsetInFormValues && !isUndefined(get(_formValues, name)) && isWatched(name, _names)) {
|
|
_state.watch = true;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
|
|
let shouldUpdateField = false;
|
|
let isPreviousDirty = false;
|
|
const output = {
|
|
name,
|
|
};
|
|
if (!_options.disabled) {
|
|
if (!isBlurEvent || shouldDirty) {
|
|
const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
|
|
if (_proxyFormState.isDirty || _proxySubscribeFormState.isDirty) {
|
|
isPreviousDirty = _formState.isDirty;
|
|
_formState.isDirty = output.isDirty = !isCurrentFieldPristine || _getDirty();
|
|
shouldUpdateField = isPreviousDirty !== output.isDirty;
|
|
}
|
|
isPreviousDirty = !!get(_formState.dirtyFields, name);
|
|
if (isCurrentFieldPristine !== _formState.isDirty) {
|
|
_formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
|
|
} else {
|
|
isCurrentFieldPristine ? unset(_formState.dirtyFields, name) : set(_formState.dirtyFields, name, true);
|
|
}
|
|
output.dirtyFields = _formState.dirtyFields;
|
|
shouldUpdateField = shouldUpdateField || ((_proxyFormState.dirtyFields || _proxySubscribeFormState.dirtyFields) && isPreviousDirty !== !isCurrentFieldPristine);
|
|
}
|
|
if (isBlurEvent) {
|
|
const isPreviousFieldTouched = get(_formState.touchedFields, name);
|
|
if (!isPreviousFieldTouched) {
|
|
set(_formState.touchedFields, name, isBlurEvent);
|
|
output.touchedFields = _formState.touchedFields;
|
|
shouldUpdateField = shouldUpdateField || ((_proxyFormState.touchedFields || _proxySubscribeFormState.touchedFields) && isPreviousFieldTouched !== isBlurEvent);
|
|
}
|
|
}
|
|
shouldUpdateField && shouldRender && _subjects.state.next(output);
|
|
}
|
|
return shouldUpdateField ? output : {};
|
|
};
|
|
const shouldRenderByError = (name, isValid, error, fieldState) => {
|
|
const previousFieldError = get(_formState.errors, name);
|
|
const shouldUpdateValid = (_proxyFormState.isValid || _proxySubscribeFormState.isValid) && isBoolean(isValid) && _formState.isValid !== isValid;
|
|
if (_options.delayError && error) {
|
|
delayErrorCallback = debounce(() => updateErrors(name, error));
|
|
delayErrorCallback(_options.delayError);
|
|
} else {
|
|
clearTimeout(timer);
|
|
delayErrorCallback = null;
|
|
error ? set(_formState.errors, name, error) : unset(_formState.errors, name);
|
|
_formState.errors = { ..._formState.errors };
|
|
}
|
|
if ((error ? !deepEqual(previousFieldError, error) : previousFieldError) || !isEmptyObject(fieldState) || shouldUpdateValid) {
|
|
const updatedFormState = {
|
|
...fieldState,
|
|
...(shouldUpdateValid && isBoolean(isValid) ? { isValid } : {}),
|
|
errors: _formState.errors,
|
|
name,
|
|
};
|
|
_formState = {
|
|
..._formState,
|
|
...updatedFormState,
|
|
};
|
|
_subjects.state.next(updatedFormState);
|
|
}
|
|
};
|
|
const _runSchema = async (name) => {
|
|
_updateIsValidating(name, true);
|
|
return await _options.resolver(_formValues, _options.context, getResolverOptions(name || _names.mount, _fields, _options.criteriaMode, _options.shouldUseNativeValidation));
|
|
};
|
|
const executeSchemaAndUpdateState = async (names) => {
|
|
const { errors } = await _runSchema(names);
|
|
_updateIsValidating(names);
|
|
if (names) {
|
|
for (const name of names) {
|
|
const error = get(errors, name);
|
|
error ?
|
|
_names.array.has(name) && isObject(error) && !Object.keys(error).some((key) => !Number.isNaN(Number(key))) ?
|
|
updateFieldArrayRootError(_formState.errors, { [name]: error }, name)
|
|
: set(_formState.errors, name, error)
|
|
: unset(_formState.errors, name);
|
|
}
|
|
_formState.errors = { ..._formState.errors };
|
|
} else {
|
|
_formState.errors = errors;
|
|
}
|
|
return errors;
|
|
};
|
|
const validateForm = async ({ name, eventType }) => {
|
|
if (props.validate) {
|
|
const result = await props.validate({
|
|
formValues: _formValues,
|
|
formState: _formState,
|
|
name,
|
|
eventType,
|
|
});
|
|
if (isObject(result)) {
|
|
for (const key in result) {
|
|
const error = result[key];
|
|
if (error) {
|
|
setError(`${FORM_ERROR_TYPE}.${key}`, {
|
|
message: isString(error.message) ? error.message : "",
|
|
type: error.type || INPUT_VALIDATION_RULES.validate,
|
|
});
|
|
}
|
|
}
|
|
} else if (isString(result) || !result) {
|
|
setError(FORM_ERROR_TYPE, {
|
|
message: result || "",
|
|
type: INPUT_VALIDATION_RULES.validate,
|
|
});
|
|
} else {
|
|
clearErrors(FORM_ERROR_TYPE);
|
|
}
|
|
return result;
|
|
}
|
|
return true;
|
|
};
|
|
const executeBuiltInValidation = async ({
|
|
fields,
|
|
onlyCheckValid,
|
|
name,
|
|
eventType,
|
|
context = {
|
|
valid: true,
|
|
runRootValidation: false,
|
|
},
|
|
}) => {
|
|
if (props.validate) {
|
|
context.runRootValidation = true;
|
|
const result = await validateForm({
|
|
name,
|
|
eventType,
|
|
});
|
|
if (!result) {
|
|
context.valid = false;
|
|
if (onlyCheckValid) {
|
|
return context.valid;
|
|
}
|
|
}
|
|
}
|
|
for (const name in fields) {
|
|
const field = fields[name];
|
|
if (field) {
|
|
const { _f, ...fieldValue } = field;
|
|
if (_f) {
|
|
const isFieldArrayRoot = _names.array.has(_f.name);
|
|
const isPromiseFunction = field._f && hasPromiseValidation(field._f);
|
|
const shouldTrackIsValidatingState =
|
|
_proxyFormState.validatingFields || _proxyFormState.isValidating || _proxySubscribeFormState.validatingFields || _proxySubscribeFormState.isValidating;
|
|
if (isPromiseFunction && shouldTrackIsValidatingState) {
|
|
_updateIsValidating([_f.name], true);
|
|
}
|
|
const fieldError = await validateField(
|
|
field,
|
|
_names.disabled,
|
|
_formValues,
|
|
shouldDisplayAllAssociatedErrors,
|
|
_options.shouldUseNativeValidation && !onlyCheckValid,
|
|
isFieldArrayRoot,
|
|
);
|
|
if (isPromiseFunction && shouldTrackIsValidatingState) {
|
|
_updateIsValidating([_f.name]);
|
|
}
|
|
if (fieldError[_f.name]) {
|
|
context.valid = false;
|
|
if (onlyCheckValid) {
|
|
break;
|
|
}
|
|
}
|
|
!onlyCheckValid &&
|
|
(get(fieldError, _f.name) ?
|
|
isFieldArrayRoot ? updateFieldArrayRootError(_formState.errors, fieldError, _f.name)
|
|
: set(_formState.errors, _f.name, fieldError[_f.name])
|
|
: unset(_formState.errors, _f.name));
|
|
if (props.shouldUseNativeValidation && fieldError[_f.name]) {
|
|
break;
|
|
}
|
|
}
|
|
!isEmptyObject(fieldValue) &&
|
|
(await executeBuiltInValidation({
|
|
context,
|
|
onlyCheckValid,
|
|
fields: fieldValue,
|
|
name: name,
|
|
eventType,
|
|
}));
|
|
}
|
|
}
|
|
return context.valid;
|
|
};
|
|
const _removeUnmounted = () => {
|
|
for (const name of _names.unMount) {
|
|
const field = get(_fields, name);
|
|
field && (field._f.refs ? field._f.refs.every((ref) => !live(ref)) : !live(field._f.ref)) && unregister(name);
|
|
}
|
|
_names.unMount = new Set();
|
|
};
|
|
const _getDirty = (name, data) => !_options.disabled && (name && data && set(_formValues, name, data), !deepEqual(_state.mount ? _formValues : _defaultValues, _defaultValues));
|
|
const _getWatch = (names, defaultValue, isGlobal) =>
|
|
generateWatchOutput(
|
|
names,
|
|
_names,
|
|
{
|
|
...(_state.mount ? _formValues
|
|
: isUndefined(defaultValue) ? _defaultValues
|
|
: isString(names) ? { [names]: defaultValue }
|
|
: defaultValue),
|
|
},
|
|
isGlobal,
|
|
defaultValue,
|
|
);
|
|
const _getFieldArray = (name) => compact(get(_state.mount ? _formValues : _defaultValues, name, _options.shouldUnregister ? get(_defaultValues, name, []) : []));
|
|
const setFieldValue = (name, value, options = {}, skipClone = false, skipRender = false) => {
|
|
const field = get(_fields, name);
|
|
let fieldValue = value;
|
|
if (field) {
|
|
const fieldReference = field._f;
|
|
if (fieldReference) {
|
|
!fieldReference.disabled && set(_formValues, name, getFieldValueAs(value, fieldReference));
|
|
fieldValue = isHTMLElement(fieldReference.ref) && isNullOrUndefined(value) ? "" : value;
|
|
if (isMultipleSelect(fieldReference.ref)) {
|
|
[...fieldReference.ref.options].forEach((optionRef) => (optionRef.selected = fieldValue.includes(optionRef.value)));
|
|
} else if (fieldReference.refs) {
|
|
if (isCheckBoxInput(fieldReference.ref)) {
|
|
fieldReference.refs.forEach((checkboxRef) => {
|
|
if (!checkboxRef.defaultChecked || !checkboxRef.disabled) {
|
|
if (Array.isArray(fieldValue)) {
|
|
checkboxRef.checked = !!fieldValue.find((data) => data === checkboxRef.value);
|
|
} else {
|
|
checkboxRef.checked = fieldValue === checkboxRef.value || !!fieldValue;
|
|
}
|
|
}
|
|
});
|
|
} else {
|
|
fieldReference.refs.forEach((radioRef) => (radioRef.checked = radioRef.value === fieldValue));
|
|
}
|
|
} else if (isFileInput(fieldReference.ref)) {
|
|
fieldReference.ref.value = "";
|
|
} else {
|
|
fieldReference.ref.value = fieldValue;
|
|
if (!fieldReference.ref.type && !skipRender) {
|
|
_subjects.state.next({
|
|
name,
|
|
values: skipClone ? _formValues : cloneObject(_formValues),
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
(options.shouldDirty || options.shouldTouch) && updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, !skipRender);
|
|
options.shouldValidate && trigger(name);
|
|
};
|
|
const setFieldValues = (name, value, options, skipClone = false, skipRender = false) => {
|
|
for (const fieldKey in value) {
|
|
if (!value.hasOwnProperty(fieldKey)) {
|
|
return;
|
|
}
|
|
const fieldValue = value[fieldKey];
|
|
const fieldName = name + "." + fieldKey;
|
|
const field = get(_fields, fieldName);
|
|
(_names.array.has(name) || isObject(fieldValue) || (field && !field._f)) && !isDateObject(fieldValue) ?
|
|
setFieldValues(fieldName, fieldValue, options, skipClone, skipRender)
|
|
: setFieldValue(fieldName, fieldValue, options, skipClone, skipRender);
|
|
}
|
|
};
|
|
const _setValue = (name, value, options, skipClone, skipStateEmit = false) => {
|
|
const field = get(_fields, name);
|
|
const isFieldArray = _names.array.has(name);
|
|
const cloneValue = skipClone ? value : cloneObject(value);
|
|
const previousValue = get(_formValues, name);
|
|
const isValueUnchanged = deepEqual(previousValue, cloneValue);
|
|
if (!isValueUnchanged) {
|
|
set(_formValues, name, cloneValue);
|
|
}
|
|
if (isFieldArray) {
|
|
_subjects.array.next({
|
|
name,
|
|
values: skipClone ? _formValues : cloneObject(_formValues),
|
|
});
|
|
if ((_proxyFormState.isDirty || _proxyFormState.dirtyFields || _proxySubscribeFormState.isDirty || _proxySubscribeFormState.dirtyFields) && options.shouldDirty) {
|
|
_updateDirtyFields();
|
|
if (!skipStateEmit) {
|
|
_subjects.state.next({
|
|
name,
|
|
dirtyFields: _formState.dirtyFields,
|
|
isDirty: _getDirty(name, cloneValue),
|
|
});
|
|
}
|
|
}
|
|
} else {
|
|
const isEmpty = (Array.isArray(cloneValue) && !cloneValue.length) || isEmptyObject(cloneValue);
|
|
if (!field || field._f || isNullOrUndefined(cloneValue) || isEmpty) {
|
|
setFieldValue(name, cloneValue, options, skipClone, skipStateEmit);
|
|
} else {
|
|
setFieldValues(name, cloneValue, options, skipClone, skipStateEmit);
|
|
}
|
|
}
|
|
if (!isValueUnchanged && !skipStateEmit) {
|
|
const watched = isWatched(name, _names);
|
|
const values = skipClone ? _formValues : cloneObject(_formValues);
|
|
_subjects.state.next({
|
|
...(watched && _formState),
|
|
name: _state.mount || watched ? name : undefined,
|
|
values,
|
|
});
|
|
}
|
|
};
|
|
const setValue = (name, value, options = {}) => _setValue(name, value, options, false);
|
|
const setValues = (formValues, options = {}) => {
|
|
const updatedFormValues = isFunction(formValues) ? formValues(_formValues) : formValues;
|
|
if (!deepEqual(_formValues, updatedFormValues)) {
|
|
_formValues = {
|
|
..._formValues,
|
|
...updatedFormValues,
|
|
};
|
|
for (const fieldName of _names.mount) {
|
|
_setValue(fieldName, get(updatedFormValues, fieldName), options, true, true);
|
|
}
|
|
_subjects.state.next({
|
|
..._formState,
|
|
name: undefined,
|
|
type: undefined,
|
|
...(_valuesSubscriberCount ? { values: _formValues } : {}),
|
|
});
|
|
if (options.shouldValidate) {
|
|
_setValid();
|
|
}
|
|
}
|
|
};
|
|
const onChange = async (event) => {
|
|
_state.mount = true;
|
|
const target = event.target;
|
|
let name = target.name;
|
|
let isFieldValueUpdated = true;
|
|
const field = get(_fields, name);
|
|
const _updateIsFieldValueUpdated = (fieldValue) => {
|
|
isFieldValueUpdated = Number.isNaN(fieldValue) || (isDateObject(fieldValue) && isNaN(fieldValue.getTime())) || deepEqual(fieldValue, get(_formValues, name, fieldValue));
|
|
};
|
|
if (field) {
|
|
let error;
|
|
let isValid;
|
|
const fieldValue = target.type ? getFieldValue(field._f) : getEventValue(event);
|
|
const isBlurEvent = event.type === EVENTS.BLUR || event.type === EVENTS.FOCUS_OUT;
|
|
const hasNoValidationEffect = !hasValidation(field._f) && !props.validate && !_options.resolver && !get(_formState.errors, name) && !field._f.deps;
|
|
const shouldSkipValidation =
|
|
hasNoValidationEffect || skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, _validationModeAfterSubmit, _validationModeBeforeSubmit);
|
|
const watched = isWatched(name, _names, isBlurEvent);
|
|
set(_formValues, name, fieldValue);
|
|
if (isBlurEvent) {
|
|
if (!target || !target.readOnly) {
|
|
field._f.onBlur && field._f.onBlur(event);
|
|
delayErrorCallback && delayErrorCallback(0);
|
|
}
|
|
} else if (field._f.onChange) {
|
|
field._f.onChange(event);
|
|
}
|
|
const fieldState = updateTouchAndDirty(name, fieldValue, isBlurEvent);
|
|
const shouldRender = !isEmptyObject(fieldState) || watched;
|
|
!isBlurEvent &&
|
|
_subjects.state.next({
|
|
name,
|
|
type: event.type,
|
|
...(_valuesSubscriberCount ? { values: cloneObject(_formValues) } : {}),
|
|
});
|
|
if (shouldSkipValidation) {
|
|
if ((!hasNoValidationEffect || !_formState.isValid) && (_proxyFormState.isValid || _proxySubscribeFormState.isValid)) {
|
|
if (_options.mode === "onBlur") {
|
|
if (isBlurEvent) {
|
|
_setValid();
|
|
}
|
|
} else if (!isBlurEvent) {
|
|
_setValid();
|
|
}
|
|
}
|
|
return shouldRender && _subjects.state.next({ name, ...(watched ? {} : fieldState) });
|
|
}
|
|
if (!_options.resolver && props.validate) {
|
|
await validateForm({
|
|
name: name,
|
|
eventType: event.type,
|
|
});
|
|
}
|
|
!isBlurEvent && watched && _subjects.state.next({ ..._formState });
|
|
if (_options.resolver) {
|
|
const { errors } = await _runSchema([name]);
|
|
_updateIsValidating([name]);
|
|
_updateIsFieldValueUpdated(fieldValue);
|
|
if (!isFieldValueUpdated) {
|
|
!isEmptyObject(fieldState) && _subjects.state.next(fieldState);
|
|
return;
|
|
}
|
|
const previousErrorLookupResult = schemaErrorLookup(_formState.errors, _fields, name);
|
|
const errorLookupResult = schemaErrorLookup(errors, _fields, previousErrorLookupResult.name || name);
|
|
error = errorLookupResult.error;
|
|
name = errorLookupResult.name;
|
|
isValid = isEmptyObject(errors);
|
|
} else {
|
|
_updateIsValidating([name], true);
|
|
error = (await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation))[name];
|
|
_updateIsValidating([name]);
|
|
_updateIsFieldValueUpdated(fieldValue);
|
|
if (isFieldValueUpdated) {
|
|
if (error) {
|
|
isValid = false;
|
|
} else if (_proxyFormState.isValid || _proxySubscribeFormState.isValid) {
|
|
isValid = await executeBuiltInValidation({
|
|
fields: _fields,
|
|
onlyCheckValid: true,
|
|
name: name,
|
|
eventType: event.type,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
if (isFieldValueUpdated) {
|
|
field._f.deps && (!Array.isArray(field._f.deps) || field._f.deps.length > 0) && trigger(field._f.deps);
|
|
shouldRenderByError(name, isValid, error, fieldState);
|
|
}
|
|
}
|
|
};
|
|
const _focusInput = (ref, key) => {
|
|
if (get(_formState.errors, key) && ref.focus) {
|
|
ref.focus();
|
|
return 1;
|
|
}
|
|
return;
|
|
};
|
|
const trigger = async (name, options = {}) => {
|
|
let isValid;
|
|
let validationResult;
|
|
const fieldNames = convertToArrayPayload(name);
|
|
if (_options.resolver) {
|
|
const errors = await executeSchemaAndUpdateState(isUndefined(name) ? name : fieldNames);
|
|
isValid = isEmptyObject(errors);
|
|
validationResult = name ? !fieldNames.some((name) => get(errors, name)) : isValid;
|
|
} else if (name) {
|
|
validationResult = (
|
|
await Promise.all(
|
|
fieldNames.map(async (fieldName) => {
|
|
const field = get(_fields, fieldName);
|
|
return await executeBuiltInValidation({
|
|
fields: field && field._f ? { [fieldName]: field } : field,
|
|
eventType: EVENTS.TRIGGER,
|
|
});
|
|
}),
|
|
)
|
|
).every(Boolean);
|
|
!(!validationResult && !_formState.isValid) && _setValid();
|
|
} else {
|
|
validationResult = isValid = await executeBuiltInValidation({
|
|
fields: _fields,
|
|
name,
|
|
eventType: EVENTS.TRIGGER,
|
|
});
|
|
}
|
|
_subjects.state.next({
|
|
...(!isString(name) || ((_proxyFormState.isValid || _proxySubscribeFormState.isValid) && isValid !== _formState.isValid) ? {} : { name }),
|
|
...(_options.resolver || !name ? { isValid } : {}),
|
|
errors: _formState.errors,
|
|
});
|
|
options.shouldFocus && !validationResult && iterateFieldsByAction(_fields, _focusInput, name ? fieldNames : _names.mount);
|
|
return validationResult;
|
|
};
|
|
const getValues = (fieldNames, config) => {
|
|
let values = {
|
|
...(_state.mount ? _formValues : _defaultValues),
|
|
};
|
|
if (config) {
|
|
values = extractFormValues(config.dirtyFields ? _formState.dirtyFields : _formState.touchedFields, values);
|
|
}
|
|
return (
|
|
isUndefined(fieldNames) ? values
|
|
: isString(fieldNames) ? get(values, fieldNames)
|
|
: fieldNames.map((name) => get(values, name))
|
|
);
|
|
};
|
|
const getFieldState = (name, formState) => ({
|
|
invalid: !!get((formState || _formState).errors, name),
|
|
isDirty: !!get((formState || _formState).dirtyFields, name),
|
|
error: get((formState || _formState).errors, name),
|
|
isValidating: !!get(_formState.validatingFields, name),
|
|
isTouched: !!get((formState || _formState).touchedFields, name),
|
|
});
|
|
const clearErrors = (name) => {
|
|
const names = name ? convertToArrayPayload(name) : undefined;
|
|
names === null || names === void 0 ? void 0 : names.forEach((inputName) => unset(_formState.errors, inputName));
|
|
if (names) {
|
|
names.forEach((inputName) => {
|
|
_subjects.state.next({
|
|
name: inputName,
|
|
errors: _formState.errors,
|
|
});
|
|
});
|
|
} else {
|
|
_subjects.state.next({
|
|
errors: {},
|
|
});
|
|
}
|
|
};
|
|
const setError = (name, error, options) => {
|
|
const ref = (get(_fields, name, { _f: {} })._f || {}).ref;
|
|
const currentError = get(_formState.errors, name) || {};
|
|
const { ref: currentRef, message, type, ...restOfErrorTree } = currentError;
|
|
set(_formState.errors, name, {
|
|
...restOfErrorTree,
|
|
...error,
|
|
ref,
|
|
});
|
|
_subjects.state.next({
|
|
name,
|
|
errors: _formState.errors,
|
|
isValid: false,
|
|
});
|
|
options && options.shouldFocus && ref && ref.focus && ref.focus();
|
|
};
|
|
const watch = (name, defaultValue) => {
|
|
if (isFunction(name)) {
|
|
_valuesSubscriberCount++;
|
|
const { unsubscribe } = _subjects.state.subscribe({
|
|
next: (payload) => "values" in payload && name(payload.values || _getWatch(undefined, defaultValue), payload),
|
|
});
|
|
let called = false;
|
|
return {
|
|
unsubscribe: () => {
|
|
if (called) {
|
|
return;
|
|
}
|
|
called = true;
|
|
_valuesSubscriberCount--;
|
|
unsubscribe();
|
|
},
|
|
};
|
|
}
|
|
return _getWatch(name, defaultValue, true);
|
|
};
|
|
const _subscribe = (props) => {
|
|
var _a;
|
|
const needsValues = !!((_a = props.formState) === null || _a === void 0 ? void 0 : _a.values);
|
|
if (needsValues) {
|
|
_valuesSubscriberCount++;
|
|
}
|
|
const { unsubscribe } = _subjects.state.subscribe({
|
|
next: (formState) => {
|
|
if (shouldSubscribeByName(props.name, formState.name, props.exact) && shouldRenderFormState(formState, props.formState || _proxyFormState, _setFormState, props.reRenderRoot)) {
|
|
const snapshot = { ..._formValues };
|
|
props.callback({
|
|
values: snapshot,
|
|
..._formState,
|
|
...formState,
|
|
defaultValues: _defaultValues,
|
|
});
|
|
}
|
|
},
|
|
});
|
|
if (!needsValues) {
|
|
return unsubscribe;
|
|
}
|
|
let called = false;
|
|
return () => {
|
|
if (called) {
|
|
return;
|
|
}
|
|
called = true;
|
|
_valuesSubscriberCount--;
|
|
unsubscribe();
|
|
};
|
|
};
|
|
const subscribe = (props) => {
|
|
_state.mount = true;
|
|
_proxySubscribeFormState = {
|
|
..._proxySubscribeFormState,
|
|
...props.formState,
|
|
};
|
|
return _subscribe({
|
|
...props,
|
|
formState: {
|
|
...defaultProxyFormState,
|
|
...props.formState,
|
|
},
|
|
});
|
|
};
|
|
const unregister = (name, options = {}) => {
|
|
for (const fieldName of name ? convertToArrayPayload(name) : _names.mount) {
|
|
_names.mount.delete(fieldName);
|
|
_names.array.delete(fieldName);
|
|
if (!options.keepValue) {
|
|
unset(_fields, fieldName);
|
|
unset(_formValues, fieldName);
|
|
}
|
|
!options.keepError && unset(_formState.errors, fieldName);
|
|
!options.keepDirty && unset(_formState.dirtyFields, fieldName);
|
|
!options.keepTouched && unset(_formState.touchedFields, fieldName);
|
|
!options.keepIsValidating && unset(_formState.validatingFields, fieldName);
|
|
!_options.shouldUnregister && !options.keepDefaultValue && unset(_defaultValues, fieldName);
|
|
}
|
|
_subjects.state.next({
|
|
values: cloneObject(_formValues),
|
|
});
|
|
_subjects.state.next({
|
|
..._formState,
|
|
...(!options.keepDirty ? {} : { isDirty: _getDirty() }),
|
|
});
|
|
!options.keepIsValid && _setValid();
|
|
};
|
|
const _setDisabledField = ({ disabled, name }) => {
|
|
if ((isBoolean(disabled) && _state.mount) || !!disabled || _names.disabled.has(name)) {
|
|
const wasDisabled = _names.disabled.has(name);
|
|
const isDisabled = !!disabled;
|
|
const disabledStateChanged = wasDisabled !== isDisabled;
|
|
disabled ? _names.disabled.add(name) : _names.disabled.delete(name);
|
|
disabledStateChanged && _state.mount && !_state.action && _setValid();
|
|
}
|
|
};
|
|
const register = (name, options = {}) => {
|
|
let field = get(_fields, name);
|
|
const disabledIsDefined = isBoolean(options.disabled) || isBoolean(_options.disabled);
|
|
const shouldRevalidateRemount = !_names.registerName.has(name) && field && field._f && !field._f.mount;
|
|
set(_fields, name, {
|
|
...(field || {}),
|
|
_f: {
|
|
...(field && field._f ? field._f : { ref: { name } }),
|
|
name,
|
|
mount: true,
|
|
...options,
|
|
},
|
|
});
|
|
_names.mount.add(name);
|
|
if (field && !shouldRevalidateRemount) {
|
|
_setDisabledField({
|
|
disabled: isBoolean(options.disabled) ? options.disabled : _options.disabled,
|
|
name,
|
|
});
|
|
} else {
|
|
updateValidAndValue(name, true, options.value);
|
|
}
|
|
return {
|
|
...(disabledIsDefined ? { disabled: options.disabled || _options.disabled } : {}),
|
|
...(_options.progressive ?
|
|
{
|
|
required: !!options.required,
|
|
min: getRuleValue(options.min),
|
|
max: getRuleValue(options.max),
|
|
minLength: getRuleValue(options.minLength),
|
|
maxLength: getRuleValue(options.maxLength),
|
|
pattern: getRuleValue(options.pattern),
|
|
}
|
|
: {}),
|
|
name,
|
|
onChange,
|
|
onBlur: onChange,
|
|
ref: (ref) => {
|
|
if (ref) {
|
|
_names.registerName.add(name);
|
|
register(name, options);
|
|
_names.registerName.delete(name);
|
|
field = get(_fields, name);
|
|
const fieldRef =
|
|
isUndefined(ref.value) ?
|
|
ref.querySelectorAll ?
|
|
ref.querySelectorAll("input,select,textarea")[0] || ref
|
|
: ref
|
|
: ref;
|
|
const radioOrCheckbox = isRadioOrCheckbox(fieldRef);
|
|
const refs = field._f.refs || [];
|
|
if (radioOrCheckbox ? refs.find((option) => option === fieldRef) : fieldRef === field._f.ref) {
|
|
return;
|
|
}
|
|
set(_fields, name, {
|
|
_f: {
|
|
...field._f,
|
|
...(radioOrCheckbox ?
|
|
{
|
|
refs: [...refs.filter(live), fieldRef, ...(Array.isArray(get(_defaultValues, name)) ? [{}] : [])],
|
|
ref: { type: fieldRef.type, name },
|
|
}
|
|
: { ref: fieldRef }),
|
|
},
|
|
});
|
|
updateValidAndValue(name, false, undefined, fieldRef);
|
|
} else {
|
|
field = get(_fields, name, {});
|
|
if (field._f) {
|
|
field._f.mount = false;
|
|
}
|
|
(_options.shouldUnregister || options.shouldUnregister) && !(isNameInFieldArray(_names.array, name) && _state.action) && _names.unMount.add(name);
|
|
}
|
|
},
|
|
};
|
|
};
|
|
const _focusError = () => _options.shouldFocusError && !_options.shouldUseNativeValidation && iterateFieldsByAction(_fields, _focusInput, _names.mount);
|
|
const _disableForm = (disabled) => {
|
|
if (isBoolean(disabled)) {
|
|
_subjects.state.next({ disabled });
|
|
iterateFieldsByAction(
|
|
_fields,
|
|
(ref, name) => {
|
|
const currentField = get(_fields, name);
|
|
if (currentField) {
|
|
ref.disabled = currentField._f.disabled || disabled;
|
|
if (Array.isArray(currentField._f.refs)) {
|
|
currentField._f.refs.forEach((inputRef) => {
|
|
inputRef.disabled = currentField._f.disabled || disabled;
|
|
});
|
|
}
|
|
}
|
|
},
|
|
0,
|
|
false,
|
|
);
|
|
}
|
|
};
|
|
const handleSubmit = (onValid, onInvalid) => async (e) => {
|
|
let onValidError = undefined;
|
|
if (e) {
|
|
e.preventDefault && e.preventDefault();
|
|
e.persist && e.persist();
|
|
}
|
|
let fieldValues = cloneObject(_formValues);
|
|
_subjects.state.next({
|
|
isSubmitting: true,
|
|
});
|
|
if (_options.resolver) {
|
|
const { errors, values } = await _runSchema();
|
|
_updateIsValidating();
|
|
_formState.errors = errors;
|
|
fieldValues = cloneObject(values);
|
|
} else {
|
|
await executeBuiltInValidation({
|
|
fields: _fields,
|
|
eventType: EVENTS.SUBMIT,
|
|
});
|
|
}
|
|
if (_names.disabled.size) {
|
|
for (const name of _names.disabled) {
|
|
unset(fieldValues, name);
|
|
}
|
|
}
|
|
unset(_formState.errors, ROOT_ERROR_TYPE);
|
|
if (isEmptyObject(_formState.errors)) {
|
|
_subjects.state.next({
|
|
errors: {},
|
|
});
|
|
try {
|
|
await onValid(fieldValues, e);
|
|
} catch (error) {
|
|
onValidError = error;
|
|
}
|
|
} else {
|
|
if (onInvalid) {
|
|
await onInvalid({ ..._formState.errors }, e);
|
|
}
|
|
_focusError();
|
|
setTimeout(_focusError);
|
|
}
|
|
_subjects.state.next({
|
|
isSubmitted: true,
|
|
isSubmitting: false,
|
|
isSubmitSuccessful: isEmptyObject(_formState.errors) && !onValidError,
|
|
submitCount: _formState.submitCount + 1,
|
|
errors: _formState.errors,
|
|
});
|
|
if (onValidError) {
|
|
throw onValidError;
|
|
}
|
|
};
|
|
const resetField = (name, options = {}) => {
|
|
if (get(_fields, name)) {
|
|
if (isUndefined(options.defaultValue)) {
|
|
setValue(name, cloneObject(get(_defaultValues, name)));
|
|
} else {
|
|
setValue(name, options.defaultValue);
|
|
set(_defaultValues, name, cloneObject(options.defaultValue));
|
|
}
|
|
if (!options.keepTouched) {
|
|
unset(_formState.touchedFields, name);
|
|
}
|
|
if (!options.keepDirty) {
|
|
unset(_formState.dirtyFields, name);
|
|
_formState.isDirty = options.defaultValue ? _getDirty(name, cloneObject(get(_defaultValues, name))) : _getDirty();
|
|
}
|
|
if (!options.keepError) {
|
|
unset(_formState.errors, name);
|
|
_proxyFormState.isValid && _setValid();
|
|
}
|
|
_subjects.state.next({ ..._formState });
|
|
}
|
|
};
|
|
const _reset = (formValues, keepStateOptions = {}) => {
|
|
const updatedValues = formValues ? cloneObject(formValues) : _defaultValues;
|
|
const cloneUpdatedValues = cloneObject(updatedValues);
|
|
const isEmptyResetValues = isEmptyObject(formValues);
|
|
const values = cloneUpdatedValues;
|
|
if (!keepStateOptions.keepDefaultValues) {
|
|
_defaultValues = updatedValues;
|
|
}
|
|
if (!keepStateOptions.keepValues) {
|
|
if (keepStateOptions.keepDirtyValues) {
|
|
const fieldsToCheck = new Set([..._names.mount, ...Object.keys(getDirtyFields(_defaultValues, _formValues))]);
|
|
for (const fieldName of Array.from(fieldsToCheck)) {
|
|
const isDirty = get(_formState.dirtyFields, fieldName);
|
|
const existingValue = get(_formValues, fieldName);
|
|
const newValue = get(values, fieldName);
|
|
if (isDirty && !isUndefined(existingValue)) {
|
|
set(values, fieldName, existingValue);
|
|
} else if (!isDirty && !isUndefined(newValue)) {
|
|
setValue(fieldName, newValue);
|
|
}
|
|
}
|
|
} else {
|
|
if (isWeb && isUndefined(formValues)) {
|
|
for (const name of _names.mount) {
|
|
const field = get(_fields, name);
|
|
if (field && field._f) {
|
|
const fieldReference = Array.isArray(field._f.refs) ? field._f.refs[0] : field._f.ref;
|
|
if (isHTMLElement(fieldReference)) {
|
|
const form = fieldReference.closest("form");
|
|
if (form) {
|
|
form.reset();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (keepStateOptions.keepFieldsRef) {
|
|
for (const fieldName of _names.mount) {
|
|
setValue(fieldName, get(values, fieldName));
|
|
}
|
|
} else {
|
|
_fields = {};
|
|
}
|
|
}
|
|
if (_options.shouldUnregister) {
|
|
_formValues = keepStateOptions.keepDefaultValues ? cloneObject(_defaultValues) : {};
|
|
if (keepStateOptions.keepFieldsRef) {
|
|
for (const fieldName of _names.mount) {
|
|
set(_formValues, fieldName, get(values, fieldName));
|
|
}
|
|
}
|
|
} else {
|
|
_formValues = cloneObject(values);
|
|
}
|
|
_subjects.array.next({
|
|
values: { ...values },
|
|
});
|
|
_subjects.state.next({
|
|
values: { ...values },
|
|
});
|
|
}
|
|
_names = {
|
|
mount: keepStateOptions.keepDirtyValues ? _names.mount : new Set(),
|
|
unMount: new Set(),
|
|
array: new Set(),
|
|
registerName: new Set(),
|
|
disabled: new Set(),
|
|
watch: new Set(),
|
|
watchAll: false,
|
|
focus: "",
|
|
};
|
|
_state.mount = !_proxyFormState.isValid || !!keepStateOptions.keepIsValid || !!keepStateOptions.keepDirtyValues || (!_options.shouldUnregister && !isEmptyObject(values));
|
|
_state.watch = !!_options.shouldUnregister;
|
|
_state.keepIsValid = !!keepStateOptions.keepIsValid;
|
|
_state.action = false;
|
|
if (!keepStateOptions.keepErrors) {
|
|
_formState.errors = {};
|
|
}
|
|
_subjects.state.next({
|
|
submitCount: keepStateOptions.keepSubmitCount ? _formState.submitCount : 0,
|
|
isDirty:
|
|
isEmptyResetValues ? false
|
|
: keepStateOptions.keepDirty ? _formState.isDirty
|
|
: keepStateOptions.keepValues ? _getDirty()
|
|
: !!(keepStateOptions.keepDefaultValues && !deepEqual(formValues, _defaultValues)),
|
|
isSubmitted: keepStateOptions.keepIsSubmitted ? _formState.isSubmitted : false,
|
|
dirtyFields:
|
|
isEmptyResetValues ? {}
|
|
: keepStateOptions.keepDirtyValues ?
|
|
keepStateOptions.keepDefaultValues && _formValues ?
|
|
getDirtyFields(_defaultValues, _formValues)
|
|
: _formState.dirtyFields
|
|
: keepStateOptions.keepDefaultValues && formValues ? getDirtyFields(_defaultValues, formValues)
|
|
: keepStateOptions.keepDirty ? _formState.dirtyFields
|
|
: {},
|
|
touchedFields: keepStateOptions.keepTouched ? _formState.touchedFields : {},
|
|
errors: keepStateOptions.keepErrors ? _formState.errors : {},
|
|
isSubmitSuccessful: keepStateOptions.keepIsSubmitSuccessful ? _formState.isSubmitSuccessful : false,
|
|
isSubmitting: false,
|
|
defaultValues: _defaultValues,
|
|
});
|
|
};
|
|
const reset = (formValues, keepStateOptions) => _reset(isFunction(formValues) ? formValues(_formValues) : formValues, { ..._options.resetOptions, ...keepStateOptions });
|
|
const setFocus = (name, options = {}) => {
|
|
const field = get(_fields, name);
|
|
const fieldReference = field && field._f;
|
|
if (fieldReference) {
|
|
const fieldRef = fieldReference.refs ? fieldReference.refs[0] : fieldReference.ref;
|
|
if (fieldRef.focus) {
|
|
setTimeout(() => {
|
|
fieldRef.focus();
|
|
options.shouldSelect && isFunction(fieldRef.select) && fieldRef.select();
|
|
});
|
|
}
|
|
}
|
|
};
|
|
const _setFormState = (updatedFormState) => {
|
|
_formState = {
|
|
..._formState,
|
|
...updatedFormState,
|
|
};
|
|
};
|
|
const _resetDefaultValues = () =>
|
|
isFunction(_options.defaultValues) &&
|
|
_options.defaultValues().then((values) => {
|
|
reset(values, _options.resetOptions);
|
|
_subjects.state.next({
|
|
isLoading: false,
|
|
});
|
|
});
|
|
const resetDefaultValues = (values, options = {}) => {
|
|
_defaultValues = cloneObject(values);
|
|
if (!options.keepDirty) {
|
|
const newDirtyFields = getDirtyFields(_defaultValues, _formValues);
|
|
_formState.dirtyFields = newDirtyFields;
|
|
_formState.isDirty = !isEmptyObject(newDirtyFields);
|
|
}
|
|
if (!options.keepIsValid) {
|
|
_setValid();
|
|
}
|
|
_subjects.state.next({
|
|
..._formState,
|
|
defaultValues: _defaultValues,
|
|
});
|
|
};
|
|
const methods = {
|
|
control: {
|
|
register,
|
|
unregister,
|
|
getFieldState,
|
|
handleSubmit,
|
|
setError,
|
|
_subscribe,
|
|
_runSchema,
|
|
_updateIsValidating,
|
|
_focusError,
|
|
_getWatch,
|
|
_getDirty,
|
|
_setValid,
|
|
_setFieldArray,
|
|
_setDisabledField,
|
|
_setErrors,
|
|
_getFieldArray,
|
|
_reset,
|
|
_resetDefaultValues,
|
|
_removeUnmounted,
|
|
_disableForm,
|
|
_subjects,
|
|
_proxyFormState,
|
|
get _fields() {
|
|
return _fields;
|
|
},
|
|
get _formValues() {
|
|
return _formValues;
|
|
},
|
|
get _state() {
|
|
return _state;
|
|
},
|
|
set _state(value) {
|
|
_state = value;
|
|
},
|
|
get _defaultValues() {
|
|
return _defaultValues;
|
|
},
|
|
get _names() {
|
|
return _names;
|
|
},
|
|
set _names(value) {
|
|
_names = value;
|
|
},
|
|
get _formState() {
|
|
return _formState;
|
|
},
|
|
get _options() {
|
|
return _options;
|
|
},
|
|
set _options(value) {
|
|
_options = {
|
|
..._options,
|
|
...value,
|
|
};
|
|
_validationModeBeforeSubmit = getValidationModes(_options.mode);
|
|
_validationModeAfterSubmit = getValidationModes(_options.reValidateMode);
|
|
},
|
|
},
|
|
subscribe,
|
|
trigger,
|
|
register,
|
|
handleSubmit,
|
|
watch,
|
|
setValue,
|
|
setValues,
|
|
getValues,
|
|
reset,
|
|
resetField,
|
|
resetDefaultValues,
|
|
clearErrors,
|
|
unregister,
|
|
setError,
|
|
setFocus,
|
|
getFieldState,
|
|
};
|
|
return {
|
|
...methods,
|
|
formControl: methods,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Custom hook to manage the entire form.
|
|
*
|
|
* @remarks
|
|
* [API](https://react-hook-form.com/docs/useform) • [Demo](https://codesandbox.io/s/react-hook-form-get-started-ts-5ksmm) • [Video](https://www.youtube.com/watch?v=RkXv4AXXC_4)
|
|
*
|
|
* @param props - form configuration and validation parameters.
|
|
*
|
|
* @returns methods - individual functions to manage the form state. {@link UseFormReturn}
|
|
*
|
|
* @example
|
|
* ```tsx
|
|
* function App() {
|
|
* const { register, handleSubmit, watch, formState: { errors } } = useForm();
|
|
* const onSubmit = data => console.log(data);
|
|
*
|
|
* console.log(watch("example"));
|
|
*
|
|
* return (
|
|
* <form onSubmit={handleSubmit(onSubmit)}>
|
|
* <input defaultValue="test" {...register("example")} />
|
|
* <input {...register("exampleRequired", { required: true })} />
|
|
* {errors.exampleRequired && <span>This field is required</span>}
|
|
* <button>Submit</button>
|
|
* </form>
|
|
* );
|
|
* }
|
|
* ```
|
|
*/
|
|
function useForm(props = {}) {
|
|
const _formControl = React$6.useRef(undefined);
|
|
const _values = React$6.useRef(undefined);
|
|
const _formControlProp = React$6.useRef(props.formControl);
|
|
const [formState, updateFormState] = React$6.useState(() => ({
|
|
...cloneObject(DEFAULT_FORM_STATE),
|
|
isLoading: isFunction(props.defaultValues),
|
|
errors: props.errors || {},
|
|
disabled: props.disabled || false,
|
|
defaultValues: isFunction(props.defaultValues) ? undefined : props.defaultValues,
|
|
}));
|
|
if (!_formControl.current || (props.formControl && _formControlProp.current !== props.formControl)) {
|
|
_formControlProp.current = props.formControl;
|
|
if (props.formControl) {
|
|
_formControl.current = {
|
|
...props.formControl,
|
|
formState,
|
|
};
|
|
if (props.defaultValues && !isFunction(props.defaultValues)) {
|
|
props.formControl.reset(props.defaultValues, props.resetOptions);
|
|
}
|
|
} else {
|
|
const { formControl, ...rest } = createFormControl(props);
|
|
_formControl.current = {
|
|
...rest,
|
|
formState,
|
|
};
|
|
}
|
|
}
|
|
const control = _formControl.current.control;
|
|
control._options = props;
|
|
useIsomorphicLayoutEffect(() => {
|
|
const sub = control._subscribe({
|
|
formState: control._proxyFormState,
|
|
callback: () =>
|
|
updateFormState({
|
|
...control._formState,
|
|
defaultValues: control._defaultValues,
|
|
}),
|
|
reRenderRoot: true,
|
|
});
|
|
updateFormState((data) => ({
|
|
...data,
|
|
isReady: true,
|
|
}));
|
|
control._formState.isReady = true;
|
|
return sub;
|
|
}, [control]);
|
|
React$6.useEffect(() => control._disableForm(props.disabled), [control, props.disabled]);
|
|
React$6.useEffect(() => {
|
|
if (props.mode) {
|
|
control._options.mode = props.mode;
|
|
}
|
|
if (props.reValidateMode) {
|
|
control._options.reValidateMode = props.reValidateMode;
|
|
}
|
|
}, [control, props.mode, props.reValidateMode]);
|
|
React$6.useEffect(() => {
|
|
if (props.errors) {
|
|
control._setErrors(props.errors);
|
|
control._focusError();
|
|
}
|
|
}, [control, props.errors]);
|
|
React$6.useEffect(() => {
|
|
props.shouldUnregister &&
|
|
control._subjects.state.next({
|
|
values: control._getWatch(),
|
|
});
|
|
}, [control, props.shouldUnregister]);
|
|
React$6.useEffect(() => {
|
|
if (control._proxyFormState.isDirty) {
|
|
const isDirty = control._getDirty();
|
|
if (isDirty !== formState.isDirty) {
|
|
control._subjects.state.next({
|
|
isDirty,
|
|
});
|
|
}
|
|
}
|
|
}, [control, formState.isDirty]);
|
|
React$6.useEffect(() => {
|
|
var _a;
|
|
if (props.values && !deepEqual(props.values, _values.current)) {
|
|
control._reset(props.values, {
|
|
keepFieldsRef: true,
|
|
...control._options.resetOptions,
|
|
});
|
|
if (!((_a = control._options.resetOptions) === null || _a === void 0 ? void 0 : _a.keepIsValid)) {
|
|
control._setValid();
|
|
}
|
|
_values.current = props.values;
|
|
updateFormState((state) => ({ ...state }));
|
|
} else {
|
|
control._resetDefaultValues();
|
|
}
|
|
}, [control, props.values]);
|
|
React$6.useEffect(() => {
|
|
if (!control._state.mount) {
|
|
control._setValid();
|
|
control._state.mount = true;
|
|
}
|
|
if (control._state.watch) {
|
|
control._state.watch = false;
|
|
control._subjects.state.next({ ...control._formState });
|
|
}
|
|
control._removeUnmounted();
|
|
});
|
|
_formControl.current.formState = React$6.useMemo(() => getProxyFormState(formState, control), [control, formState]);
|
|
return _formControl.current;
|
|
}
|
|
|
|
// src/avatar.tsx
|
|
const React$5 = await importShared("react");
|
|
var AVATAR_NAME = "Avatar";
|
|
var [createAvatarContext] = createContextScope(AVATAR_NAME);
|
|
var STATIC_IMAGE_COUNT_STATE = [0, () => void 0];
|
|
var [AvatarProvider, useAvatarContext] = createAvatarContext(AVATAR_NAME);
|
|
var Avatar = React$5.forwardRef((props, forwardedRef) => {
|
|
const { __scopeAvatar, ...avatarProps } = props;
|
|
const [imageLoadingStatus, setImageLoadingStatus] = React$5.useState("idle");
|
|
const [imageCount, setImageCount] = useImageCount();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(AvatarProvider, {
|
|
scope: __scopeAvatar,
|
|
imageLoadingStatus,
|
|
setImageLoadingStatus,
|
|
imageCount,
|
|
setImageCount,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.span, { ...avatarProps, ref: forwardedRef }),
|
|
});
|
|
});
|
|
Avatar.displayName = AVATAR_NAME;
|
|
var IMAGE_NAME = "AvatarImage";
|
|
var AvatarImage = React$5.forwardRef((props, forwardedRef) => {
|
|
const { __scopeAvatar, src, onLoadingStatusChange, ...imageProps } = props;
|
|
const context = useAvatarContext(IMAGE_NAME, __scopeAvatar);
|
|
useUpdateImageCount(context.setImageCount);
|
|
const imageLoadingStatus = useImageLoadingStatus(src, {
|
|
referrerPolicy: imageProps.referrerPolicy,
|
|
crossOrigin: imageProps.crossOrigin,
|
|
loadingStatus: context.imageLoadingStatus,
|
|
setLoadingStatus: context.setImageLoadingStatus,
|
|
});
|
|
const handleLoadingStatusChange = useCallbackRef((status) => {
|
|
onLoadingStatusChange?.(status);
|
|
});
|
|
const loadingStatusRef = React$5.useRef(imageLoadingStatus);
|
|
useLayoutEffect2(() => {
|
|
const previousLoadingStatus = loadingStatusRef.current;
|
|
loadingStatusRef.current = imageLoadingStatus;
|
|
if (imageLoadingStatus !== previousLoadingStatus) {
|
|
handleLoadingStatusChange(imageLoadingStatus);
|
|
}
|
|
}, [imageLoadingStatus, handleLoadingStatusChange]);
|
|
return imageLoadingStatus === "loaded" ? /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.img, { ...imageProps, ref: forwardedRef, src }) : null;
|
|
});
|
|
AvatarImage.displayName = IMAGE_NAME;
|
|
var FALLBACK_NAME = "AvatarFallback";
|
|
var AvatarFallback = React$5.forwardRef((props, forwardedRef) => {
|
|
const { __scopeAvatar, delayMs, ...fallbackProps } = props;
|
|
const context = useAvatarContext(FALLBACK_NAME, __scopeAvatar);
|
|
const [canRender, setCanRender] = React$5.useState(delayMs === void 0);
|
|
React$5.useEffect(() => {
|
|
if (delayMs !== void 0) {
|
|
const timerId = window.setTimeout(() => setCanRender(true), delayMs);
|
|
return () => window.clearTimeout(timerId);
|
|
}
|
|
}, [delayMs]);
|
|
return canRender && context.imageLoadingStatus !== "loaded" ? /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.span, { ...fallbackProps, ref: forwardedRef }) : null;
|
|
});
|
|
AvatarFallback.displayName = FALLBACK_NAME;
|
|
function useImageLoadingStatus(src, { loadingStatus, setLoadingStatus, referrerPolicy, crossOrigin }) {
|
|
useLayoutEffect2(() => {
|
|
if (!src) {
|
|
setLoadingStatus("error");
|
|
return;
|
|
}
|
|
const image = new window.Image();
|
|
const handleLoad = (event) => {
|
|
const image2 = event.currentTarget;
|
|
setLoadingStatus(getImageLoadingStatus(image2));
|
|
};
|
|
const handleError = () => setLoadingStatus("error");
|
|
image.addEventListener("load", handleLoad);
|
|
image.addEventListener("error", handleError);
|
|
if (referrerPolicy) {
|
|
image.referrerPolicy = referrerPolicy;
|
|
}
|
|
image.crossOrigin = crossOrigin ?? null;
|
|
image.src = src;
|
|
setLoadingStatus(getImageLoadingStatus(image));
|
|
return () => {
|
|
image.removeEventListener("load", handleLoad);
|
|
image.removeEventListener("error", handleError);
|
|
setLoadingStatus("idle");
|
|
};
|
|
}, [src, crossOrigin, referrerPolicy, setLoadingStatus]);
|
|
return loadingStatus;
|
|
}
|
|
function getImageLoadingStatus(image) {
|
|
return (
|
|
image.complete ?
|
|
image.naturalWidth > 0 ?
|
|
"loaded"
|
|
: "error"
|
|
: "loading"
|
|
);
|
|
}
|
|
function useImageCount() {
|
|
let state = STATIC_IMAGE_COUNT_STATE;
|
|
{
|
|
state = React$5.useState(0);
|
|
const [imageCount] = state;
|
|
const hasWarnedRef = React$5.useRef(false);
|
|
React$5.useEffect(() => {
|
|
if (imageCount > 1 && !hasWarnedRef.current) {
|
|
hasWarnedRef.current = true;
|
|
console.warn("Avatar: Only one `Avatar.Image` component should be rendered per `Avatar.Root`, but multiple were detected. This will lead to unexpected behavior.");
|
|
}
|
|
}, [imageCount]);
|
|
}
|
|
return state;
|
|
}
|
|
function useUpdateImageCount(setImageCount) {
|
|
{
|
|
React$5.useEffect(() => {
|
|
setImageCount((imageCount) => imageCount + 1);
|
|
return () => {
|
|
setImageCount((imageCount) => imageCount - 1);
|
|
};
|
|
}, [setImageCount]);
|
|
}
|
|
}
|
|
|
|
// src/menu.tsx
|
|
const React$4 = await importShared("react");
|
|
var SELECTION_KEYS = ["Enter", " "];
|
|
var FIRST_KEYS = ["ArrowDown", "PageUp", "Home"];
|
|
var LAST_KEYS = ["ArrowUp", "PageDown", "End"];
|
|
var FIRST_LAST_KEYS = [...FIRST_KEYS, ...LAST_KEYS];
|
|
var SUB_OPEN_KEYS = {
|
|
ltr: [...SELECTION_KEYS, "ArrowRight"],
|
|
rtl: [...SELECTION_KEYS, "ArrowLeft"],
|
|
};
|
|
var SUB_CLOSE_KEYS = {
|
|
ltr: ["ArrowLeft"],
|
|
rtl: ["ArrowRight"],
|
|
};
|
|
var MENU_NAME = "Menu";
|
|
var [Collection, useCollection, createCollectionScope] = createCollection(MENU_NAME);
|
|
var [createMenuContext, createMenuScope] = createContextScope(MENU_NAME, [createCollectionScope, createPopperScope, createRovingFocusGroupScope]);
|
|
var usePopperScope$2 = createPopperScope();
|
|
var useRovingFocusGroupScope = createRovingFocusGroupScope();
|
|
var [MenuProvider, useMenuContext] = createMenuContext(MENU_NAME);
|
|
var [MenuRootProvider, useMenuRootContext] = createMenuContext(MENU_NAME);
|
|
var Menu = (props) => {
|
|
const { __scopeMenu, open = false, children, dir, onOpenChange, modal = true } = props;
|
|
const popperScope = usePopperScope$2(__scopeMenu);
|
|
const [content, setContent] = React$4.useState(null);
|
|
const isUsingKeyboardRef = React$4.useRef(false);
|
|
const handleOpenChange = useCallbackRef(onOpenChange);
|
|
const direction = useDirection(dir);
|
|
React$4.useEffect(() => {
|
|
const handleKeyDown = () => {
|
|
isUsingKeyboardRef.current = true;
|
|
document.addEventListener("pointerdown", handlePointer, { capture: true, once: true });
|
|
document.addEventListener("pointermove", handlePointer, { capture: true, once: true });
|
|
};
|
|
const handlePointer = () => (isUsingKeyboardRef.current = false);
|
|
document.addEventListener("keydown", handleKeyDown, { capture: true });
|
|
return () => {
|
|
document.removeEventListener("keydown", handleKeyDown, { capture: true });
|
|
document.removeEventListener("pointerdown", handlePointer, { capture: true });
|
|
document.removeEventListener("pointermove", handlePointer, { capture: true });
|
|
};
|
|
}, []);
|
|
React$4.useEffect(() => {
|
|
if (!open) {
|
|
return;
|
|
}
|
|
const handleBlur = () => handleOpenChange(false);
|
|
window.addEventListener("blur", handleBlur);
|
|
return () => window.removeEventListener("blur", handleBlur);
|
|
}, [open, handleOpenChange]);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Root2$2, {
|
|
...popperScope,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(MenuProvider, {
|
|
scope: __scopeMenu,
|
|
open,
|
|
onOpenChange: handleOpenChange,
|
|
content,
|
|
onContentChange: setContent,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(MenuRootProvider, {
|
|
scope: __scopeMenu,
|
|
onClose: React$4.useCallback(() => handleOpenChange(false), [handleOpenChange]),
|
|
isUsingKeyboardRef,
|
|
dir: direction,
|
|
modal,
|
|
children,
|
|
}),
|
|
}),
|
|
});
|
|
};
|
|
Menu.displayName = MENU_NAME;
|
|
var ANCHOR_NAME$1 = "MenuAnchor";
|
|
var MenuAnchor = React$4.forwardRef((props, forwardedRef) => {
|
|
const { __scopeMenu, ...anchorProps } = props;
|
|
const popperScope = usePopperScope$2(__scopeMenu);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Anchor, { ...popperScope, ...anchorProps, ref: forwardedRef });
|
|
});
|
|
MenuAnchor.displayName = ANCHOR_NAME$1;
|
|
var PORTAL_NAME$2 = "MenuPortal";
|
|
var [PortalProvider$2, usePortalContext$2] = createMenuContext(PORTAL_NAME$2, {
|
|
forceMount: void 0,
|
|
});
|
|
var CONTENT_NAME$3 = "MenuContent";
|
|
var [MenuContentProvider, useMenuContentContext] = createMenuContext(CONTENT_NAME$3);
|
|
var MenuContent = React$4.forwardRef((props, forwardedRef) => {
|
|
const portalContext = usePortalContext$2(CONTENT_NAME$3, props.__scopeMenu);
|
|
const { forceMount = portalContext.forceMount, ...contentProps } = props;
|
|
const context = useMenuContext(CONTENT_NAME$3, props.__scopeMenu);
|
|
const rootContext = useMenuRootContext(CONTENT_NAME$3, props.__scopeMenu);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Collection.Provider, {
|
|
scope: props.__scopeMenu,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Presence, {
|
|
present: forceMount || context.open,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Collection.Slot, {
|
|
scope: props.__scopeMenu,
|
|
children:
|
|
rootContext.modal ?
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(MenuRootContentModal, { ...contentProps, ref: forwardedRef })
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsx(MenuRootContentNonModal, { ...contentProps, ref: forwardedRef }),
|
|
}),
|
|
}),
|
|
});
|
|
});
|
|
var MenuRootContentModal = React$4.forwardRef((props, forwardedRef) => {
|
|
const context = useMenuContext(CONTENT_NAME$3, props.__scopeMenu);
|
|
const ref = React$4.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
React$4.useEffect(() => {
|
|
const content = ref.current;
|
|
if (content) return hideOthers(content);
|
|
}, []);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(MenuContentImpl, {
|
|
...props,
|
|
ref: composedRefs,
|
|
trapFocus: context.open,
|
|
disableOutsidePointerEvents: context.open,
|
|
disableOutsideScroll: true,
|
|
onFocusOutside: composeEventHandlers(props.onFocusOutside, (event) => event.preventDefault(), { checkForDefaultPrevented: false }),
|
|
onDismiss: () => context.onOpenChange(false),
|
|
});
|
|
});
|
|
var MenuRootContentNonModal = React$4.forwardRef((props, forwardedRef) => {
|
|
const context = useMenuContext(CONTENT_NAME$3, props.__scopeMenu);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(MenuContentImpl, {
|
|
...props,
|
|
ref: forwardedRef,
|
|
trapFocus: false,
|
|
disableOutsidePointerEvents: false,
|
|
disableOutsideScroll: false,
|
|
onDismiss: () => context.onOpenChange(false),
|
|
});
|
|
});
|
|
var Slot$1 = createSlot("MenuContent.ScrollLock");
|
|
var MenuContentImpl = React$4.forwardRef((props, forwardedRef) => {
|
|
const {
|
|
__scopeMenu,
|
|
loop = false,
|
|
trapFocus,
|
|
onOpenAutoFocus,
|
|
onCloseAutoFocus,
|
|
disableOutsidePointerEvents,
|
|
onEntryFocus,
|
|
onEscapeKeyDown,
|
|
onPointerDownOutside,
|
|
onFocusOutside,
|
|
onInteractOutside,
|
|
onDismiss,
|
|
disableOutsideScroll,
|
|
...contentProps
|
|
} = props;
|
|
const context = useMenuContext(CONTENT_NAME$3, __scopeMenu);
|
|
const rootContext = useMenuRootContext(CONTENT_NAME$3, __scopeMenu);
|
|
const popperScope = usePopperScope$2(__scopeMenu);
|
|
const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeMenu);
|
|
const getItems = useCollection(__scopeMenu);
|
|
const [currentItemId, setCurrentItemId] = React$4.useState(null);
|
|
const contentRef = React$4.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, contentRef, context.onContentChange);
|
|
const timerRef = React$4.useRef(0);
|
|
const searchRef = React$4.useRef("");
|
|
const pointerGraceTimerRef = React$4.useRef(0);
|
|
const pointerGraceIntentRef = React$4.useRef(null);
|
|
const pointerDirRef = React$4.useRef("right");
|
|
const lastPointerXRef = React$4.useRef(0);
|
|
const ScrollLockWrapper = disableOutsideScroll ? ReactRemoveScroll : React$4.Fragment;
|
|
const scrollLockWrapperProps = disableOutsideScroll ? { as: Slot$1, allowPinchZoom: true } : void 0;
|
|
const handleTypeaheadSearch = (key) => {
|
|
const search = searchRef.current + key;
|
|
const items = getItems().filter((item) => !item.disabled);
|
|
const currentItem = document.activeElement;
|
|
const currentMatch = items.find((item) => item.ref.current === currentItem)?.textValue;
|
|
const values = items.map((item) => item.textValue);
|
|
const nextMatch = getNextMatch(values, search, currentMatch);
|
|
const newItem = items.find((item) => item.textValue === nextMatch)?.ref.current;
|
|
(function updateSearch(value) {
|
|
searchRef.current = value;
|
|
window.clearTimeout(timerRef.current);
|
|
if (value !== "") timerRef.current = window.setTimeout(() => updateSearch(""), 1e3);
|
|
})(search);
|
|
if (newItem) {
|
|
setTimeout(() => newItem.focus());
|
|
}
|
|
};
|
|
React$4.useEffect(() => {
|
|
return () => window.clearTimeout(timerRef.current);
|
|
}, []);
|
|
useFocusGuards();
|
|
const isPointerMovingToSubmenu = React$4.useCallback((event) => {
|
|
const isMovingTowards = pointerDirRef.current === pointerGraceIntentRef.current?.side;
|
|
return isMovingTowards && isPointerInGraceArea(event, pointerGraceIntentRef.current?.area);
|
|
}, []);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(MenuContentProvider, {
|
|
scope: __scopeMenu,
|
|
searchRef,
|
|
onItemEnter: React$4.useCallback(
|
|
(event) => {
|
|
if (isPointerMovingToSubmenu(event)) event.preventDefault();
|
|
},
|
|
[isPointerMovingToSubmenu],
|
|
),
|
|
onItemLeave: React$4.useCallback(
|
|
(event) => {
|
|
if (isPointerMovingToSubmenu(event)) return;
|
|
contentRef.current?.focus();
|
|
setCurrentItemId(null);
|
|
},
|
|
[isPointerMovingToSubmenu],
|
|
),
|
|
onTriggerLeave: React$4.useCallback(
|
|
(event) => {
|
|
if (isPointerMovingToSubmenu(event)) event.preventDefault();
|
|
},
|
|
[isPointerMovingToSubmenu],
|
|
),
|
|
pointerGraceTimerRef,
|
|
onPointerGraceIntentChange: React$4.useCallback((intent) => {
|
|
pointerGraceIntentRef.current = intent;
|
|
}, []),
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollLockWrapper, {
|
|
...scrollLockWrapperProps,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(FocusScope, {
|
|
asChild: true,
|
|
trapped: trapFocus,
|
|
onMountAutoFocus: composeEventHandlers(onOpenAutoFocus, (event) => {
|
|
event.preventDefault();
|
|
contentRef.current?.focus({ preventScroll: true });
|
|
}),
|
|
onUnmountAutoFocus: onCloseAutoFocus,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(DismissableLayer, {
|
|
asChild: true,
|
|
disableOutsidePointerEvents,
|
|
onEscapeKeyDown,
|
|
onPointerDownOutside,
|
|
onFocusOutside,
|
|
onInteractOutside,
|
|
onDismiss,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Root$1, {
|
|
asChild: true,
|
|
...rovingFocusGroupScope,
|
|
dir: rootContext.dir,
|
|
orientation: "vertical",
|
|
loop,
|
|
currentTabStopId: currentItemId,
|
|
onCurrentTabStopIdChange: setCurrentItemId,
|
|
onEntryFocus: composeEventHandlers(onEntryFocus, (event) => {
|
|
if (!rootContext.isUsingKeyboardRef.current) event.preventDefault();
|
|
}),
|
|
preventScrollOnEntryFocus: true,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Content, {
|
|
"role": "menu",
|
|
"aria-orientation": "vertical",
|
|
"data-state": getOpenState(context.open),
|
|
"data-radix-menu-content": "",
|
|
"dir": rootContext.dir,
|
|
...popperScope,
|
|
...contentProps,
|
|
"ref": composedRefs,
|
|
"style": { outline: "none", ...contentProps.style },
|
|
"onKeyDown": composeEventHandlers(contentProps.onKeyDown, (event) => {
|
|
const target = event.target;
|
|
const isKeyDownInside = target.closest("[data-radix-menu-content]") === event.currentTarget;
|
|
const isModifierKey = event.ctrlKey || event.altKey || event.metaKey;
|
|
const isCharacterKey = event.key.length === 1;
|
|
if (isKeyDownInside) {
|
|
if (event.key === "Tab") event.preventDefault();
|
|
if (!isModifierKey && isCharacterKey) handleTypeaheadSearch(event.key);
|
|
}
|
|
const content = contentRef.current;
|
|
if (event.target !== content) return;
|
|
if (!FIRST_LAST_KEYS.includes(event.key)) return;
|
|
event.preventDefault();
|
|
const items = getItems().filter((item) => !item.disabled);
|
|
const candidateNodes = items.map((item) => item.ref.current);
|
|
if (LAST_KEYS.includes(event.key)) candidateNodes.reverse();
|
|
focusFirst(candidateNodes);
|
|
}),
|
|
"onBlur": composeEventHandlers(props.onBlur, (event) => {
|
|
if (!event.currentTarget.contains(event.target)) {
|
|
window.clearTimeout(timerRef.current);
|
|
searchRef.current = "";
|
|
}
|
|
}),
|
|
"onPointerMove": composeEventHandlers(
|
|
props.onPointerMove,
|
|
whenMouse((event) => {
|
|
const target = event.target;
|
|
const pointerXHasChanged = lastPointerXRef.current !== event.clientX;
|
|
if (event.currentTarget.contains(target) && pointerXHasChanged) {
|
|
const newDir = event.clientX > lastPointerXRef.current ? "right" : "left";
|
|
pointerDirRef.current = newDir;
|
|
lastPointerXRef.current = event.clientX;
|
|
}
|
|
}),
|
|
),
|
|
}),
|
|
}),
|
|
}),
|
|
}),
|
|
}),
|
|
});
|
|
});
|
|
MenuContent.displayName = CONTENT_NAME$3;
|
|
var GROUP_NAME$1 = "MenuGroup";
|
|
var MenuGroup = React$4.forwardRef((props, forwardedRef) => {
|
|
const { __scopeMenu, ...groupProps } = props;
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.div, { role: "group", ...groupProps, ref: forwardedRef });
|
|
});
|
|
MenuGroup.displayName = GROUP_NAME$1;
|
|
var LABEL_NAME$1 = "MenuLabel";
|
|
var MenuLabel = React$4.forwardRef((props, forwardedRef) => {
|
|
const { __scopeMenu, ...labelProps } = props;
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.div, { ...labelProps, ref: forwardedRef });
|
|
});
|
|
MenuLabel.displayName = LABEL_NAME$1;
|
|
var ITEM_NAME$1 = "MenuItem";
|
|
var ITEM_SELECT = "menu.itemSelect";
|
|
var MenuItem = React$4.forwardRef((props, forwardedRef) => {
|
|
const { disabled = false, onSelect, ...itemProps } = props;
|
|
const ref = React$4.useRef(null);
|
|
const rootContext = useMenuRootContext(ITEM_NAME$1, props.__scopeMenu);
|
|
const contentContext = useMenuContentContext(ITEM_NAME$1, props.__scopeMenu);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
const isPointerDownRef = React$4.useRef(false);
|
|
const handleSelect = () => {
|
|
const menuItem = ref.current;
|
|
if (!disabled && menuItem) {
|
|
const itemSelectEvent = new CustomEvent(ITEM_SELECT, { bubbles: true, cancelable: true });
|
|
menuItem.addEventListener(ITEM_SELECT, (event) => onSelect?.(event), { once: true });
|
|
dispatchDiscreteCustomEvent(menuItem, itemSelectEvent);
|
|
if (itemSelectEvent.defaultPrevented) {
|
|
isPointerDownRef.current = false;
|
|
} else {
|
|
rootContext.onClose();
|
|
}
|
|
}
|
|
};
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(MenuItemImpl, {
|
|
...itemProps,
|
|
ref: composedRefs,
|
|
disabled,
|
|
onClick: composeEventHandlers(props.onClick, handleSelect),
|
|
onPointerDown: (event) => {
|
|
props.onPointerDown?.(event);
|
|
isPointerDownRef.current = true;
|
|
},
|
|
onPointerUp: composeEventHandlers(props.onPointerUp, (event) => {
|
|
if (!isPointerDownRef.current) event.currentTarget?.click();
|
|
}),
|
|
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
const isTypingAhead = contentContext.searchRef.current !== "";
|
|
if (disabled || (isTypingAhead && event.key === " ")) return;
|
|
if (SELECTION_KEYS.includes(event.key)) {
|
|
event.currentTarget.click();
|
|
event.preventDefault();
|
|
}
|
|
}),
|
|
});
|
|
});
|
|
MenuItem.displayName = ITEM_NAME$1;
|
|
var MenuItemImpl = React$4.forwardRef((props, forwardedRef) => {
|
|
const { __scopeMenu, disabled = false, textValue, ...itemProps } = props;
|
|
const contentContext = useMenuContentContext(ITEM_NAME$1, __scopeMenu);
|
|
const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeMenu);
|
|
const ref = React$4.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
const [isFocused, setIsFocused] = React$4.useState(false);
|
|
const [textContent, setTextContent] = React$4.useState("");
|
|
React$4.useEffect(() => {
|
|
const menuItem = ref.current;
|
|
if (menuItem) {
|
|
setTextContent((menuItem.textContent ?? "").trim());
|
|
}
|
|
}, [itemProps.children]);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Collection.ItemSlot, {
|
|
scope: __scopeMenu,
|
|
disabled,
|
|
textValue: textValue ?? textContent,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Item, {
|
|
asChild: true,
|
|
...rovingFocusGroupScope,
|
|
focusable: !disabled,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.div, {
|
|
"role": "menuitem",
|
|
"data-highlighted": isFocused ? "" : void 0,
|
|
"aria-disabled": disabled || void 0,
|
|
"data-disabled": disabled ? "" : void 0,
|
|
...itemProps,
|
|
"ref": composedRefs,
|
|
"onPointerMove": composeEventHandlers(
|
|
props.onPointerMove,
|
|
whenMouse((event) => {
|
|
if (disabled) {
|
|
contentContext.onItemLeave(event);
|
|
} else {
|
|
contentContext.onItemEnter(event);
|
|
if (!event.defaultPrevented) {
|
|
const item = event.currentTarget;
|
|
item.focus({ preventScroll: true });
|
|
}
|
|
}
|
|
}),
|
|
),
|
|
"onPointerLeave": composeEventHandlers(
|
|
props.onPointerLeave,
|
|
whenMouse((event) => contentContext.onItemLeave(event)),
|
|
),
|
|
"onFocus": composeEventHandlers(props.onFocus, () => setIsFocused(true)),
|
|
"onBlur": composeEventHandlers(props.onBlur, () => setIsFocused(false)),
|
|
}),
|
|
}),
|
|
});
|
|
});
|
|
var CHECKBOX_ITEM_NAME$1 = "MenuCheckboxItem";
|
|
var MenuCheckboxItem = React$4.forwardRef((props, forwardedRef) => {
|
|
const { checked = false, onCheckedChange, ...checkboxItemProps } = props;
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(ItemIndicatorProvider, {
|
|
scope: props.__scopeMenu,
|
|
checked,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(MenuItem, {
|
|
"role": "menuitemcheckbox",
|
|
"aria-checked": isIndeterminate(checked) ? "mixed" : checked,
|
|
...checkboxItemProps,
|
|
"ref": forwardedRef,
|
|
"data-state": getCheckedState(checked),
|
|
"onSelect": composeEventHandlers(checkboxItemProps.onSelect, () => onCheckedChange?.(isIndeterminate(checked) ? true : !checked), { checkForDefaultPrevented: false }),
|
|
}),
|
|
});
|
|
});
|
|
MenuCheckboxItem.displayName = CHECKBOX_ITEM_NAME$1;
|
|
var RADIO_GROUP_NAME$1 = "MenuRadioGroup";
|
|
var [RadioGroupProvider, useRadioGroupContext] = createMenuContext(RADIO_GROUP_NAME$1, { value: void 0, onValueChange: () => {} });
|
|
var MenuRadioGroup = React$4.forwardRef((props, forwardedRef) => {
|
|
const { value, onValueChange, ...groupProps } = props;
|
|
const handleValueChange = useCallbackRef(onValueChange);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(RadioGroupProvider, {
|
|
scope: props.__scopeMenu,
|
|
value,
|
|
onValueChange: handleValueChange,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(MenuGroup, { ...groupProps, ref: forwardedRef }),
|
|
});
|
|
});
|
|
MenuRadioGroup.displayName = RADIO_GROUP_NAME$1;
|
|
var RADIO_ITEM_NAME$1 = "MenuRadioItem";
|
|
var MenuRadioItem = React$4.forwardRef((props, forwardedRef) => {
|
|
const { value, ...radioItemProps } = props;
|
|
const context = useRadioGroupContext(RADIO_ITEM_NAME$1, props.__scopeMenu);
|
|
const checked = value === context.value;
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(ItemIndicatorProvider, {
|
|
scope: props.__scopeMenu,
|
|
checked,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(MenuItem, {
|
|
"role": "menuitemradio",
|
|
"aria-checked": checked,
|
|
...radioItemProps,
|
|
"ref": forwardedRef,
|
|
"data-state": getCheckedState(checked),
|
|
"onSelect": composeEventHandlers(radioItemProps.onSelect, () => context.onValueChange?.(value), { checkForDefaultPrevented: false }),
|
|
}),
|
|
});
|
|
});
|
|
MenuRadioItem.displayName = RADIO_ITEM_NAME$1;
|
|
var ITEM_INDICATOR_NAME = "MenuItemIndicator";
|
|
var [ItemIndicatorProvider, useItemIndicatorContext] = createMenuContext(ITEM_INDICATOR_NAME, { checked: false });
|
|
var MenuItemIndicator = React$4.forwardRef((props, forwardedRef) => {
|
|
const { __scopeMenu, forceMount, ...itemIndicatorProps } = props;
|
|
const indicatorContext = useItemIndicatorContext(ITEM_INDICATOR_NAME, __scopeMenu);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Presence, {
|
|
present: forceMount || isIndeterminate(indicatorContext.checked) || indicatorContext.checked === true,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.span, {
|
|
...itemIndicatorProps,
|
|
"ref": forwardedRef,
|
|
"data-state": getCheckedState(indicatorContext.checked),
|
|
}),
|
|
});
|
|
});
|
|
MenuItemIndicator.displayName = ITEM_INDICATOR_NAME;
|
|
var SEPARATOR_NAME$1 = "MenuSeparator";
|
|
var MenuSeparator = React$4.forwardRef((props, forwardedRef) => {
|
|
const { __scopeMenu, ...separatorProps } = props;
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.div, {
|
|
"role": "separator",
|
|
"aria-orientation": "horizontal",
|
|
...separatorProps,
|
|
"ref": forwardedRef,
|
|
});
|
|
});
|
|
MenuSeparator.displayName = SEPARATOR_NAME$1;
|
|
var ARROW_NAME$3 = "MenuArrow";
|
|
var MenuArrow = React$4.forwardRef((props, forwardedRef) => {
|
|
const { __scopeMenu, ...arrowProps } = props;
|
|
const popperScope = usePopperScope$2(__scopeMenu);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Arrow, { ...popperScope, ...arrowProps, ref: forwardedRef });
|
|
});
|
|
MenuArrow.displayName = ARROW_NAME$3;
|
|
var SUB_NAME = "MenuSub";
|
|
var [MenuSubProvider, useMenuSubContext] = createMenuContext(SUB_NAME);
|
|
var MenuSub = (props) => {
|
|
const { __scopeMenu, children, open = false, onOpenChange } = props;
|
|
const parentMenuContext = useMenuContext(SUB_NAME, __scopeMenu);
|
|
const popperScope = usePopperScope$2(__scopeMenu);
|
|
const [trigger, setTrigger] = React$4.useState(null);
|
|
const [content, setContent] = React$4.useState(null);
|
|
const handleOpenChange = useCallbackRef(onOpenChange);
|
|
React$4.useEffect(() => {
|
|
if (parentMenuContext.open === false) handleOpenChange(false);
|
|
return () => handleOpenChange(false);
|
|
}, [parentMenuContext.open, handleOpenChange]);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Root2$2, {
|
|
...popperScope,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(MenuProvider, {
|
|
scope: __scopeMenu,
|
|
open,
|
|
onOpenChange: handleOpenChange,
|
|
content,
|
|
onContentChange: setContent,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(MenuSubProvider, {
|
|
scope: __scopeMenu,
|
|
contentId: useId$1(),
|
|
triggerId: useId$1(),
|
|
trigger,
|
|
onTriggerChange: setTrigger,
|
|
children,
|
|
}),
|
|
}),
|
|
});
|
|
};
|
|
MenuSub.displayName = SUB_NAME;
|
|
var SUB_TRIGGER_NAME$1 = "MenuSubTrigger";
|
|
var MenuSubTrigger = React$4.forwardRef((props, forwardedRef) => {
|
|
const context = useMenuContext(SUB_TRIGGER_NAME$1, props.__scopeMenu);
|
|
const rootContext = useMenuRootContext(SUB_TRIGGER_NAME$1, props.__scopeMenu);
|
|
const subContext = useMenuSubContext(SUB_TRIGGER_NAME$1, props.__scopeMenu);
|
|
const contentContext = useMenuContentContext(SUB_TRIGGER_NAME$1, props.__scopeMenu);
|
|
const openTimerRef = React$4.useRef(null);
|
|
const { pointerGraceTimerRef, onPointerGraceIntentChange } = contentContext;
|
|
const scope = { __scopeMenu: props.__scopeMenu };
|
|
const clearOpenTimer = React$4.useCallback(() => {
|
|
if (openTimerRef.current) window.clearTimeout(openTimerRef.current);
|
|
openTimerRef.current = null;
|
|
}, []);
|
|
React$4.useEffect(() => clearOpenTimer, [clearOpenTimer]);
|
|
React$4.useEffect(() => {
|
|
const pointerGraceTimer = pointerGraceTimerRef.current;
|
|
return () => {
|
|
window.clearTimeout(pointerGraceTimer);
|
|
onPointerGraceIntentChange(null);
|
|
};
|
|
}, [pointerGraceTimerRef, onPointerGraceIntentChange]);
|
|
const composedRefs = useComposedRefs(forwardedRef, subContext.onTriggerChange);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(MenuAnchor, {
|
|
asChild: true,
|
|
...scope,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(MenuItemImpl, {
|
|
"id": subContext.triggerId,
|
|
"aria-haspopup": "menu",
|
|
"aria-expanded": context.open,
|
|
"aria-controls": context.open ? subContext.contentId : void 0,
|
|
"data-state": getOpenState(context.open),
|
|
...props,
|
|
"ref": composedRefs,
|
|
"onClick": (event) => {
|
|
props.onClick?.(event);
|
|
if (props.disabled || event.defaultPrevented) return;
|
|
event.currentTarget.focus();
|
|
if (!context.open) context.onOpenChange(true);
|
|
},
|
|
"onPointerMove": composeEventHandlers(
|
|
props.onPointerMove,
|
|
whenMouse((event) => {
|
|
contentContext.onItemEnter(event);
|
|
if (event.defaultPrevented) return;
|
|
if (!props.disabled && !context.open && !openTimerRef.current) {
|
|
contentContext.onPointerGraceIntentChange(null);
|
|
openTimerRef.current = window.setTimeout(() => {
|
|
context.onOpenChange(true);
|
|
clearOpenTimer();
|
|
}, 100);
|
|
}
|
|
}),
|
|
),
|
|
"onPointerLeave": composeEventHandlers(
|
|
props.onPointerLeave,
|
|
whenMouse((event) => {
|
|
clearOpenTimer();
|
|
const contentRect = context.content?.getBoundingClientRect();
|
|
if (contentRect) {
|
|
const side = context.content?.dataset.side;
|
|
const rightSide = side === "right";
|
|
const bleed = rightSide ? -5 : 5;
|
|
const contentNearEdge = contentRect[rightSide ? "left" : "right"];
|
|
const contentFarEdge = contentRect[rightSide ? "right" : "left"];
|
|
contentContext.onPointerGraceIntentChange({
|
|
area: [
|
|
// Apply a bleed on clientX to ensure that our exit point is
|
|
// consistently within polygon bounds
|
|
{ x: event.clientX + bleed, y: event.clientY },
|
|
{ x: contentNearEdge, y: contentRect.top },
|
|
{ x: contentFarEdge, y: contentRect.top },
|
|
{ x: contentFarEdge, y: contentRect.bottom },
|
|
{ x: contentNearEdge, y: contentRect.bottom },
|
|
],
|
|
side,
|
|
});
|
|
window.clearTimeout(pointerGraceTimerRef.current);
|
|
pointerGraceTimerRef.current = window.setTimeout(() => contentContext.onPointerGraceIntentChange(null), 300);
|
|
} else {
|
|
contentContext.onTriggerLeave(event);
|
|
if (event.defaultPrevented) return;
|
|
contentContext.onPointerGraceIntentChange(null);
|
|
}
|
|
}),
|
|
),
|
|
"onKeyDown": composeEventHandlers(props.onKeyDown, (event) => {
|
|
const isTypingAhead = contentContext.searchRef.current !== "";
|
|
if (props.disabled || (isTypingAhead && event.key === " ")) return;
|
|
if (SUB_OPEN_KEYS[rootContext.dir].includes(event.key)) {
|
|
context.onOpenChange(true);
|
|
context.content?.focus();
|
|
event.preventDefault();
|
|
}
|
|
}),
|
|
}),
|
|
});
|
|
});
|
|
MenuSubTrigger.displayName = SUB_TRIGGER_NAME$1;
|
|
var SUB_CONTENT_NAME$1 = "MenuSubContent";
|
|
var MenuSubContent = React$4.forwardRef((props, forwardedRef) => {
|
|
const portalContext = usePortalContext$2(CONTENT_NAME$3, props.__scopeMenu);
|
|
const { forceMount = portalContext.forceMount, align = "start", ...subContentProps } = props;
|
|
const context = useMenuContext(CONTENT_NAME$3, props.__scopeMenu);
|
|
const rootContext = useMenuRootContext(CONTENT_NAME$3, props.__scopeMenu);
|
|
const subContext = useMenuSubContext(SUB_CONTENT_NAME$1, props.__scopeMenu);
|
|
const ref = React$4.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Collection.Provider, {
|
|
scope: props.__scopeMenu,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Presence, {
|
|
present: forceMount || context.open,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Collection.Slot, {
|
|
scope: props.__scopeMenu,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(MenuContentImpl, {
|
|
"id": subContext.contentId,
|
|
"aria-labelledby": subContext.triggerId,
|
|
...subContentProps,
|
|
"ref": composedRefs,
|
|
align,
|
|
"side": rootContext.dir === "rtl" ? "left" : "right",
|
|
"disableOutsidePointerEvents": false,
|
|
"disableOutsideScroll": false,
|
|
"trapFocus": false,
|
|
"onOpenAutoFocus": (event) => {
|
|
if (rootContext.isUsingKeyboardRef.current) ref.current?.focus();
|
|
event.preventDefault();
|
|
},
|
|
"onCloseAutoFocus": (event) => event.preventDefault(),
|
|
"onFocusOutside": composeEventHandlers(props.onFocusOutside, (event) => {
|
|
if (event.target !== subContext.trigger) context.onOpenChange(false);
|
|
}),
|
|
"onEscapeKeyDown": composeEventHandlers(props.onEscapeKeyDown, (event) => {
|
|
rootContext.onClose();
|
|
event.preventDefault();
|
|
}),
|
|
"onKeyDown": composeEventHandlers(props.onKeyDown, (event) => {
|
|
const isKeyDownInside = event.currentTarget.contains(event.target);
|
|
const isCloseKey = SUB_CLOSE_KEYS[rootContext.dir].includes(event.key);
|
|
if (isKeyDownInside && isCloseKey) {
|
|
context.onOpenChange(false);
|
|
subContext.trigger?.focus();
|
|
event.preventDefault();
|
|
}
|
|
}),
|
|
}),
|
|
}),
|
|
}),
|
|
});
|
|
});
|
|
MenuSubContent.displayName = SUB_CONTENT_NAME$1;
|
|
function getOpenState(open) {
|
|
return open ? "open" : "closed";
|
|
}
|
|
function isIndeterminate(checked) {
|
|
return checked === "indeterminate";
|
|
}
|
|
function getCheckedState(checked) {
|
|
return (
|
|
isIndeterminate(checked) ? "indeterminate"
|
|
: checked ? "checked"
|
|
: "unchecked"
|
|
);
|
|
}
|
|
function focusFirst(candidates) {
|
|
const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
|
|
for (const candidate of candidates) {
|
|
if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
|
|
candidate.focus();
|
|
if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
|
|
}
|
|
}
|
|
function wrapArray(array, startIndex) {
|
|
return array.map((_, index) => array[(startIndex + index) % array.length]);
|
|
}
|
|
function getNextMatch(values, search, currentMatch) {
|
|
const isRepeated = search.length > 1 && Array.from(search).every((char) => char === search[0]);
|
|
const normalizedSearch = isRepeated ? search[0] : search;
|
|
const currentMatchIndex = currentMatch ? values.indexOf(currentMatch) : -1;
|
|
let wrappedValues = wrapArray(values, Math.max(currentMatchIndex, 0));
|
|
const excludeCurrentMatch = normalizedSearch.length === 1;
|
|
if (excludeCurrentMatch) wrappedValues = wrappedValues.filter((v) => v !== currentMatch);
|
|
const nextMatch = wrappedValues.find((value) => value.toLowerCase().startsWith(normalizedSearch.toLowerCase()));
|
|
return nextMatch !== currentMatch ? nextMatch : void 0;
|
|
}
|
|
function isPointInPolygon$1(point, polygon) {
|
|
const { x, y } = point;
|
|
let inside = false;
|
|
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
|
const ii = polygon[i];
|
|
const jj = polygon[j];
|
|
const xi = ii.x;
|
|
const yi = ii.y;
|
|
const xj = jj.x;
|
|
const yj = jj.y;
|
|
const intersect = yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;
|
|
if (intersect) inside = !inside;
|
|
}
|
|
return inside;
|
|
}
|
|
function isPointerInGraceArea(event, area) {
|
|
if (!area) return false;
|
|
const cursorPos = { x: event.clientX, y: event.clientY };
|
|
return isPointInPolygon$1(cursorPos, area);
|
|
}
|
|
function whenMouse(handler) {
|
|
return (event) => (event.pointerType === "mouse" ? handler(event) : void 0);
|
|
}
|
|
var Root3$1 = Menu;
|
|
var Anchor2 = MenuAnchor;
|
|
var Content2$3 = MenuContent;
|
|
var Group = MenuGroup;
|
|
var Label = MenuLabel;
|
|
var Item2$1 = MenuItem;
|
|
var CheckboxItem = MenuCheckboxItem;
|
|
var RadioGroup = MenuRadioGroup;
|
|
var RadioItem = MenuRadioItem;
|
|
var ItemIndicator = MenuItemIndicator;
|
|
var Separator = MenuSeparator;
|
|
var Arrow2$1 = MenuArrow;
|
|
var Sub = MenuSub;
|
|
var SubTrigger = MenuSubTrigger;
|
|
var SubContent = MenuSubContent;
|
|
|
|
// src/dropdown-menu.tsx
|
|
const React$3 = await importShared("react");
|
|
var DROPDOWN_MENU_NAME = "DropdownMenu";
|
|
var [createDropdownMenuContext] = createContextScope(DROPDOWN_MENU_NAME, [createMenuScope]);
|
|
var useMenuScope = createMenuScope();
|
|
var [DropdownMenuProvider, useDropdownMenuContext] = createDropdownMenuContext(DROPDOWN_MENU_NAME);
|
|
var DropdownMenu = (props) => {
|
|
const { __scopeDropdownMenu, children, dir, open: openProp, defaultOpen, onOpenChange, modal = true } = props;
|
|
const menuScope = useMenuScope(__scopeDropdownMenu);
|
|
const triggerRef = React$3.useRef(null);
|
|
const [open, setOpen] = useControllableState({
|
|
prop: openProp,
|
|
defaultProp: defaultOpen ?? false,
|
|
onChange: onOpenChange,
|
|
caller: DROPDOWN_MENU_NAME,
|
|
});
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(DropdownMenuProvider, {
|
|
scope: __scopeDropdownMenu,
|
|
triggerId: useId$1(),
|
|
triggerRef,
|
|
contentId: useId$1(),
|
|
open,
|
|
onOpenChange: setOpen,
|
|
onOpenToggle: React$3.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),
|
|
modal,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Root3$1, { ...menuScope, open, onOpenChange: setOpen, dir, modal, children }),
|
|
});
|
|
};
|
|
DropdownMenu.displayName = DROPDOWN_MENU_NAME;
|
|
var TRIGGER_NAME$2 = "DropdownMenuTrigger";
|
|
var DropdownMenuTrigger = React$3.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, disabled = false, ...triggerProps } = props;
|
|
const context = useDropdownMenuContext(TRIGGER_NAME$2, __scopeDropdownMenu);
|
|
const menuScope = useMenuScope(__scopeDropdownMenu);
|
|
const composedRefs = useComposedRefs(forwardedRef, context.triggerRef);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Anchor2, {
|
|
asChild: true,
|
|
...menuScope,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.button, {
|
|
"type": "button",
|
|
"id": context.triggerId,
|
|
"aria-haspopup": "menu",
|
|
"aria-expanded": context.open,
|
|
"aria-controls": context.open ? context.contentId : void 0,
|
|
"data-state": context.open ? "open" : "closed",
|
|
"data-disabled": disabled ? "" : void 0,
|
|
disabled,
|
|
...triggerProps,
|
|
"ref": composedRefs,
|
|
"onPointerDown": composeEventHandlers(props.onPointerDown, (event) => {
|
|
if (!disabled && event.button === 0 && event.ctrlKey === false) {
|
|
context.onOpenToggle();
|
|
if (!context.open) event.preventDefault();
|
|
}
|
|
}),
|
|
"onKeyDown": composeEventHandlers(props.onKeyDown, (event) => {
|
|
if (disabled) return;
|
|
if (["Enter", " "].includes(event.key)) context.onOpenToggle();
|
|
if (event.key === "ArrowDown") context.onOpenChange(true);
|
|
if (["Enter", " ", "ArrowDown"].includes(event.key)) event.preventDefault();
|
|
}),
|
|
}),
|
|
});
|
|
});
|
|
DropdownMenuTrigger.displayName = TRIGGER_NAME$2;
|
|
var CONTENT_NAME$2 = "DropdownMenuContent";
|
|
var DropdownMenuContent = React$3.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...contentProps } = props;
|
|
const context = useDropdownMenuContext(CONTENT_NAME$2, __scopeDropdownMenu);
|
|
const menuScope = useMenuScope(__scopeDropdownMenu);
|
|
const hasInteractedOutsideRef = React$3.useRef(false);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Content2$3, {
|
|
"id": context.contentId,
|
|
"aria-labelledby": context.triggerId,
|
|
...menuScope,
|
|
...contentProps,
|
|
"ref": forwardedRef,
|
|
"onCloseAutoFocus": composeEventHandlers(props.onCloseAutoFocus, (event) => {
|
|
if (!hasInteractedOutsideRef.current) context.triggerRef.current?.focus();
|
|
hasInteractedOutsideRef.current = false;
|
|
event.preventDefault();
|
|
}),
|
|
"onInteractOutside": composeEventHandlers(props.onInteractOutside, (event) => {
|
|
const originalEvent = event.detail.originalEvent;
|
|
const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;
|
|
const isRightClick = originalEvent.button === 2 || ctrlLeftClick;
|
|
if (!context.modal || isRightClick) hasInteractedOutsideRef.current = true;
|
|
}),
|
|
"style": {
|
|
...props.style,
|
|
// re-namespace exposed content custom properties
|
|
...{
|
|
"--radix-dropdown-menu-content-transform-origin": "var(--radix-popper-transform-origin)",
|
|
"--radix-dropdown-menu-content-available-width": "var(--radix-popper-available-width)",
|
|
"--radix-dropdown-menu-content-available-height": "var(--radix-popper-available-height)",
|
|
"--radix-dropdown-menu-trigger-width": "var(--radix-popper-anchor-width)",
|
|
"--radix-dropdown-menu-trigger-height": "var(--radix-popper-anchor-height)",
|
|
},
|
|
},
|
|
});
|
|
});
|
|
DropdownMenuContent.displayName = CONTENT_NAME$2;
|
|
var GROUP_NAME = "DropdownMenuGroup";
|
|
var DropdownMenuGroup = React$3.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...groupProps } = props;
|
|
const menuScope = useMenuScope(__scopeDropdownMenu);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Group, { ...menuScope, ...groupProps, ref: forwardedRef });
|
|
});
|
|
DropdownMenuGroup.displayName = GROUP_NAME;
|
|
var LABEL_NAME = "DropdownMenuLabel";
|
|
var DropdownMenuLabel = React$3.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...labelProps } = props;
|
|
const menuScope = useMenuScope(__scopeDropdownMenu);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Label, { ...menuScope, ...labelProps, ref: forwardedRef });
|
|
});
|
|
DropdownMenuLabel.displayName = LABEL_NAME;
|
|
var ITEM_NAME = "DropdownMenuItem";
|
|
var DropdownMenuItem = React$3.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...itemProps } = props;
|
|
const menuScope = useMenuScope(__scopeDropdownMenu);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Item2$1, { ...menuScope, ...itemProps, ref: forwardedRef });
|
|
});
|
|
DropdownMenuItem.displayName = ITEM_NAME;
|
|
var CHECKBOX_ITEM_NAME = "DropdownMenuCheckboxItem";
|
|
var DropdownMenuCheckboxItem = React$3.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...checkboxItemProps } = props;
|
|
const menuScope = useMenuScope(__scopeDropdownMenu);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(CheckboxItem, { ...menuScope, ...checkboxItemProps, ref: forwardedRef });
|
|
});
|
|
DropdownMenuCheckboxItem.displayName = CHECKBOX_ITEM_NAME;
|
|
var RADIO_GROUP_NAME = "DropdownMenuRadioGroup";
|
|
var DropdownMenuRadioGroup = React$3.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...radioGroupProps } = props;
|
|
const menuScope = useMenuScope(__scopeDropdownMenu);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(RadioGroup, { ...menuScope, ...radioGroupProps, ref: forwardedRef });
|
|
});
|
|
DropdownMenuRadioGroup.displayName = RADIO_GROUP_NAME;
|
|
var RADIO_ITEM_NAME = "DropdownMenuRadioItem";
|
|
var DropdownMenuRadioItem = React$3.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...radioItemProps } = props;
|
|
const menuScope = useMenuScope(__scopeDropdownMenu);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(RadioItem, { ...menuScope, ...radioItemProps, ref: forwardedRef });
|
|
});
|
|
DropdownMenuRadioItem.displayName = RADIO_ITEM_NAME;
|
|
var INDICATOR_NAME = "DropdownMenuItemIndicator";
|
|
var DropdownMenuItemIndicator = React$3.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...itemIndicatorProps } = props;
|
|
const menuScope = useMenuScope(__scopeDropdownMenu);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(ItemIndicator, { ...menuScope, ...itemIndicatorProps, ref: forwardedRef });
|
|
});
|
|
DropdownMenuItemIndicator.displayName = INDICATOR_NAME;
|
|
var SEPARATOR_NAME = "DropdownMenuSeparator";
|
|
var DropdownMenuSeparator = React$3.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...separatorProps } = props;
|
|
const menuScope = useMenuScope(__scopeDropdownMenu);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Separator, { ...menuScope, ...separatorProps, ref: forwardedRef });
|
|
});
|
|
DropdownMenuSeparator.displayName = SEPARATOR_NAME;
|
|
var ARROW_NAME$2 = "DropdownMenuArrow";
|
|
var DropdownMenuArrow = React$3.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...arrowProps } = props;
|
|
const menuScope = useMenuScope(__scopeDropdownMenu);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Arrow2$1, { ...menuScope, ...arrowProps, ref: forwardedRef });
|
|
});
|
|
DropdownMenuArrow.displayName = ARROW_NAME$2;
|
|
var DropdownMenuSub = (props) => {
|
|
const { __scopeDropdownMenu, children, open: openProp, onOpenChange, defaultOpen } = props;
|
|
const menuScope = useMenuScope(__scopeDropdownMenu);
|
|
const [open, setOpen] = useControllableState({
|
|
prop: openProp,
|
|
defaultProp: defaultOpen ?? false,
|
|
onChange: onOpenChange,
|
|
caller: "DropdownMenuSub",
|
|
});
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Sub, { ...menuScope, open, onOpenChange: setOpen, children });
|
|
};
|
|
var SUB_TRIGGER_NAME = "DropdownMenuSubTrigger";
|
|
var DropdownMenuSubTrigger = React$3.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...subTriggerProps } = props;
|
|
const menuScope = useMenuScope(__scopeDropdownMenu);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(SubTrigger, { ...menuScope, ...subTriggerProps, ref: forwardedRef });
|
|
});
|
|
DropdownMenuSubTrigger.displayName = SUB_TRIGGER_NAME;
|
|
var SUB_CONTENT_NAME = "DropdownMenuSubContent";
|
|
var DropdownMenuSubContent = React$3.forwardRef((props, forwardedRef) => {
|
|
const { __scopeDropdownMenu, ...subContentProps } = props;
|
|
const menuScope = useMenuScope(__scopeDropdownMenu);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(SubContent, {
|
|
...menuScope,
|
|
...subContentProps,
|
|
ref: forwardedRef,
|
|
style: {
|
|
...props.style,
|
|
// re-namespace exposed content custom properties
|
|
...{
|
|
"--radix-dropdown-menu-content-transform-origin": "var(--radix-popper-transform-origin)",
|
|
"--radix-dropdown-menu-content-available-width": "var(--radix-popper-available-width)",
|
|
"--radix-dropdown-menu-content-available-height": "var(--radix-popper-available-height)",
|
|
"--radix-dropdown-menu-trigger-width": "var(--radix-popper-anchor-width)",
|
|
"--radix-dropdown-menu-trigger-height": "var(--radix-popper-anchor-height)",
|
|
},
|
|
},
|
|
});
|
|
});
|
|
DropdownMenuSubContent.displayName = SUB_CONTENT_NAME;
|
|
var Root2$1 = DropdownMenu;
|
|
var Trigger$2 = DropdownMenuTrigger;
|
|
var Content2$2 = DropdownMenuContent;
|
|
var Label2 = DropdownMenuLabel;
|
|
var Item2 = DropdownMenuItem;
|
|
var CheckboxItem2 = DropdownMenuCheckboxItem;
|
|
var ItemIndicator2 = DropdownMenuItemIndicator;
|
|
var Separator2 = DropdownMenuSeparator;
|
|
var Sub2 = DropdownMenuSub;
|
|
var SubTrigger2 = DropdownMenuSubTrigger;
|
|
var SubContent2 = DropdownMenuSubContent;
|
|
|
|
/**
|
|
* @license lucide-react v0.525.0 - ISC
|
|
*
|
|
* This source code is licensed under the ISC license.
|
|
* See the LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
const toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
const toCamelCase = (string) => string.replace(/^([A-Z])|[\s-_]+(\w)/g, (match, p1, p2) => (p2 ? p2.toUpperCase() : p1.toLowerCase()));
|
|
const toPascalCase = (string) => {
|
|
const camelCase = toCamelCase(string);
|
|
return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
|
|
};
|
|
const mergeClasses = (...classes) =>
|
|
classes
|
|
.filter((className, index, array) => {
|
|
return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index;
|
|
})
|
|
.join(" ")
|
|
.trim();
|
|
const hasA11yProp = (props) => {
|
|
for (const prop in props) {
|
|
if (prop.startsWith("aria-") || prop === "role" || prop === "title") {
|
|
return true;
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @license lucide-react v0.525.0 - ISC
|
|
*
|
|
* This source code is licensed under the ISC license.
|
|
* See the LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
var defaultAttributes = {
|
|
xmlns: "http://www.w3.org/2000/svg",
|
|
width: 24,
|
|
height: 24,
|
|
viewBox: "0 0 24 24",
|
|
fill: "none",
|
|
stroke: "currentColor",
|
|
strokeWidth: 2,
|
|
strokeLinecap: "round",
|
|
strokeLinejoin: "round",
|
|
};
|
|
|
|
/**
|
|
* @license lucide-react v0.525.0 - ISC
|
|
*
|
|
* This source code is licensed under the ISC license.
|
|
* See the LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
const { forwardRef: forwardRef$1, createElement: createElement$1 } = await importShared("react");
|
|
|
|
const Icon = forwardRef$1(({ color = "currentColor", size = 24, strokeWidth = 2, absoluteStrokeWidth, className = "", children, iconNode, ...rest }, ref) =>
|
|
createElement$1(
|
|
"svg",
|
|
{
|
|
ref,
|
|
...defaultAttributes,
|
|
width: size,
|
|
height: size,
|
|
stroke: color,
|
|
strokeWidth: absoluteStrokeWidth ? (Number(strokeWidth) * 24) / Number(size) : strokeWidth,
|
|
className: mergeClasses("lucide", className),
|
|
...(!children && !hasA11yProp(rest) && { "aria-hidden": "true" }),
|
|
...rest,
|
|
},
|
|
[...iconNode.map(([tag, attrs]) => createElement$1(tag, attrs)), ...(Array.isArray(children) ? children : [children])],
|
|
),
|
|
);
|
|
|
|
/**
|
|
* @license lucide-react v0.525.0 - ISC
|
|
*
|
|
* This source code is licensed under the ISC license.
|
|
* See the LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
const { forwardRef, createElement } = await importShared("react");
|
|
|
|
const createLucideIcon = (iconName, iconNode) => {
|
|
const Component = forwardRef(({ className, ...props }, ref) =>
|
|
createElement(Icon, {
|
|
ref,
|
|
iconNode,
|
|
className: mergeClasses(`lucide-${toKebabCase(toPascalCase(iconName))}`, `lucide-${iconName}`, className),
|
|
...props,
|
|
}),
|
|
);
|
|
Component.displayName = toPascalCase(iconName);
|
|
return Component;
|
|
};
|
|
|
|
/**
|
|
* @license lucide-react v0.525.0 - ISC
|
|
*
|
|
* This source code is licensed under the ISC license.
|
|
* See the LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
const __iconNode$3 = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
|
|
const Check = createLucideIcon("check", __iconNode$3);
|
|
|
|
/**
|
|
* @license lucide-react v0.525.0 - ISC
|
|
*
|
|
* This source code is licensed under the ISC license.
|
|
* See the LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
const __iconNode$2 = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
|
|
const ChevronDown = createLucideIcon("chevron-down", __iconNode$2);
|
|
|
|
/**
|
|
* @license lucide-react v0.525.0 - ISC
|
|
*
|
|
* This source code is licensed under the ISC license.
|
|
* See the LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
const __iconNode$1 = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
|
|
const ChevronRight = createLucideIcon("chevron-right", __iconNode$1);
|
|
|
|
/**
|
|
* @license lucide-react v0.525.0 - ISC
|
|
*
|
|
* This source code is licensed under the ISC license.
|
|
* See the LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
const __iconNode = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
|
|
const ChevronUp = createLucideIcon("chevron-up", __iconNode);
|
|
|
|
// src/popover.tsx
|
|
const React$2 = await importShared("react");
|
|
var POPOVER_NAME = "Popover";
|
|
var [createPopoverContext] = createContextScope(POPOVER_NAME, [createPopperScope]);
|
|
var usePopperScope$1 = createPopperScope();
|
|
var [PopoverProvider, usePopoverContext] = createPopoverContext(POPOVER_NAME);
|
|
var Popover = (props) => {
|
|
const { __scopePopover, children, open: openProp, defaultOpen, onOpenChange, modal = false } = props;
|
|
const popperScope = usePopperScope$1(__scopePopover);
|
|
const triggerRef = React$2.useRef(null);
|
|
const [hasCustomAnchor, setHasCustomAnchor] = React$2.useState(false);
|
|
const [open, setOpen] = useControllableState({
|
|
prop: openProp,
|
|
defaultProp: defaultOpen ?? false,
|
|
onChange: onOpenChange,
|
|
caller: POPOVER_NAME,
|
|
});
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Root2$2, {
|
|
...popperScope,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(PopoverProvider, {
|
|
scope: __scopePopover,
|
|
contentId: useId$1(),
|
|
triggerRef,
|
|
open,
|
|
onOpenChange: setOpen,
|
|
onOpenToggle: React$2.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),
|
|
hasCustomAnchor,
|
|
onCustomAnchorAdd: React$2.useCallback(() => setHasCustomAnchor(true), []),
|
|
onCustomAnchorRemove: React$2.useCallback(() => setHasCustomAnchor(false), []),
|
|
modal,
|
|
children,
|
|
}),
|
|
});
|
|
};
|
|
Popover.displayName = POPOVER_NAME;
|
|
var ANCHOR_NAME = "PopoverAnchor";
|
|
var PopoverAnchor = React$2.forwardRef((props, forwardedRef) => {
|
|
const { __scopePopover, ...anchorProps } = props;
|
|
const context = usePopoverContext(ANCHOR_NAME, __scopePopover);
|
|
const popperScope = usePopperScope$1(__scopePopover);
|
|
const { onCustomAnchorAdd, onCustomAnchorRemove } = context;
|
|
React$2.useEffect(() => {
|
|
onCustomAnchorAdd();
|
|
return () => onCustomAnchorRemove();
|
|
}, [onCustomAnchorAdd, onCustomAnchorRemove]);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Anchor, { ...popperScope, ...anchorProps, ref: forwardedRef });
|
|
});
|
|
PopoverAnchor.displayName = ANCHOR_NAME;
|
|
var TRIGGER_NAME$1 = "PopoverTrigger";
|
|
var PopoverTrigger = React$2.forwardRef((props, forwardedRef) => {
|
|
const { __scopePopover, ...triggerProps } = props;
|
|
const context = usePopoverContext(TRIGGER_NAME$1, __scopePopover);
|
|
const popperScope = usePopperScope$1(__scopePopover);
|
|
const composedTriggerRef = useComposedRefs(forwardedRef, context.triggerRef);
|
|
const trigger = /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.button, {
|
|
"type": "button",
|
|
"aria-haspopup": "dialog",
|
|
"aria-expanded": context.open,
|
|
"aria-controls": context.open ? context.contentId : void 0,
|
|
"data-state": getState(context.open),
|
|
...triggerProps,
|
|
"ref": composedTriggerRef,
|
|
"onClick": composeEventHandlers(props.onClick, context.onOpenToggle),
|
|
});
|
|
return context.hasCustomAnchor ? trigger : /* @__PURE__ */ jsxRuntimeExports.jsx(Anchor, { asChild: true, ...popperScope, children: trigger });
|
|
});
|
|
PopoverTrigger.displayName = TRIGGER_NAME$1;
|
|
var PORTAL_NAME$1 = "PopoverPortal";
|
|
var [PortalProvider$1, usePortalContext$1] = createPopoverContext(PORTAL_NAME$1, {
|
|
forceMount: void 0,
|
|
});
|
|
var CONTENT_NAME$1 = "PopoverContent";
|
|
var PopoverContent = React$2.forwardRef((props, forwardedRef) => {
|
|
const portalContext = usePortalContext$1(CONTENT_NAME$1, props.__scopePopover);
|
|
const { forceMount = portalContext.forceMount, ...contentProps } = props;
|
|
const context = usePopoverContext(CONTENT_NAME$1, props.__scopePopover);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Presence, {
|
|
present: forceMount || context.open,
|
|
children:
|
|
context.modal ?
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(PopoverContentModal, { ...contentProps, ref: forwardedRef })
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsx(PopoverContentNonModal, { ...contentProps, ref: forwardedRef }),
|
|
});
|
|
});
|
|
PopoverContent.displayName = CONTENT_NAME$1;
|
|
var Slot = createSlot("PopoverContent.RemoveScroll");
|
|
var PopoverContentModal = React$2.forwardRef((props, forwardedRef) => {
|
|
const context = usePopoverContext(CONTENT_NAME$1, props.__scopePopover);
|
|
const contentRef = React$2.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, contentRef);
|
|
const isRightClickOutsideRef = React$2.useRef(false);
|
|
React$2.useEffect(() => {
|
|
const content = contentRef.current;
|
|
if (content) return hideOthers(content);
|
|
}, []);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(ReactRemoveScroll, {
|
|
as: Slot,
|
|
allowPinchZoom: true,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(PopoverContentImpl, {
|
|
...props,
|
|
ref: composedRefs,
|
|
trapFocus: context.open,
|
|
disableOutsidePointerEvents: true,
|
|
onCloseAutoFocus: composeEventHandlers(props.onCloseAutoFocus, (event) => {
|
|
event.preventDefault();
|
|
if (!isRightClickOutsideRef.current) context.triggerRef.current?.focus();
|
|
}),
|
|
onPointerDownOutside: composeEventHandlers(
|
|
props.onPointerDownOutside,
|
|
(event) => {
|
|
const originalEvent = event.detail.originalEvent;
|
|
const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;
|
|
const isRightClick = originalEvent.button === 2 || ctrlLeftClick;
|
|
isRightClickOutsideRef.current = isRightClick;
|
|
},
|
|
{ checkForDefaultPrevented: false },
|
|
),
|
|
onFocusOutside: composeEventHandlers(props.onFocusOutside, (event) => event.preventDefault(), { checkForDefaultPrevented: false }),
|
|
}),
|
|
});
|
|
});
|
|
var PopoverContentNonModal = React$2.forwardRef((props, forwardedRef) => {
|
|
const context = usePopoverContext(CONTENT_NAME$1, props.__scopePopover);
|
|
const hasInteractedOutsideRef = React$2.useRef(false);
|
|
const hasPointerDownOutsideRef = React$2.useRef(false);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(PopoverContentImpl, {
|
|
...props,
|
|
ref: forwardedRef,
|
|
trapFocus: false,
|
|
disableOutsidePointerEvents: false,
|
|
onCloseAutoFocus: (event) => {
|
|
props.onCloseAutoFocus?.(event);
|
|
if (!event.defaultPrevented) {
|
|
if (!hasInteractedOutsideRef.current) context.triggerRef.current?.focus();
|
|
event.preventDefault();
|
|
}
|
|
hasInteractedOutsideRef.current = false;
|
|
hasPointerDownOutsideRef.current = false;
|
|
},
|
|
onInteractOutside: (event) => {
|
|
props.onInteractOutside?.(event);
|
|
if (!event.defaultPrevented) {
|
|
hasInteractedOutsideRef.current = true;
|
|
if (event.detail.originalEvent.type === "pointerdown") {
|
|
hasPointerDownOutsideRef.current = true;
|
|
}
|
|
}
|
|
const target = event.target;
|
|
const targetIsTrigger = context.triggerRef.current?.contains(target);
|
|
if (targetIsTrigger) event.preventDefault();
|
|
if (event.detail.originalEvent.type === "focusin" && hasPointerDownOutsideRef.current) {
|
|
event.preventDefault();
|
|
}
|
|
},
|
|
});
|
|
});
|
|
var PopoverContentImpl = React$2.forwardRef((props, forwardedRef) => {
|
|
const { __scopePopover, trapFocus, onOpenAutoFocus, onCloseAutoFocus, disableOutsidePointerEvents, onEscapeKeyDown, onPointerDownOutside, onFocusOutside, onInteractOutside, ...contentProps } =
|
|
props;
|
|
const context = usePopoverContext(CONTENT_NAME$1, __scopePopover);
|
|
const popperScope = usePopperScope$1(__scopePopover);
|
|
useFocusGuards();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(FocusScope, {
|
|
asChild: true,
|
|
loop: true,
|
|
trapped: trapFocus,
|
|
onMountAutoFocus: onOpenAutoFocus,
|
|
onUnmountAutoFocus: onCloseAutoFocus,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(DismissableLayer, {
|
|
asChild: true,
|
|
disableOutsidePointerEvents,
|
|
onInteractOutside,
|
|
onEscapeKeyDown,
|
|
onPointerDownOutside,
|
|
onFocusOutside,
|
|
onDismiss: () => context.onOpenChange(false),
|
|
deferPointerDownOutside: true,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Content, {
|
|
"data-state": getState(context.open),
|
|
"role": "dialog",
|
|
"id": context.contentId,
|
|
...popperScope,
|
|
...contentProps,
|
|
"ref": forwardedRef,
|
|
"style": {
|
|
...contentProps.style,
|
|
// re-namespace exposed content custom properties
|
|
...{
|
|
"--radix-popover-content-transform-origin": "var(--radix-popper-transform-origin)",
|
|
"--radix-popover-content-available-width": "var(--radix-popper-available-width)",
|
|
"--radix-popover-content-available-height": "var(--radix-popper-available-height)",
|
|
"--radix-popover-trigger-width": "var(--radix-popper-anchor-width)",
|
|
"--radix-popover-trigger-height": "var(--radix-popper-anchor-height)",
|
|
},
|
|
},
|
|
}),
|
|
}),
|
|
});
|
|
});
|
|
var CLOSE_NAME = "PopoverClose";
|
|
var PopoverClose = React$2.forwardRef((props, forwardedRef) => {
|
|
const { __scopePopover, ...closeProps } = props;
|
|
const context = usePopoverContext(CLOSE_NAME, __scopePopover);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.button, {
|
|
type: "button",
|
|
...closeProps,
|
|
ref: forwardedRef,
|
|
onClick: composeEventHandlers(props.onClick, () => context.onOpenChange(false)),
|
|
});
|
|
});
|
|
PopoverClose.displayName = CLOSE_NAME;
|
|
var ARROW_NAME$1 = "PopoverArrow";
|
|
var PopoverArrow = React$2.forwardRef((props, forwardedRef) => {
|
|
const { __scopePopover, ...arrowProps } = props;
|
|
const popperScope = usePopperScope$1(__scopePopover);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Arrow, { ...popperScope, ...arrowProps, ref: forwardedRef });
|
|
});
|
|
PopoverArrow.displayName = ARROW_NAME$1;
|
|
function getState(open) {
|
|
return open ? "open" : "closed";
|
|
}
|
|
var Root2 = Popover;
|
|
var Trigger$1 = PopoverTrigger;
|
|
var Content2$1 = PopoverContent;
|
|
|
|
// src/toggle.tsx
|
|
const React$1 = await importShared("react");
|
|
var NAME = "Toggle";
|
|
var Toggle = React$1.forwardRef((props, forwardedRef) => {
|
|
const { pressed: pressedProp, defaultPressed, onPressedChange, ...buttonProps } = props;
|
|
const [pressed, setPressed] = useControllableState({
|
|
prop: pressedProp,
|
|
onChange: onPressedChange,
|
|
defaultProp: defaultPressed ?? false,
|
|
caller: NAME,
|
|
});
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.button, {
|
|
"type": "button",
|
|
"aria-pressed": pressed,
|
|
"data-state": pressed ? "on" : "off",
|
|
"data-disabled": props.disabled ? "" : void 0,
|
|
...buttonProps,
|
|
"ref": forwardedRef,
|
|
"onClick": composeEventHandlers(props.onClick, () => {
|
|
if (!props.disabled) {
|
|
setPressed(!pressed);
|
|
}
|
|
}),
|
|
});
|
|
});
|
|
Toggle.displayName = NAME;
|
|
var Root = Toggle;
|
|
|
|
// src/tooltip.tsx
|
|
const React = await importShared("react");
|
|
var [createTooltipContext] = createContextScope("Tooltip", [createPopperScope]);
|
|
var usePopperScope = createPopperScope();
|
|
var PROVIDER_NAME = "TooltipProvider";
|
|
var DEFAULT_DELAY_DURATION = 700;
|
|
var TOOLTIP_OPEN = "tooltip.open";
|
|
var [TooltipProviderContextProvider, useTooltipProviderContext] = createTooltipContext(PROVIDER_NAME);
|
|
var TooltipProvider = (props) => {
|
|
const { __scopeTooltip, delayDuration = DEFAULT_DELAY_DURATION, skipDelayDuration = 300, disableHoverableContent = false, children } = props;
|
|
const isOpenDelayedRef = React.useRef(true);
|
|
const isPointerInTransitRef = React.useRef(false);
|
|
const skipDelayTimerRef = React.useRef(0);
|
|
React.useEffect(() => {
|
|
const skipDelayTimer = skipDelayTimerRef.current;
|
|
return () => window.clearTimeout(skipDelayTimer);
|
|
}, []);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProviderContextProvider, {
|
|
scope: __scopeTooltip,
|
|
isOpenDelayedRef,
|
|
delayDuration,
|
|
onOpen: React.useCallback(() => {
|
|
if (skipDelayDuration <= 0) return;
|
|
window.clearTimeout(skipDelayTimerRef.current);
|
|
isOpenDelayedRef.current = false;
|
|
}, [skipDelayDuration]),
|
|
onClose: React.useCallback(() => {
|
|
if (skipDelayDuration <= 0) return;
|
|
window.clearTimeout(skipDelayTimerRef.current);
|
|
skipDelayTimerRef.current = window.setTimeout(() => (isOpenDelayedRef.current = true), skipDelayDuration);
|
|
}, [skipDelayDuration]),
|
|
isPointerInTransitRef,
|
|
onPointerInTransitChange: React.useCallback((inTransit) => {
|
|
isPointerInTransitRef.current = inTransit;
|
|
}, []),
|
|
disableHoverableContent,
|
|
children,
|
|
});
|
|
};
|
|
TooltipProvider.displayName = PROVIDER_NAME;
|
|
var TOOLTIP_NAME = "Tooltip";
|
|
var [TooltipContextProvider, useTooltipContext] = createTooltipContext(TOOLTIP_NAME);
|
|
var Tooltip = (props) => {
|
|
const { __scopeTooltip, children, open: openProp, defaultOpen, onOpenChange, disableHoverableContent: disableHoverableContentProp, delayDuration: delayDurationProp } = props;
|
|
const providerContext = useTooltipProviderContext(TOOLTIP_NAME, props.__scopeTooltip);
|
|
const popperScope = usePopperScope(__scopeTooltip);
|
|
const [trigger, setTrigger] = React.useState(null);
|
|
const contentId = useId$1();
|
|
const openTimerRef = React.useRef(0);
|
|
const disableHoverableContent = disableHoverableContentProp ?? providerContext.disableHoverableContent;
|
|
const delayDuration = delayDurationProp ?? providerContext.delayDuration;
|
|
const wasOpenDelayedRef = React.useRef(false);
|
|
const [open, setOpen] = useControllableState({
|
|
prop: openProp,
|
|
defaultProp: defaultOpen ?? false,
|
|
onChange: (open2) => {
|
|
if (open2) {
|
|
providerContext.onOpen();
|
|
document.dispatchEvent(new CustomEvent(TOOLTIP_OPEN));
|
|
} else {
|
|
providerContext.onClose();
|
|
}
|
|
onOpenChange?.(open2);
|
|
},
|
|
caller: TOOLTIP_NAME,
|
|
});
|
|
const stateAttribute = React.useMemo(() => {
|
|
return (
|
|
open ?
|
|
wasOpenDelayedRef.current ?
|
|
"delayed-open"
|
|
: "instant-open"
|
|
: "closed"
|
|
);
|
|
}, [open]);
|
|
const handleOpen = React.useCallback(() => {
|
|
window.clearTimeout(openTimerRef.current);
|
|
openTimerRef.current = 0;
|
|
wasOpenDelayedRef.current = false;
|
|
setOpen(true);
|
|
}, [setOpen]);
|
|
const handleClose = React.useCallback(() => {
|
|
window.clearTimeout(openTimerRef.current);
|
|
openTimerRef.current = 0;
|
|
setOpen(false);
|
|
}, [setOpen]);
|
|
const handleDelayedOpen = React.useCallback(() => {
|
|
window.clearTimeout(openTimerRef.current);
|
|
openTimerRef.current = window.setTimeout(() => {
|
|
wasOpenDelayedRef.current = true;
|
|
setOpen(true);
|
|
openTimerRef.current = 0;
|
|
}, delayDuration);
|
|
}, [delayDuration, setOpen]);
|
|
React.useEffect(() => {
|
|
return () => {
|
|
if (openTimerRef.current) {
|
|
window.clearTimeout(openTimerRef.current);
|
|
openTimerRef.current = 0;
|
|
}
|
|
};
|
|
}, []);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Root2$2, {
|
|
...popperScope,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContextProvider, {
|
|
scope: __scopeTooltip,
|
|
contentId,
|
|
open,
|
|
stateAttribute,
|
|
trigger,
|
|
onTriggerChange: setTrigger,
|
|
onTriggerEnter: React.useCallback(() => {
|
|
if (providerContext.isOpenDelayedRef.current) handleDelayedOpen();
|
|
else handleOpen();
|
|
}, [providerContext.isOpenDelayedRef, handleDelayedOpen, handleOpen]),
|
|
onTriggerLeave: React.useCallback(() => {
|
|
if (disableHoverableContent) {
|
|
handleClose();
|
|
} else {
|
|
window.clearTimeout(openTimerRef.current);
|
|
openTimerRef.current = 0;
|
|
}
|
|
}, [handleClose, disableHoverableContent]),
|
|
onOpen: handleOpen,
|
|
onClose: handleClose,
|
|
disableHoverableContent,
|
|
children,
|
|
}),
|
|
});
|
|
};
|
|
Tooltip.displayName = TOOLTIP_NAME;
|
|
var TRIGGER_NAME = "TooltipTrigger";
|
|
var TooltipTrigger = React.forwardRef((props, forwardedRef) => {
|
|
const { __scopeTooltip, ...triggerProps } = props;
|
|
const context = useTooltipContext(TRIGGER_NAME, __scopeTooltip);
|
|
const providerContext = useTooltipProviderContext(TRIGGER_NAME, __scopeTooltip);
|
|
const popperScope = usePopperScope(__scopeTooltip);
|
|
const ref = React.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref, context.onTriggerChange);
|
|
const isPointerDownRef = React.useRef(false);
|
|
const hasPointerMoveOpenedRef = React.useRef(false);
|
|
const handlePointerUp = React.useCallback(() => (isPointerDownRef.current = false), []);
|
|
React.useEffect(() => {
|
|
return () => document.removeEventListener("pointerup", handlePointerUp);
|
|
}, [handlePointerUp]);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Anchor, {
|
|
asChild: true,
|
|
...popperScope,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.button, {
|
|
"aria-describedby": context.open ? context.contentId : void 0,
|
|
"data-state": context.stateAttribute,
|
|
...triggerProps,
|
|
"ref": composedRefs,
|
|
"onPointerMove": composeEventHandlers(props.onPointerMove, (event) => {
|
|
if (event.pointerType === "touch") return;
|
|
if (!hasPointerMoveOpenedRef.current && !providerContext.isPointerInTransitRef.current) {
|
|
context.onTriggerEnter();
|
|
hasPointerMoveOpenedRef.current = true;
|
|
}
|
|
}),
|
|
"onPointerLeave": composeEventHandlers(props.onPointerLeave, () => {
|
|
context.onTriggerLeave();
|
|
hasPointerMoveOpenedRef.current = false;
|
|
}),
|
|
"onPointerDown": composeEventHandlers(props.onPointerDown, () => {
|
|
if (context.open) {
|
|
context.onClose();
|
|
}
|
|
isPointerDownRef.current = true;
|
|
document.addEventListener("pointerup", handlePointerUp, { once: true });
|
|
}),
|
|
"onFocus": composeEventHandlers(props.onFocus, () => {
|
|
if (!isPointerDownRef.current) context.onOpen();
|
|
}),
|
|
"onBlur": composeEventHandlers(props.onBlur, context.onClose),
|
|
"onClick": composeEventHandlers(props.onClick, context.onClose),
|
|
}),
|
|
});
|
|
});
|
|
TooltipTrigger.displayName = TRIGGER_NAME;
|
|
var PORTAL_NAME = "TooltipPortal";
|
|
var [PortalProvider, usePortalContext] = createTooltipContext(PORTAL_NAME, {
|
|
forceMount: void 0,
|
|
});
|
|
var CONTENT_NAME = "TooltipContent";
|
|
var TooltipContent = React.forwardRef((props, forwardedRef) => {
|
|
const portalContext = usePortalContext(CONTENT_NAME, props.__scopeTooltip);
|
|
const { forceMount = portalContext.forceMount, side = "top", ...contentProps } = props;
|
|
const context = useTooltipContext(CONTENT_NAME, props.__scopeTooltip);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Presence, {
|
|
present: forceMount || context.open,
|
|
children:
|
|
context.disableHoverableContent ?
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContentImpl, { side, ...contentProps, ref: forwardedRef })
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContentHoverable, { side, ...contentProps, ref: forwardedRef }),
|
|
});
|
|
});
|
|
var TooltipContentHoverable = React.forwardRef((props, forwardedRef) => {
|
|
const context = useTooltipContext(CONTENT_NAME, props.__scopeTooltip);
|
|
const providerContext = useTooltipProviderContext(CONTENT_NAME, props.__scopeTooltip);
|
|
const ref = React.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
const [pointerGraceArea, setPointerGraceArea] = React.useState(null);
|
|
const { trigger, onClose } = context;
|
|
const content = ref.current;
|
|
const { onPointerInTransitChange } = providerContext;
|
|
const handleRemoveGraceArea = React.useCallback(() => {
|
|
setPointerGraceArea(null);
|
|
onPointerInTransitChange(false);
|
|
}, [onPointerInTransitChange]);
|
|
const handleCreateGraceArea = React.useCallback(
|
|
(event, hoverTarget) => {
|
|
const currentTarget = event.currentTarget;
|
|
const exitPoint = { x: event.clientX, y: event.clientY };
|
|
const exitSide = getExitSideFromRect(exitPoint, currentTarget.getBoundingClientRect());
|
|
const paddedExitPoints = getPaddedExitPoints(exitPoint, exitSide);
|
|
const hoverTargetPoints = getPointsFromRect(hoverTarget.getBoundingClientRect());
|
|
const graceArea = getHull([...paddedExitPoints, ...hoverTargetPoints]);
|
|
setPointerGraceArea(graceArea);
|
|
onPointerInTransitChange(true);
|
|
},
|
|
[onPointerInTransitChange],
|
|
);
|
|
React.useEffect(() => {
|
|
return () => handleRemoveGraceArea();
|
|
}, [handleRemoveGraceArea]);
|
|
React.useEffect(() => {
|
|
if (trigger && content) {
|
|
const handleTriggerLeave = (event) => handleCreateGraceArea(event, content);
|
|
const handleContentLeave = (event) => handleCreateGraceArea(event, trigger);
|
|
trigger.addEventListener("pointerleave", handleTriggerLeave);
|
|
content.addEventListener("pointerleave", handleContentLeave);
|
|
return () => {
|
|
trigger.removeEventListener("pointerleave", handleTriggerLeave);
|
|
content.removeEventListener("pointerleave", handleContentLeave);
|
|
};
|
|
}
|
|
}, [trigger, content, handleCreateGraceArea, handleRemoveGraceArea]);
|
|
React.useEffect(() => {
|
|
if (pointerGraceArea) {
|
|
const handleTrackPointerGrace = (event) => {
|
|
const target = event.target;
|
|
const pointerPosition = { x: event.clientX, y: event.clientY };
|
|
const hasEnteredTarget = trigger?.contains(target) || content?.contains(target);
|
|
const isPointerOutsideGraceArea = !isPointInPolygon(pointerPosition, pointerGraceArea);
|
|
if (hasEnteredTarget) {
|
|
handleRemoveGraceArea();
|
|
} else if (isPointerOutsideGraceArea) {
|
|
handleRemoveGraceArea();
|
|
onClose();
|
|
}
|
|
};
|
|
document.addEventListener("pointermove", handleTrackPointerGrace);
|
|
return () => document.removeEventListener("pointermove", handleTrackPointerGrace);
|
|
}
|
|
}, [trigger, content, pointerGraceArea, onClose, handleRemoveGraceArea]);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContentImpl, { ...props, ref: composedRefs });
|
|
});
|
|
var [VisuallyHiddenContentContextProvider, useVisuallyHiddenContentContext] = createTooltipContext(TOOLTIP_NAME, { isInside: false });
|
|
var Slottable = createSlottable("TooltipContent");
|
|
var TooltipContentImpl = React.forwardRef((props, forwardedRef) => {
|
|
const { __scopeTooltip, children, "aria-label": ariaLabel, onEscapeKeyDown, onPointerDownOutside, ...contentProps } = props;
|
|
const context = useTooltipContext(CONTENT_NAME, __scopeTooltip);
|
|
const popperScope = usePopperScope(__scopeTooltip);
|
|
const { onClose } = context;
|
|
React.useEffect(() => {
|
|
document.addEventListener(TOOLTIP_OPEN, onClose);
|
|
return () => document.removeEventListener(TOOLTIP_OPEN, onClose);
|
|
}, [onClose]);
|
|
React.useEffect(() => {
|
|
if (context.trigger) {
|
|
const handleScroll = (event) => {
|
|
if (event.target instanceof Node && event.target.contains(context.trigger)) {
|
|
onClose();
|
|
}
|
|
};
|
|
window.addEventListener("scroll", handleScroll, { capture: true });
|
|
return () => window.removeEventListener("scroll", handleScroll, { capture: true });
|
|
}
|
|
}, [context.trigger, onClose]);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(DismissableLayer, {
|
|
asChild: true,
|
|
disableOutsidePointerEvents: false,
|
|
onEscapeKeyDown,
|
|
onPointerDownOutside,
|
|
onFocusOutside: (event) => event.preventDefault(),
|
|
onDismiss: onClose,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Content, {
|
|
"data-state": context.stateAttribute,
|
|
...popperScope,
|
|
...contentProps,
|
|
"ref": forwardedRef,
|
|
"style": {
|
|
...contentProps.style,
|
|
// re-namespace exposed content custom properties
|
|
...{
|
|
"--radix-tooltip-content-transform-origin": "var(--radix-popper-transform-origin)",
|
|
"--radix-tooltip-content-available-width": "var(--radix-popper-available-width)",
|
|
"--radix-tooltip-content-available-height": "var(--radix-popper-available-height)",
|
|
"--radix-tooltip-trigger-width": "var(--radix-popper-anchor-width)",
|
|
"--radix-tooltip-trigger-height": "var(--radix-popper-anchor-height)",
|
|
},
|
|
},
|
|
"children": [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Slottable, { children }),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(VisuallyHiddenContentContextProvider, {
|
|
scope: __scopeTooltip,
|
|
isInside: true,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Root$2, { id: context.contentId, role: "tooltip", children: ariaLabel || children }),
|
|
}),
|
|
],
|
|
}),
|
|
});
|
|
});
|
|
TooltipContent.displayName = CONTENT_NAME;
|
|
var ARROW_NAME = "TooltipArrow";
|
|
var TooltipArrow = React.forwardRef((props, forwardedRef) => {
|
|
const { __scopeTooltip, ...arrowProps } = props;
|
|
const popperScope = usePopperScope(__scopeTooltip);
|
|
const visuallyHiddenContentContext = useVisuallyHiddenContentContext(ARROW_NAME, __scopeTooltip);
|
|
return visuallyHiddenContentContext.isInside ? null : /* @__PURE__ */ jsxRuntimeExports.jsx(Arrow, { ...popperScope, ...arrowProps, ref: forwardedRef });
|
|
});
|
|
TooltipArrow.displayName = ARROW_NAME;
|
|
function getExitSideFromRect(point, rect) {
|
|
const top = Math.abs(rect.top - point.y);
|
|
const bottom = Math.abs(rect.bottom - point.y);
|
|
const right = Math.abs(rect.right - point.x);
|
|
const left = Math.abs(rect.left - point.x);
|
|
switch (Math.min(top, bottom, right, left)) {
|
|
case left:
|
|
return "left";
|
|
case right:
|
|
return "right";
|
|
case top:
|
|
return "top";
|
|
case bottom:
|
|
return "bottom";
|
|
default:
|
|
throw new Error("unreachable");
|
|
}
|
|
}
|
|
function getPaddedExitPoints(exitPoint, exitSide, padding = 5) {
|
|
const paddedExitPoints = [];
|
|
switch (exitSide) {
|
|
case "top":
|
|
paddedExitPoints.push({ x: exitPoint.x - padding, y: exitPoint.y + padding }, { x: exitPoint.x + padding, y: exitPoint.y + padding });
|
|
break;
|
|
case "bottom":
|
|
paddedExitPoints.push({ x: exitPoint.x - padding, y: exitPoint.y - padding }, { x: exitPoint.x + padding, y: exitPoint.y - padding });
|
|
break;
|
|
case "left":
|
|
paddedExitPoints.push({ x: exitPoint.x + padding, y: exitPoint.y - padding }, { x: exitPoint.x + padding, y: exitPoint.y + padding });
|
|
break;
|
|
case "right":
|
|
paddedExitPoints.push({ x: exitPoint.x - padding, y: exitPoint.y - padding }, { x: exitPoint.x - padding, y: exitPoint.y + padding });
|
|
break;
|
|
}
|
|
return paddedExitPoints;
|
|
}
|
|
function getPointsFromRect(rect) {
|
|
const { top, right, bottom, left } = rect;
|
|
return [
|
|
{ x: left, y: top },
|
|
{ x: right, y: top },
|
|
{ x: right, y: bottom },
|
|
{ x: left, y: bottom },
|
|
];
|
|
}
|
|
function isPointInPolygon(point, polygon) {
|
|
const { x, y } = point;
|
|
let inside = false;
|
|
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
|
const ii = polygon[i];
|
|
const jj = polygon[j];
|
|
const xi = ii.x;
|
|
const yi = ii.y;
|
|
const xj = jj.x;
|
|
const yj = jj.y;
|
|
const intersect = yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;
|
|
if (intersect) inside = !inside;
|
|
}
|
|
return inside;
|
|
}
|
|
function getHull(points) {
|
|
const newPoints = points.slice();
|
|
newPoints.sort((a, b) => {
|
|
if (a.x < b.x) return -1;
|
|
else if (a.x > b.x) return 1;
|
|
else if (a.y < b.y) return -1;
|
|
else if (a.y > b.y) return 1;
|
|
else return 0;
|
|
});
|
|
return getHullPresorted(newPoints);
|
|
}
|
|
function getHullPresorted(points) {
|
|
if (points.length <= 1) return points.slice();
|
|
const upperHull = [];
|
|
for (let i = 0; i < points.length; i++) {
|
|
const p = points[i];
|
|
while (upperHull.length >= 2) {
|
|
const q = upperHull[upperHull.length - 1];
|
|
const r = upperHull[upperHull.length - 2];
|
|
if ((q.x - r.x) * (p.y - r.y) >= (q.y - r.y) * (p.x - r.x)) upperHull.pop();
|
|
else break;
|
|
}
|
|
upperHull.push(p);
|
|
}
|
|
upperHull.pop();
|
|
const lowerHull = [];
|
|
for (let i = points.length - 1; i >= 0; i--) {
|
|
const p = points[i];
|
|
while (lowerHull.length >= 2) {
|
|
const q = lowerHull[lowerHull.length - 1];
|
|
const r = lowerHull[lowerHull.length - 2];
|
|
if ((q.x - r.x) * (p.y - r.y) >= (q.y - r.y) * (p.x - r.x)) lowerHull.pop();
|
|
else break;
|
|
}
|
|
lowerHull.push(p);
|
|
}
|
|
lowerHull.pop();
|
|
if (upperHull.length === 1 && lowerHull.length === 1 && upperHull[0].x === lowerHull[0].x && upperHull[0].y === lowerHull[0].y) {
|
|
return upperHull;
|
|
} else {
|
|
return upperHull.concat(lowerHull);
|
|
}
|
|
}
|
|
var Provider = TooltipProvider;
|
|
var Root3 = Tooltip;
|
|
var Trigger = TooltipTrigger;
|
|
var Content2 = TooltipContent;
|
|
var Arrow2 = TooltipArrow;
|
|
|
|
const F = await importShared("react");
|
|
|
|
const { createContext: ne, useContext: oe, forwardRef: p, useMemo: L, useRef: E, useEffect: A, useState: ae } = await importShared("react");
|
|
function d(...e) {
|
|
return twMerge(clsx(e));
|
|
}
|
|
function ge({ className: e, ...t }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Avatar, {
|
|
"data-slot": "avatar",
|
|
"className": d("relative flex size-8 shrink-0 overflow-hidden rounded-full", e),
|
|
...t,
|
|
});
|
|
}
|
|
function ve({ className: e, ...t }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(AvatarImage, {
|
|
"data-slot": "avatar-image",
|
|
"className": d("aspect-square size-full", e),
|
|
...t,
|
|
});
|
|
}
|
|
function fe({ className: e, ...t }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(AvatarFallback, {
|
|
"data-slot": "avatar-fallback",
|
|
"className": d("bg-muted flex size-full items-center justify-center rounded-full", e),
|
|
...t,
|
|
});
|
|
}
|
|
const be = cva(
|
|
"inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
|
|
{
|
|
variants: {
|
|
variant: {
|
|
default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
|
|
secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
|
|
destructive:
|
|
"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
|
outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
|
|
},
|
|
},
|
|
defaultVariants: {
|
|
variant: "default",
|
|
},
|
|
},
|
|
);
|
|
function he({ className: e, variant: t, asChild: n = false, ...a }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(n ? Slot$2 : "span", {
|
|
"data-slot": "badge",
|
|
"className": d(be({ variant: t }), e),
|
|
...a,
|
|
});
|
|
}
|
|
const xe = cva(
|
|
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*=size-])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
|
{
|
|
variants: {
|
|
variant: {
|
|
default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
|
|
destructive: "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
|
outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
|
secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
|
|
ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
|
link: "text-primary underline-offset-4 hover:underline",
|
|
},
|
|
size: {
|
|
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
|
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
|
|
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
|
icon: "size-9",
|
|
},
|
|
},
|
|
defaultVariants: {
|
|
variant: "default",
|
|
size: "default",
|
|
},
|
|
},
|
|
);
|
|
function we({ className: e, variant: t, size: n, asChild: a = false, ...r }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(a ? Slot$2 : "button", {
|
|
"data-slot": "button",
|
|
"className": d(xe({ variant: t, size: n, className: e })),
|
|
...r,
|
|
});
|
|
}
|
|
function Ce({ className: e, ...t }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
"data-slot": "card",
|
|
"className": d("bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm", e),
|
|
...t,
|
|
});
|
|
}
|
|
function Ne({ className: e, ...t }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
"data-slot": "card-content",
|
|
"className": d("px-6", e),
|
|
...t,
|
|
});
|
|
}
|
|
function Te({ ...e }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Root2$1, { "data-slot": "dropdown-menu", ...e });
|
|
}
|
|
function Se({ ...e }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Trigger$2, {
|
|
"data-slot": "dropdown-menu-trigger",
|
|
...e,
|
|
});
|
|
}
|
|
function ye({ className: e, sideOffset: t = 4, ...n }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Content2$2, {
|
|
"data-slot": "dropdown-menu-content",
|
|
"sideOffset": t,
|
|
"className": d(
|
|
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 max-h-(--radix-dropdown-menu-content-available-height) origin-(--radix-dropdown-menu-content-transform-origin) z-50 min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border p-1 shadow-md",
|
|
e,
|
|
),
|
|
...n,
|
|
});
|
|
}
|
|
function ke({ className: e, inset: t, variant: n = "default", ...a }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Item2, {
|
|
"data-slot": "dropdown-menu-item",
|
|
"data-inset": t,
|
|
"data-variant": n,
|
|
"className": d(
|
|
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*=text-])]:text-muted-foreground outline-hidden relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm data-[disabled]:pointer-events-none data-[inset]:pl-8 data-[disabled]:opacity-50 [&_svg:not([class*=size-])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
e,
|
|
),
|
|
...a,
|
|
});
|
|
}
|
|
function Me({ className: e, children: t, checked: n, ...a }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(CheckboxItem2, {
|
|
"data-slot": "dropdown-menu-checkbox-item",
|
|
"className": d(
|
|
"focus:bg-accent focus:text-accent-foreground outline-hidden relative flex cursor-default select-none items-center gap-2 rounded-sm py-1.5 pl-8 pr-2 text-sm data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg:not([class*=size-])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
e,
|
|
),
|
|
"checked": n,
|
|
...a,
|
|
"children": [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", {
|
|
className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ItemIndicator2, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-4" }) }),
|
|
}),
|
|
t,
|
|
],
|
|
});
|
|
}
|
|
function ze({ className: e, inset: t, ...n }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Label2, {
|
|
"data-slot": "dropdown-menu-label",
|
|
"data-inset": t,
|
|
"className": d("px-2 py-1.5 text-sm font-medium data-[inset]:pl-8", e),
|
|
...n,
|
|
});
|
|
}
|
|
function De({ className: e, ...t }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Separator2, {
|
|
"data-slot": "dropdown-menu-separator",
|
|
"className": d("bg-border -mx-1 my-1 h-px", e),
|
|
...t,
|
|
});
|
|
}
|
|
function Ie({ ...e }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Sub2, { "data-slot": "dropdown-menu-sub", ...e });
|
|
}
|
|
function Be({ className: e, inset: t, children: n, ...a }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(SubTrigger2, {
|
|
"data-slot": "dropdown-menu-sub-trigger",
|
|
"data-inset": t,
|
|
"className": d(
|
|
"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground outline-hidden flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm data-[inset]:pl-8",
|
|
e,
|
|
),
|
|
...a,
|
|
"children": [n, /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "ml-auto size-4" })],
|
|
});
|
|
}
|
|
function Pe({ className: e, ...t }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(SubContent2, {
|
|
"data-slot": "dropdown-menu-sub-content",
|
|
"className": d(
|
|
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-(--radix-dropdown-menu-content-transform-origin) z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-lg",
|
|
e,
|
|
),
|
|
...t,
|
|
});
|
|
}
|
|
function _e({ className: e, ...t }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Root$3, {
|
|
"data-slot": "label",
|
|
"className": d(
|
|
"flex select-none items-center gap-2 text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-50 group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50",
|
|
e,
|
|
),
|
|
...t,
|
|
});
|
|
}
|
|
const Re = FormProvider;
|
|
F.createContext({});
|
|
F.createContext({});
|
|
function Fe({ className: e, type: t, ...n }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("input", {
|
|
"type": t,
|
|
"data-slot": "input",
|
|
"className": d(
|
|
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input shadow-xs flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base outline-none transition-[color,box-shadow] file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
|
e,
|
|
),
|
|
...n,
|
|
});
|
|
}
|
|
function Le({ ...e }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Root2, { "data-slot": "popover", ...e });
|
|
}
|
|
function Ee({ ...e }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Trigger$1, { "data-slot": "popover-trigger", ...e });
|
|
}
|
|
function Ae({ className: e, align: t = "center", sideOffset: n = 4, ...a }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Content2$1, {
|
|
"data-slot": "popover-content",
|
|
"align": t,
|
|
"sideOffset": n,
|
|
"className": d(
|
|
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-(--radix-popover-content-transform-origin) outline-hidden z-50 w-72 rounded-md border p-4 shadow-md",
|
|
e,
|
|
),
|
|
...a,
|
|
});
|
|
}
|
|
function Ve({ ...e }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Select, { "data-slot": "select", ...e });
|
|
}
|
|
function je({ ...e }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { "data-slot": "select-value", ...e });
|
|
}
|
|
function qe({ className: e, size: t = "default", children: n, ...a }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectTrigger, {
|
|
"data-slot": "select-trigger",
|
|
"data-size": t,
|
|
"className": d(
|
|
"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*=text-])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 shadow-xs flex w-fit items-center justify-between gap-2 whitespace-nowrap rounded-md border bg-transparent px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg:not([class*=size-])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
e,
|
|
),
|
|
...a,
|
|
"children": [n, /* @__PURE__ */ jsxRuntimeExports.jsx(SelectIcon, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4 opacity-50" }) })],
|
|
});
|
|
}
|
|
function $e({ className: e, children: t, position: n = "popper", ...a }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, {
|
|
"data-slot": "select-content",
|
|
"className": d(
|
|
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 max-h-(--radix-select-content-available-height) origin-(--radix-select-content-transform-origin) relative z-50 min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border shadow-md",
|
|
n === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
e,
|
|
),
|
|
"position": n,
|
|
...a,
|
|
"children": [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Oe, {}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectViewport, {
|
|
className: d("p-1", n === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"),
|
|
children: t,
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Ue, {}),
|
|
],
|
|
});
|
|
}
|
|
function Ge({ className: e, children: t, ...n }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(SelectItem, {
|
|
"data-slot": "select-item",
|
|
"className": d(
|
|
"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*=text-])]:text-muted-foreground outline-hidden *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2 relative flex w-full cursor-default select-none items-center gap-2 rounded-sm py-1.5 pl-2 pr-8 text-sm data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg:not([class*=size-])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
e,
|
|
),
|
|
...n,
|
|
"children": [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", {
|
|
className: "absolute right-2 flex size-3.5 items-center justify-center",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectItemIndicator, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-4" }) }),
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectItemText, { children: t }),
|
|
],
|
|
});
|
|
}
|
|
function Oe({ className: e, ...t }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(SelectScrollUpButton, {
|
|
"data-slot": "select-scroll-up-button",
|
|
"className": d("flex cursor-default items-center justify-center py-1", e),
|
|
...t,
|
|
"children": /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronUp, { className: "size-4" }),
|
|
});
|
|
}
|
|
function Ue({ className: e, ...t }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(SelectScrollDownButton, {
|
|
"data-slot": "select-scroll-down-button",
|
|
"className": d("flex cursor-default items-center justify-center py-1", e),
|
|
...t,
|
|
"children": /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4" }),
|
|
});
|
|
}
|
|
function He({ className: e, ...t }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
"data-slot": "skeleton",
|
|
"className": d("bg-accent animate-pulse rounded-md", e),
|
|
...t,
|
|
});
|
|
}
|
|
function Ke({ className: e, ...t }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Root2$3, {
|
|
"data-slot": "tabs",
|
|
"className": d("flex flex-col gap-2", e),
|
|
...t,
|
|
});
|
|
}
|
|
function Qe({ className: e, ...t }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(List, {
|
|
"data-slot": "tabs-list",
|
|
"className": d("bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]", e),
|
|
...t,
|
|
});
|
|
}
|
|
function We({ className: e, ...t }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Trigger$3, {
|
|
"data-slot": "tabs-trigger",
|
|
"className": d(
|
|
"data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 whitespace-nowrap rounded-md border border-transparent px-2 py-1 text-sm font-medium transition-[color,box-shadow] focus-visible:outline-1 focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg:not([class*=size-])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
e,
|
|
),
|
|
...t,
|
|
});
|
|
}
|
|
function Ze({ className: e, ...t }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Content$1, {
|
|
"data-slot": "tabs-content",
|
|
"className": d("flex-1 outline-none", e),
|
|
...t,
|
|
});
|
|
}
|
|
const Je = cva(
|
|
"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*=size-])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap",
|
|
{
|
|
variants: {
|
|
variant: {
|
|
default: "bg-transparent",
|
|
outline: "border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground",
|
|
},
|
|
size: {
|
|
default: "h-9 px-2 min-w-9",
|
|
sm: "h-8 px-1.5 min-w-8",
|
|
lg: "h-10 px-2.5 min-w-10",
|
|
},
|
|
},
|
|
defaultVariants: {
|
|
variant: "default",
|
|
size: "default",
|
|
},
|
|
},
|
|
);
|
|
function Xe({ className: e, variant: t, size: n, ...a }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Root, {
|
|
"data-slot": "toggle",
|
|
"className": d(Je({ variant: t, size: n, className: e })),
|
|
...a,
|
|
});
|
|
}
|
|
function $({ delayDuration: e = 0, ...t }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Provider, {
|
|
"data-slot": "tooltip-provider",
|
|
"delayDuration": e,
|
|
...t,
|
|
});
|
|
}
|
|
function Ye({ ...e }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx($, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(Root3, { "data-slot": "tooltip", ...e }) });
|
|
}
|
|
function et({ ...e }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Trigger, { "data-slot": "tooltip-trigger", ...e });
|
|
}
|
|
function tt({ className: e, sideOffset: t = 0, children: n, ...a }) {
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(Content2, {
|
|
"data-slot": "tooltip-content",
|
|
"sideOffset": t,
|
|
"className": d(
|
|
"bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-(--radix-tooltip-content-transform-origin) z-50 w-fit text-balance rounded-md px-3 py-1.5 text-xs",
|
|
e,
|
|
),
|
|
...a,
|
|
"children": [n, /* @__PURE__ */ jsxRuntimeExports.jsx(Arrow2, { className: "bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" })],
|
|
});
|
|
}
|
|
const nt = {
|
|
Avatar: {
|
|
Avatar: ge,
|
|
AvatarFallback: fe,
|
|
AvatarImage: ve,
|
|
},
|
|
Badge: {
|
|
Badge: he,
|
|
},
|
|
Button: {
|
|
Button: we,
|
|
},
|
|
Card: {
|
|
Card: Ce,
|
|
CardContent: Ne,
|
|
},
|
|
DropdownMenu: {
|
|
DropdownMenu: Te,
|
|
DropdownMenuCheckboxItem: Me,
|
|
DropdownMenuContent: ye,
|
|
DropdownMenuItem: ke,
|
|
DropdownMenuLabel: ze,
|
|
DropdownMenuSeparator: De,
|
|
DropdownMenuSub: Ie,
|
|
DropdownMenuSubContent: Pe,
|
|
DropdownMenuSubTrigger: Be,
|
|
DropdownMenuTrigger: Se,
|
|
},
|
|
Form: {
|
|
Form: Re,
|
|
},
|
|
Input: {
|
|
Input: Fe,
|
|
},
|
|
Label: {
|
|
Label: _e,
|
|
},
|
|
Popover: {
|
|
Popover: Le,
|
|
PopoverContent: Ae,
|
|
PopoverTrigger: Ee,
|
|
},
|
|
Select: {
|
|
Select: Ve,
|
|
SelectContent: $e,
|
|
SelectItem: Ge,
|
|
SelectTrigger: qe,
|
|
SelectValue: je,
|
|
},
|
|
Skeleton: {
|
|
Skeleton: He,
|
|
},
|
|
Tabs: {
|
|
Tabs: Ke,
|
|
TabsContent: Ze,
|
|
TabsList: Qe,
|
|
TabsTrigger: We,
|
|
},
|
|
Toggle: {
|
|
Toggle: Xe,
|
|
},
|
|
Tooltip: {
|
|
Tooltip: Ye,
|
|
TooltipContent: tt,
|
|
TooltipProvider: $,
|
|
TooltipTrigger: et,
|
|
},
|
|
},
|
|
G = ne(void 0);
|
|
function f() {
|
|
return oe(G);
|
|
}
|
|
const ot = (e) => {
|
|
const { children: t, ...n } = e;
|
|
At$2(n);
|
|
const a = f(),
|
|
r = useForm();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(a.Form.Form, { ...r, children: t });
|
|
},
|
|
at = p((e, t) => {
|
|
const {
|
|
"className": n,
|
|
"name": a,
|
|
"label": r,
|
|
"variant": s,
|
|
"icon": i,
|
|
// TODO: implement
|
|
"value": c,
|
|
"autoFocus": u,
|
|
"placeholder": l,
|
|
"disabled": g,
|
|
"onKeyDown": b,
|
|
"onChange": h,
|
|
"onSubmit": C,
|
|
"autoComplete": T,
|
|
"aria-activedescendant": y,
|
|
"rightSection": O,
|
|
// TODO: add rightSection
|
|
...U
|
|
} = e;
|
|
At$2(U);
|
|
const P = f();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", {
|
|
className: d(
|
|
n,
|
|
"border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
"text-foreground items-center gap-2",
|
|
),
|
|
children: [
|
|
i,
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", {
|
|
className: "flex-1",
|
|
children: [
|
|
r && /* @__PURE__ */ jsxRuntimeExports.jsx(P.Label.Label, { htmlFor: r, children: r }),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(P.Input.Input, {
|
|
"className": d(n, "h-auto border-none p-0"),
|
|
"id": r,
|
|
"name": a,
|
|
"autoFocus": u,
|
|
"placeholder": l,
|
|
"disabled": g,
|
|
"value": c,
|
|
"onKeyDown": b,
|
|
"onChange": h,
|
|
"onSubmit": C,
|
|
"ref": t,
|
|
"aria-activedescendant": y,
|
|
}),
|
|
],
|
|
}),
|
|
O,
|
|
],
|
|
});
|
|
}),
|
|
rt = (e) =>
|
|
p((t, n) =>
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(e, {
|
|
onPointerDown: (a) => {
|
|
a.nativeEvent.fakeEvent || (a.ctrlKey = true);
|
|
},
|
|
onPointerUp: (a) => {
|
|
const r = new PointerEvent("pointerdown", a.nativeEvent);
|
|
((r.fakeEvent = true), a.target.dispatchEvent(r));
|
|
},
|
|
...t,
|
|
ref: n,
|
|
}),
|
|
),
|
|
st = (e) => {
|
|
const {
|
|
children: t,
|
|
onOpenChange: n,
|
|
position: a,
|
|
// Unused
|
|
sub: r,
|
|
...s
|
|
} = e;
|
|
At$2(s);
|
|
const i = f();
|
|
return r ?
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(i.DropdownMenu.DropdownMenuSub, {
|
|
onOpenChange: n,
|
|
children: t,
|
|
})
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsx(i.DropdownMenu.DropdownMenu, {
|
|
modal: false,
|
|
onOpenChange: n,
|
|
children: t,
|
|
});
|
|
},
|
|
it = (e) => {
|
|
const { children: t, sub: n, ...a } = e;
|
|
At$2(a);
|
|
const r = f(),
|
|
s = L(() => rt(r.DropdownMenu.DropdownMenuTrigger), [r.DropdownMenu.DropdownMenuTrigger]);
|
|
return n ? /* @__PURE__ */ jsxRuntimeExports.jsx(r.DropdownMenu.DropdownMenuSubTrigger, { children: t }) : /* @__PURE__ */ jsxRuntimeExports.jsx(s, { asChild: true, ...a, children: t });
|
|
},
|
|
dt = p((e, t) => {
|
|
const { className: n, children: a, sub: r, ...s } = e;
|
|
At$2(s);
|
|
const i = f();
|
|
return r ?
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(i.DropdownMenu.DropdownMenuSubContent, {
|
|
className: n,
|
|
ref: t,
|
|
children: a,
|
|
})
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsx(i.DropdownMenu.DropdownMenuContent, {
|
|
className: n,
|
|
ref: t,
|
|
children: a,
|
|
});
|
|
}),
|
|
lt = p((e, t) => {
|
|
const { className: n, children: a, icon: r, checked: s, subTrigger: i, onClick: c, ...u } = e;
|
|
At$2(u);
|
|
const l = f();
|
|
return (
|
|
i ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [r, a] })
|
|
: s !== void 0 ?
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(l.DropdownMenu.DropdownMenuCheckboxItem, {
|
|
className: d(n, "gap-1", s ? "" : "px-2"),
|
|
ref: t,
|
|
checked: s,
|
|
onClick: c,
|
|
...u,
|
|
children: [r, a],
|
|
})
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsxs(l.DropdownMenu.DropdownMenuItem, {
|
|
className: n,
|
|
ref: t,
|
|
onClick: c,
|
|
...u,
|
|
children: [r, a, i && /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "ml-auto h-4 w-4" })],
|
|
})
|
|
);
|
|
}),
|
|
ct = p((e, t) => {
|
|
const { className: n, ...a } = e;
|
|
At$2(a);
|
|
const r = f();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(r.DropdownMenu.DropdownMenuSeparator, {
|
|
className: n,
|
|
ref: t,
|
|
});
|
|
}),
|
|
ut = p((e, t) => {
|
|
const { className: n, children: a, ...r } = e;
|
|
At$2(r);
|
|
const s = f();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(s.DropdownMenu.DropdownMenuLabel, {
|
|
className: n,
|
|
ref: t,
|
|
children: a,
|
|
});
|
|
}),
|
|
mt = p((e, t) => {
|
|
const { className: n, children: a, icon: r, onClick: s, onDragEnd: i, onDragStart: c, draggable: u, label: l, ...g } = e;
|
|
At$2(g, false);
|
|
const b = f();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(b.Button.Button, {
|
|
"variant": "ghost",
|
|
"className": d(n, "text-gray-400"),
|
|
"ref": t,
|
|
"aria-label": l,
|
|
"onClick": s,
|
|
"onDragStart": c,
|
|
"onDragEnd": i,
|
|
"draggable": u,
|
|
...g,
|
|
"children": [r, a],
|
|
});
|
|
}),
|
|
pt = p((e, t) => {
|
|
const {
|
|
className: n,
|
|
tabs: a,
|
|
defaultOpenTab: r,
|
|
openTab: s,
|
|
setOpenTab: i,
|
|
loading: c,
|
|
// TODO: implement loader
|
|
...u
|
|
} = e;
|
|
At$2(u);
|
|
const l = f();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(l.Tabs.Tabs, {
|
|
className: d(n, "bg-popover max-w-screen rounded-lg p-2"),
|
|
ref: t,
|
|
value: s,
|
|
defaultValue: r,
|
|
onValueChange: i,
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(l.Tabs.TabsList, {
|
|
children: a.map((g) => /* @__PURE__ */ jsxRuntimeExports.jsx(l.Tabs.TabsTrigger, { value: g.name, children: g.name }, g.name)),
|
|
}),
|
|
a.map((g) =>
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
l.Tabs.TabsContent,
|
|
{
|
|
value: g.name,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(l.Card.Card, {
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(l.Card.CardContent, { className: "p-4", children: g.tabPanel }),
|
|
}),
|
|
},
|
|
g.name,
|
|
),
|
|
),
|
|
],
|
|
});
|
|
}),
|
|
gt = p((e, t) => {
|
|
const { className: n, children: a, ...r } = e;
|
|
return (
|
|
At$2(r),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
className: d(n, "flex flex-col items-start justify-center gap-2"),
|
|
ref: t,
|
|
children: a,
|
|
})
|
|
);
|
|
}),
|
|
vt = p((e, t) => {
|
|
const { className: n, value: a, placeholder: r, onKeyDown: s, onChange: i, ...c } = e;
|
|
At$2(c);
|
|
const u = f();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(u.Input.Input, {
|
|
"data-test": "embed-input",
|
|
"className": d(n, "w-80 max-w-full"),
|
|
"ref": t,
|
|
"value": a,
|
|
"placeholder": r,
|
|
"onKeyDown": s,
|
|
"onChange": i,
|
|
});
|
|
}),
|
|
ft = (e) => {
|
|
const {
|
|
children: t,
|
|
open: n,
|
|
onOpenChange: a,
|
|
position: r,
|
|
// unused
|
|
...s
|
|
} = e;
|
|
At$2(s);
|
|
const i = f();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(i.Popover.Popover, { open: n, onOpenChange: a, children: t });
|
|
},
|
|
bt = p((e, t) => {
|
|
const { children: n, ...a } = e;
|
|
At$2(a);
|
|
const r = f();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(r.Popover.PopoverTrigger, { ref: t, asChild: true, children: n });
|
|
}),
|
|
ht = p((e, t) => {
|
|
const { className: n, variant: a, children: r, ...s } = e;
|
|
At$2(s);
|
|
const i = f();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(i.Popover.PopoverContent, {
|
|
sideOffset: 8,
|
|
className: d(n, "z-[10000] flex flex-col gap-2", a === "panel-popover" ? "w-fit max-w-none border-none p-0 shadow-none" : ""),
|
|
ref: t,
|
|
children: r,
|
|
});
|
|
}),
|
|
xt = p((e, t) => {
|
|
const { className: n, children: a, ...r } = e;
|
|
return (At$2(r, false), /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: n, ref: t, ...r, children: a }));
|
|
}),
|
|
wt = p((e, t) => {
|
|
const { className: n, children: a, icon: r, onClick: s, onDragEnd: i, onDragStart: c, draggable: u, label: l, ...g } = e;
|
|
At$2(g, false);
|
|
const b = f();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(b.Button.Button, {
|
|
"variant": "ghost",
|
|
"className": d(n, "text-gray-400"),
|
|
"ref": t,
|
|
"aria-label": l,
|
|
"onClick": s,
|
|
"onDragStart": c,
|
|
"onDragEnd": i,
|
|
"draggable": u,
|
|
...g,
|
|
"children": [r, a],
|
|
});
|
|
}),
|
|
Ct = p((e, t) => {
|
|
const { className: n, children: a, id: r, columns: s, ...i } = e;
|
|
return (
|
|
At$2(i),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
className: d(
|
|
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 max-h-(--radix-dropdown-menu-content-available-height) origin-(--radix-dropdown-menu-content-transform-origin) z-50 min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border p-1 shadow-md",
|
|
"grid",
|
|
n,
|
|
),
|
|
style: { gridTemplateColumns: `repeat(${s}, 1fr)` },
|
|
ref: t,
|
|
id: r,
|
|
role: "grid",
|
|
children: a,
|
|
})
|
|
);
|
|
}),
|
|
Nt = p((e, t) => {
|
|
const { className: n, children: a, columns: r, ...s } = e;
|
|
return (
|
|
At$2(s),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
className: n,
|
|
style: { gridColumn: `1 / ${r + 1}` },
|
|
ref: t,
|
|
children: a,
|
|
})
|
|
);
|
|
}),
|
|
Tt = p((e, t) => {
|
|
const { className: n, children: a, id: r, ...s } = e;
|
|
return (
|
|
At$2(s),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
id: r,
|
|
role: "listbox",
|
|
className: d(
|
|
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 max-h-(--radix-dropdown-menu-content-available-height) origin-(--radix-dropdown-menu-content-transform-origin) z-50 min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border p-1 shadow-md",
|
|
n,
|
|
),
|
|
ref: t,
|
|
children: a,
|
|
})
|
|
);
|
|
}),
|
|
St = p((e, t) => {
|
|
const { className: n, children: a, ...r } = e;
|
|
return (
|
|
At$2(r),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
className: d(
|
|
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*=text-])]:text-muted-foreground outline-hidden relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm data-[disabled]:pointer-events-none data-[inset]:pl-8 data-[disabled]:opacity-50 [&_svg:not([class*=size-])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
"hover:bg-accent hover:text-accent-foreground data-[variant=destructive]:hover:bg-destructive/10 dark:data-[variant=destructive]:hover:bg-destructive/20 data-[variant=destructive]:hover:text-destructive",
|
|
"aria-selected:bg-accent aria-selected:text-accent-foreground data-[variant=destructive]:aria-selected:bg-destructive/10 dark:data-[variant=destructive]:aria-selected:bg-destructive/20 data-[variant=destructive]:aria-selected:text-destructive",
|
|
n,
|
|
),
|
|
ref: t,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: a }),
|
|
})
|
|
);
|
|
}),
|
|
yt = p((e, t) => {
|
|
const n = f(),
|
|
{ className: a, item: r, isSelected: s, onClick: i, id: c, ...u } = e;
|
|
At$2(u);
|
|
const l = E(null);
|
|
return (
|
|
A(() => {
|
|
if (!l.current || !s) return;
|
|
zl(l.current, l.current.closest(".bn-suggestion-menu, #ai-suggestion-menu")) !== "none" && l.current.scrollIntoView({ block: "nearest" });
|
|
}, [s]),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", {
|
|
"className": d(
|
|
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*=text-])]:text-muted-foreground outline-hidden relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm data-[disabled]:pointer-events-none data-[inset]:pl-8 data-[disabled]:opacity-50 [&_svg:not([class*=size-])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
"hover:bg-accent hover:text-accent-foreground data-[variant=destructive]:hover:bg-destructive/10 dark:data-[variant=destructive]:hover:bg-destructive/20 data-[variant=destructive]:hover:text-destructive",
|
|
"aria-selected:bg-accent aria-selected:text-accent-foreground data-[variant=destructive]:aria-selected:bg-destructive/10 dark:data-[variant=destructive]:aria-selected:bg-destructive/20 data-[variant=destructive]:aria-selected:text-destructive",
|
|
e.item.size === "small" ? "gap-3 py-1" : "",
|
|
a,
|
|
),
|
|
"data-highlighted": true,
|
|
"ref": jl([t, l]),
|
|
"id": c,
|
|
"onMouseDown": (g) => g.preventDefault(),
|
|
"onClick": i,
|
|
"role": "option",
|
|
"aria-selected": s || void 0,
|
|
"children": [
|
|
r.icon &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
"className": d("p-3", e.item.size === "small" ? "p-0" : "", a),
|
|
"data-position": "left",
|
|
"children": r.icon,
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", {
|
|
className: "flex-1",
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
className: d("text-base", e.item.size === "small" ? "text-sm" : "", a),
|
|
children: r.title,
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
className: d("text-xs", e.item.size === "small" ? "hidden" : "", a),
|
|
children: r.subtext,
|
|
}),
|
|
],
|
|
}),
|
|
r.badge &&
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
"data-position": "right",
|
|
"className": "text-xs",
|
|
"children": /* @__PURE__ */ jsxRuntimeExports.jsx(n.Badge.Badge, { variant: "secondary", children: r.badge }),
|
|
}),
|
|
],
|
|
})
|
|
);
|
|
}),
|
|
kt = p((e, t) => {
|
|
const { className: n, children: a, ...r } = e;
|
|
return (
|
|
At$2(r),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
className: d("px-2 py-1.5 text-sm font-medium data-[inset]:pl-8", n),
|
|
ref: t,
|
|
children: a,
|
|
})
|
|
);
|
|
}),
|
|
Mt = p((e, t) => {
|
|
const { className: n, ...a } = e;
|
|
return (
|
|
At$2(a),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
className: d(n, "animate-spin"),
|
|
ref: t,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx("svg", {
|
|
xmlns: "http://www.w3.org/2000/svg",
|
|
height: "1em",
|
|
viewBox: "0 -960 960 960",
|
|
width: "1em",
|
|
fill: "#e8eaed",
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", {
|
|
d: "M480-80q-82 0-155-31.5t-127.5-86Q143-252 111.5-325T80-480q0-83 31.5-155.5t86-127Q252-817 325-848.5T480-880q17 0 28.5 11.5T520-840q0 17-11.5 28.5T480-800q-133 0-226.5 93.5T160-480q0 133 93.5 226.5T480-160q133 0 226.5-93.5T800-480q0-17 11.5-28.5T840-520q17 0 28.5 11.5T880-480q0 82-31.5 155t-86 127.5q-54.5 54.5-127 86T480-80Z",
|
|
}),
|
|
}),
|
|
})
|
|
);
|
|
}),
|
|
zt = p((e, t) => {
|
|
const { className: n, children: a, onMouseDown: r, onClick: s, ...i } = e;
|
|
At$2(i, false);
|
|
const c = f();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(c.Button.Button, {
|
|
variant: "ghost",
|
|
className: d(
|
|
n,
|
|
"h-full w-full p-0 text-gray-400",
|
|
n != null && n.includes("extend-button-add-remove-columns") ? "ml-1" : "mt-1",
|
|
n != null && n.includes("extend-button-editing") ? "bg-accent text-accent-foreground" : "",
|
|
),
|
|
ref: t,
|
|
onClick: s,
|
|
onMouseDown: r,
|
|
...i,
|
|
children: a,
|
|
});
|
|
}),
|
|
Dt = p((e, t) => {
|
|
const { className: n, children: a, draggable: r, onDragStart: s, onDragEnd: i, style: c, label: u, ...l } = e;
|
|
At$2(l, false);
|
|
const g = f();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(g.Button.Button, {
|
|
"variant": "ghost",
|
|
"className": d(n, "h-fit w-fit p-0 text-gray-400"),
|
|
"ref": t,
|
|
"aria-label": u,
|
|
"draggable": r,
|
|
"onDragStart": s,
|
|
"onDragEnd": i,
|
|
"style": c,
|
|
...l,
|
|
"children": a,
|
|
});
|
|
}),
|
|
k = p((e, t) => {
|
|
const { className: n, children: a, onMouseEnter: r, onMouseLeave: s, variant: i, ...c } = e;
|
|
At$2(c);
|
|
const u = f();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(u.Tooltip.TooltipProvider, {
|
|
delayDuration: 0,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
className: d(n, "bg-popover text-popover-foreground flex h-fit gap-1 rounded-lg border p-1 shadow-md", i === "action-toolbar" ? "w-fit" : ""),
|
|
ref: t,
|
|
onMouseEnter: r,
|
|
onMouseLeave: s,
|
|
children: a,
|
|
}),
|
|
});
|
|
}),
|
|
M = p((e, t) => {
|
|
const { className: n, children: a, mainTooltip: r, secondaryTooltip: s, icon: i, isSelected: c, isDisabled: u, onClick: l, label: g, variant: b, ...h } = e;
|
|
At$2(h, false);
|
|
const C = f(),
|
|
T =
|
|
c === void 0 ?
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(C.Button.Button, {
|
|
"className": d(n, b === "compact" ? "h-6 min-w-6 p-0" : ""),
|
|
"variant": "ghost",
|
|
"size": b === "compact" ? "sm" : "default",
|
|
"disabled": u,
|
|
"onClick": l,
|
|
"ref": t,
|
|
"aria-label": g,
|
|
...h,
|
|
"children": [i, a],
|
|
})
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsxs(C.Toggle.Toggle, {
|
|
"className": d(n, "data-[state=open]:bg-accent data-[state=closed]:text-accent-foreground", b === "compact" ? "h-6 min-w-6 p-0" : ""),
|
|
"size": b === "compact" ? "sm" : "default",
|
|
"aria-label": g,
|
|
"onClick": l,
|
|
"pressed": c,
|
|
"disabled": u,
|
|
"data-state": c ? "on" : "off",
|
|
"data-disabled": u,
|
|
"ref": t,
|
|
...h,
|
|
"children": [i, a],
|
|
});
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(C.Tooltip.Tooltip, {
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(C.Tooltip.TooltipTrigger, { asChild: true, children: T }),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(C.Tooltip.TooltipContent, {
|
|
className: "flex flex-col items-center whitespace-pre-wrap",
|
|
children: [/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: r }), s && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: s })],
|
|
}),
|
|
],
|
|
});
|
|
}),
|
|
z = p((e, t) => {
|
|
const { className: n, items: a, isDisabled: r, ...s } = e;
|
|
At$2(s);
|
|
const i = f(),
|
|
c = (l) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [l.icon, l.text] }),
|
|
u = a.filter((l) => l.isSelected)[0];
|
|
return u ?
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(i.Select.Select, {
|
|
value: u.text,
|
|
onValueChange: (l) => {
|
|
var g, b;
|
|
return (b = (g = a.find((h) => h.text === l)).onClick) == null ? void 0 : b.call(g);
|
|
},
|
|
disabled: r,
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(i.Select.SelectTrigger, { className: "border-none", children: /* @__PURE__ */ jsxRuntimeExports.jsx(i.Select.SelectValue, {}) }),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(i.Select.SelectContent, {
|
|
className: n,
|
|
ref: t,
|
|
children: a.map((l) =>
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
i.Select.SelectItem,
|
|
{
|
|
disabled: l.isDisabled,
|
|
value: l.text,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(c, { ...l }),
|
|
},
|
|
l.text,
|
|
),
|
|
),
|
|
}),
|
|
],
|
|
})
|
|
: null;
|
|
}),
|
|
It = p((e, t) => {
|
|
const { className: n, children: a, selected: r, headerText: s, onFocus: i, onBlur: c, tabIndex: u, ...l } = e;
|
|
At$2(l);
|
|
const g = f();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(g.Card.Card, {
|
|
className: d(n, "w-[300px]", r ? "bg-accent text-accent-foreground" : ""),
|
|
onFocus: i,
|
|
onBlur: c,
|
|
tabIndex: u,
|
|
ref: t,
|
|
children: [s && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-4 pt-4 text-sm italic", children: s }), a],
|
|
});
|
|
}),
|
|
Bt = p((e, t) => {
|
|
const { className: n, children: a, ...r } = e;
|
|
return (
|
|
At$2(r),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
className: d(n, "p-4", n != null && n.includes("thread-comments") ? "flex flex-col gap-6 border-b" : ""),
|
|
ref: t,
|
|
children: a,
|
|
})
|
|
);
|
|
}),
|
|
Pt = p((e, t) => {
|
|
const { className: n, children: a, ...r } = e;
|
|
At$2(r, false);
|
|
const s = f();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(s.Button.Button, {
|
|
className: d(n, "text-foreground w-fit bg-transparent p-0 hover:bg-transparent"),
|
|
ref: t,
|
|
children: a,
|
|
});
|
|
}),
|
|
_t = p((e, t) => {
|
|
const { authorInfo: n, timeString: a, edited: r, ...s } = e,
|
|
i = S();
|
|
At$2(s, false);
|
|
const c = f();
|
|
return n === "loading" ?
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", {
|
|
className: "flex flex-row flex-nowrap items-center gap-4",
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(c.Skeleton.Skeleton, {
|
|
className: "size-7 animate-pulse rounded-full bg-neutral-400",
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(c.Skeleton.Skeleton, {
|
|
className: "h-3 w-32 animate-pulse rounded-full bg-neutral-400",
|
|
}),
|
|
],
|
|
})
|
|
: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", {
|
|
className: "flex flex-row flex-nowrap items-center gap-4",
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(c.Avatar.Avatar, {
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(c.Avatar.AvatarImage, {
|
|
src: n.avatarUrl,
|
|
alt: n.username,
|
|
className: "h-7 rounded-full",
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(c.Avatar.AvatarFallback, { children: n.username[0] }),
|
|
],
|
|
}),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", {
|
|
className: "flex flex-row flex-nowrap items-center gap-2",
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-bold", children: n.username }),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs", children: [a, " ", r && `(${i.comments.edited})`] }),
|
|
],
|
|
}),
|
|
],
|
|
});
|
|
}),
|
|
Rt = p((e, t) => {
|
|
const {
|
|
className: n,
|
|
showActions: a,
|
|
authorInfo: r,
|
|
timeString: s,
|
|
actions: i,
|
|
edited: c,
|
|
emojiPickerOpen: u,
|
|
// Unused
|
|
children: l,
|
|
...g
|
|
} = e;
|
|
At$2(g);
|
|
const [b, h] = ae(false),
|
|
{ focused: C, ref: T } = Zl(),
|
|
y = i && (a === true || a === void 0 || (a === "hover" && b) || C);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", {
|
|
ref: t,
|
|
className: d(n, "relative flex flex-col gap-2"),
|
|
onMouseEnter: () => h(true),
|
|
onMouseLeave: () => h(false),
|
|
children: [
|
|
y ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute right-0 top-0 z-10", ref: T, children: i }) : null,
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(_t, { ...e }),
|
|
l,
|
|
],
|
|
});
|
|
}),
|
|
Ft = p((e, t) => {
|
|
const { className: n, onFocus: a, onBlur: r, autoFocus: s, editor: i, editable: c, ...u } = e;
|
|
At$2(u);
|
|
const l = q();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Ot, {
|
|
autoFocus: s,
|
|
className: d(n, ""),
|
|
theme: l == null ? void 0 : l.colorSchemePreference,
|
|
editor: e.editor,
|
|
sideMenu: false,
|
|
slashMenu: false,
|
|
tableHandles: false,
|
|
filePanel: false,
|
|
formattingToolbar: false,
|
|
editable: c,
|
|
ref: t,
|
|
onFocus: a,
|
|
onBlur: r,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Br, {
|
|
formattingToolbar: Lt,
|
|
}),
|
|
});
|
|
}),
|
|
Lt = () => {
|
|
const e = Tr([]).filter((t) => t.key !== "nestBlockButton" && t.key !== "unnestBlockButton");
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(qt$1, { blockTypeSelectItems: [], children: e });
|
|
},
|
|
Et = p((e, t) => {
|
|
const { className: n, text: a, icon: r, isSelected: s, mainTooltip: i, secondaryTooltip: c, onClick: u, onMouseEnter: l, ...g } = e;
|
|
At$2(g, false);
|
|
const b = f(),
|
|
h = /* @__PURE__ */ jsxRuntimeExports.jsxs(b.Button.Button, {
|
|
variant: s ? "secondary" : "outline",
|
|
className: d(n, "flex h-7 items-center gap-1 rounded-full px-2.5"),
|
|
onClick: u,
|
|
onMouseEnter: l,
|
|
ref: t,
|
|
children: [/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: r }), /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: a })],
|
|
});
|
|
return i ?
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(b.Tooltip.Tooltip, {
|
|
children: [
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx(b.Tooltip.TooltipTrigger, { asChild: true, children: h }),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(b.Tooltip.TooltipContent, {
|
|
className: "flex flex-col items-center whitespace-pre-wrap",
|
|
children: [/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: i }), c && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: c })],
|
|
}),
|
|
],
|
|
})
|
|
: h;
|
|
}),
|
|
At = p((e, t) => {
|
|
const { className: n, children: a, ...r } = e;
|
|
At$2(r);
|
|
const s = f();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(s.Tooltip.TooltipProvider, {
|
|
delayDuration: 0,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
className: d(n, "flex w-full flex-row flex-wrap gap-1"),
|
|
ref: t,
|
|
children: a,
|
|
}),
|
|
});
|
|
}),
|
|
Vt = p((e, t) => {
|
|
const { className: n, children: a, onClick: r, label: s, ...i } = e;
|
|
At$2(i);
|
|
const c = f();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(c.Button.Button, {
|
|
"type": "submit",
|
|
"className": n,
|
|
"aria-label": s,
|
|
"ref": t,
|
|
"onClick": r,
|
|
"children": a,
|
|
});
|
|
}),
|
|
jt = p((e, t) => {
|
|
const { className: n, accept: a, value: r, placeholder: s, onChange: i, ...c } = e;
|
|
At$2(c);
|
|
const u = f();
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(u.Input.Input, {
|
|
type: "file",
|
|
className: n,
|
|
ref: t,
|
|
accept: a,
|
|
value: r ? r.name : void 0,
|
|
onChange: async (l) => (i == null ? void 0 : i(l.target.files[0])),
|
|
placeholder: s,
|
|
});
|
|
}),
|
|
qt = p((e, t) => {
|
|
const { className: n, isSelected: a, onClick: r, item: s, id: i, ...c } = e;
|
|
At$2(c);
|
|
const u = E(null);
|
|
return (
|
|
A(() => {
|
|
if (!u.current || !a) return;
|
|
zl(u.current, u.current.closest(".bn-grid-suggestion-menu")) !== "none" && u.current.scrollIntoView({ block: "nearest" });
|
|
}, [a]),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
"className": d(
|
|
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*=text-])]:text-muted-foreground outline-hidden relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm data-[disabled]:pointer-events-none data-[inset]:pl-8 data-[disabled]:opacity-50 [&_svg:not([class*=size-])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
"hover:bg-accent hover:text-accent-foreground data-[variant=destructive]:hover:bg-destructive/10 dark:data-[variant=destructive]:hover:bg-destructive/20 data-[variant=destructive]:hover:text-destructive",
|
|
"aria-selected:bg-accent aria-selected:text-accent-foreground data-[variant=destructive]:aria-selected:bg-destructive/10 dark:data-[variant=destructive]:aria-selected:bg-destructive/20 data-[variant=destructive]:aria-selected:text-destructive",
|
|
"text-lg!",
|
|
n,
|
|
),
|
|
"ref": jl([t, u]),
|
|
"id": i,
|
|
"role": "option",
|
|
"onClick": r,
|
|
"aria-selected": a || void 0,
|
|
"children": s.icon,
|
|
})
|
|
);
|
|
}),
|
|
$t = p((e, t) => {
|
|
const {
|
|
className: n,
|
|
children: a,
|
|
// unused, using "dots" instead
|
|
columns: r,
|
|
...s
|
|
} = e;
|
|
return (
|
|
At$2(s),
|
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
className: n,
|
|
style: { gridColumn: `1 / ${r + 1}` },
|
|
ref: t,
|
|
children: a,
|
|
})
|
|
);
|
|
}),
|
|
Gt = {
|
|
FormattingToolbar: {
|
|
Root: k,
|
|
Button: M,
|
|
Select: z,
|
|
},
|
|
FilePanel: {
|
|
Root: pt,
|
|
Button: Vt,
|
|
FileInput: jt,
|
|
TabPanel: gt,
|
|
TextInput: vt,
|
|
},
|
|
LinkToolbar: {
|
|
Root: k,
|
|
Button: M,
|
|
Select: z,
|
|
},
|
|
SideMenu: {
|
|
Root: xt,
|
|
Button: wt,
|
|
},
|
|
SuggestionMenu: {
|
|
Root: Tt,
|
|
Item: yt,
|
|
EmptyItem: St,
|
|
Label: kt,
|
|
Loader: Mt,
|
|
},
|
|
GridSuggestionMenu: {
|
|
Root: Ct,
|
|
Item: qt,
|
|
EmptyItem: Nt,
|
|
Loader: $t,
|
|
},
|
|
TableHandle: {
|
|
Root: Dt,
|
|
ExtendButton: zt,
|
|
},
|
|
Comments: {
|
|
Comment: Rt,
|
|
Editor: Ft,
|
|
Card: It,
|
|
CardSection: Bt,
|
|
ExpandSectionsPrompt: Pt,
|
|
},
|
|
Generic: {
|
|
Badge: {
|
|
Root: Et,
|
|
Group: At,
|
|
},
|
|
Toolbar: {
|
|
Root: k,
|
|
Button: M,
|
|
Select: z,
|
|
},
|
|
Form: {
|
|
Root: ot,
|
|
TextInput: at,
|
|
},
|
|
Menu: {
|
|
Root: st,
|
|
Trigger: it,
|
|
Dropdown: dt,
|
|
Divider: ct,
|
|
Label: ut,
|
|
Item: lt,
|
|
Button: mt,
|
|
},
|
|
Popover: {
|
|
Root: ft,
|
|
Trigger: bt,
|
|
Content: ht,
|
|
},
|
|
},
|
|
},
|
|
Ot = (e) => {
|
|
const { className: t, shadCNComponents: n, ...a } = e,
|
|
r = L(
|
|
() => ({
|
|
...nt,
|
|
...n,
|
|
}),
|
|
[n],
|
|
);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(G.Provider, {
|
|
value: r,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ao.Provider, {
|
|
value: Gt,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Ml, {
|
|
className: D("bn-shadcn", t || ""),
|
|
...a,
|
|
}),
|
|
}),
|
|
});
|
|
};
|
|
|
|
// src/components/blocknote-editor/blocknote-editor-inner.tsx
|
|
const { useCallback, useEffect, useMemo, useRef } = await importShared("react");
|
|
function parseValue(value) {
|
|
if (!value || value.trim() === "") return void 0;
|
|
try {
|
|
const parsed = JSON.parse(value);
|
|
if (!Array.isArray(parsed)) {
|
|
console.warn("[BlockNoteEditor] value is not a JSON array \u2014 rendering empty editor");
|
|
return void 0;
|
|
}
|
|
return parsed;
|
|
} catch {
|
|
console.warn("[BlockNoteEditor] Failed to parse JSON value \u2014 rendering empty editor");
|
|
return void 0;
|
|
}
|
|
}
|
|
function BlockNoteEditorInner({ value, onChange, schema, readOnly = false, className, maxLength, onBlur, autoFocus = false, theme = "light" }) {
|
|
const resolvedSchema = schema ?? defaultSchema;
|
|
const initialContent = useMemo(() => parseValue(value), []);
|
|
const editor = Ke$1({
|
|
schema: resolvedSchema,
|
|
initialContent: initialContent?.length ? initialContent : void 0,
|
|
});
|
|
const warnedRef = useRef(false);
|
|
const handleChange = useCallback(() => {
|
|
const blocks = editor.document;
|
|
const json = JSON.stringify(blocks);
|
|
if (maxLength !== void 0) {
|
|
let charCount = 0;
|
|
const countChars = (b) => {
|
|
if (b.content && Array.isArray(b.content)) {
|
|
for (const item of b.content) {
|
|
if (typeof item === "object" && "text" in item) {
|
|
charCount += item.text.length;
|
|
}
|
|
}
|
|
}
|
|
if (b.children && Array.isArray(b.children)) {
|
|
for (const child of b.children) countChars(child);
|
|
}
|
|
};
|
|
for (const block of blocks) countChars(block);
|
|
if (charCount > maxLength && !warnedRef.current) {
|
|
console.warn(`[BlockNoteEditor] Content exceeds maxLength (${charCount}/${maxLength})`);
|
|
warnedRef.current = true;
|
|
} else if (charCount <= maxLength) {
|
|
warnedRef.current = false;
|
|
}
|
|
}
|
|
onChange(json);
|
|
}, [editor, onChange, maxLength]);
|
|
useEffect(() => {
|
|
return editor.onChange(handleChange);
|
|
}, [editor, handleChange]);
|
|
useEffect(() => {
|
|
if (autoFocus && !readOnly) {
|
|
editor.focus();
|
|
}
|
|
}, [autoFocus, readOnly, editor]);
|
|
const wrapperRef = useRef(null);
|
|
const handleBlur = useCallback(
|
|
(e) => {
|
|
if (!onBlur) return;
|
|
if (wrapperRef.current && !wrapperRef.current.contains(e.relatedTarget)) {
|
|
onBlur();
|
|
}
|
|
},
|
|
[onBlur],
|
|
);
|
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", {
|
|
ref: wrapperRef,
|
|
className: "blocknote-editor-wrapper " + (className ?? ""),
|
|
onBlur: onBlur ? handleBlur : void 0,
|
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Ot, {
|
|
editor,
|
|
editable: !readOnly,
|
|
theme,
|
|
}),
|
|
});
|
|
}
|
|
|
|
export { BlockNoteEditorInner };
|