Files
base/.svelte-kit/adapter-node/entries/pages/_layout.svelte.js
T
eewing ec317eb17c
CI / build (push) Has been skipped
CI / deploy (push) Successful in 1m11s
INIT
2026-02-18 15:17:47 -06:00

3984 lines
122 KiB
JavaScript

import { l as lifecycle_function_unavailable, h as hasContext, g as getContext, s as setContext, d as derived, a as getAllContexts, p as props_id, b as attributes, c as bind_props, e as spread_props, f as escape_html } from "../../chunks/index2.js";
import "clsx";
import "@sveltejs/kit/internal";
import "../../chunks/exports.js";
import "../../chunks/utils.js";
import "@sveltejs/kit/internal/server";
import { o as on } from "../../chunks/root.js";
import "../../chunks/state.svelte.js";
import { c as cn } from "../../chunks/utils2.js";
import { i as isWritableSymbol, B as BoxSymbol, b as boxFrom, a as boxWith, c as boxFlatten, t as toReadonlyBox, d as isBox, e as isWritableBox, s as styleToString, f as isObject, g as executeCallbacks, h as attachRef, j as createBitsAttrs, k as getDataOpenClosed, l as boolToEmptyStrOrUndef, m as boolToStr, n as simpleBox, o as composeHandlers, p as createId, q as mergeProps, r as cssToStyleObj, u as getDataChecked, v as getAriaChecked, w as boolToTrueOrUndef, L as Label } from "../../chunks/label.js";
import { isTabbable, tabbable, isFocusable, focusable } from "tabbable";
import { computePosition, offset, shift, limitShift, flip, size, arrow, hide } from "@floating-ui/dom";
function mount() {
lifecycle_function_unavailable("mount");
}
function unmount() {
lifecycle_function_unavailable("unmount");
}
async function tick() {
}
function box(initialValue) {
let current = initialValue;
return {
[BoxSymbol]: true,
[isWritableSymbol]: true,
get current() {
return current;
},
set current(v) {
current = v;
}
};
}
box.from = boxFrom;
box.with = boxWith;
box.flatten = boxFlatten;
box.readonly = toReadonlyBox;
box.isBox = isBox;
box.isWritableBox = isWritableBox;
const srOnlyStyles = {
position: "absolute",
width: "1px",
height: "1px",
padding: "0",
margin: "-1px",
overflow: "hidden",
clip: "rect(0, 0, 0, 0)",
whiteSpace: "nowrap",
borderWidth: "0",
transform: "translateX(-100%)"
};
const srOnlyStylesString = styleToString(srOnlyStyles);
const defaultWindow = void 0;
function getActiveElement$1(document2) {
let activeElement = document2.activeElement;
while (activeElement?.shadowRoot) {
const node = activeElement.shadowRoot.activeElement;
if (node === activeElement)
break;
else
activeElement = node;
}
return activeElement;
}
const SvelteMap = globalThis.Map;
function createSubscriber(_) {
return () => {
};
}
class ActiveElement {
#document;
#subscribe;
constructor(options = {}) {
const { window: window2 = defaultWindow, document: document2 = window2?.document } = options;
if (window2 === void 0) return;
this.#document = document2;
this.#subscribe = createSubscriber();
}
get current() {
this.#subscribe?.();
if (!this.#document) return null;
return getActiveElement$1(this.#document);
}
}
new ActiveElement();
function isFunction(value) {
return typeof value === "function";
}
class Context {
#name;
#key;
/**
* @param name The name of the context.
* This is used for generating the context key and error messages.
*/
constructor(name) {
this.#name = name;
this.#key = Symbol(name);
}
/**
* The key used to get and set the context.
*
* It is not recommended to use this value directly.
* Instead, use the methods provided by this class.
*/
get key() {
return this.#key;
}
/**
* Checks whether this has been set in the context of a parent component.
*
* Must be called during component initialisation.
*/
exists() {
return hasContext(this.#key);
}
/**
* Retrieves the context that belongs to the closest parent component.
*
* Must be called during component initialisation.
*
* @throws An error if the context does not exist.
*/
get() {
const context = getContext(this.#key);
if (context === void 0) {
throw new Error(`Context "${this.#name}" not found`);
}
return context;
}
/**
* Retrieves the context that belongs to the closest parent component,
* or the given fallback value if the context does not exist.
*
* Must be called during component initialisation.
*/
getOr(fallback) {
const context = getContext(this.#key);
if (context === void 0) {
return fallback;
}
return context;
}
/**
* Associates the given value with the current component and returns it.
*
* Must be called during component initialisation.
*/
set(context) {
return setContext(this.#key, context);
}
}
function runWatcher(sources, flush, effect, options = {}) {
const { lazy = false } = options;
}
function watch(sources, effect, options) {
runWatcher(sources, "post", effect, options);
}
function watchPre(sources, effect, options) {
runWatcher(sources, "pre", effect, options);
}
watch.pre = watchPre;
function get$1(value) {
if (isFunction(value)) {
return value();
}
return value;
}
class ElementSize {
// no need to use `$state` here since we are using createSubscriber
#size = { width: 0, height: 0 };
#observed = false;
#options;
#node;
#window;
// we use a derived here to extract the width so that if the width doesn't change we don't get a state update
// which we would get if we would just use a getter since the version of the subscriber will be changing
#width = derived(() => {
this.#subscribe()?.();
return this.getSize().width;
});
// we use a derived here to extract the height so that if the height doesn't change we don't get a state update
// which we would get if we would just use a getter since the version of the subscriber will be changing
#height = derived(() => {
this.#subscribe()?.();
return this.getSize().height;
});
// we need to use a derived here because the class will be created before the node is bound to the ref
#subscribe = derived(() => {
const node$ = get$1(this.#node);
if (!node$) return;
return createSubscriber();
});
constructor(node, options = { box: "border-box" }) {
this.#window = options.window ?? defaultWindow;
this.#options = options;
this.#node = node;
this.#size = { width: 0, height: 0 };
}
calculateSize() {
const element = get$1(this.#node);
if (!element || !this.#window) {
return;
}
const offsetWidth = element.offsetWidth;
const offsetHeight = element.offsetHeight;
if (this.#options.box === "border-box") {
return { width: offsetWidth, height: offsetHeight };
}
const style = this.#window.getComputedStyle(element);
const paddingWidth = parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);
const paddingHeight = parseFloat(style.paddingTop) + parseFloat(style.paddingBottom);
const borderWidth = parseFloat(style.borderLeftWidth) + parseFloat(style.borderRightWidth);
const borderHeight = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth);
const contentWidth = offsetWidth - paddingWidth - borderWidth;
const contentHeight = offsetHeight - paddingHeight - borderHeight;
return { width: contentWidth, height: contentHeight };
}
getSize() {
return this.#observed ? this.#size : this.calculateSize() ?? this.#size;
}
get current() {
this.#subscribe()?.();
return this.getSize();
}
get width() {
return this.#width();
}
get height() {
return this.#height();
}
}
function afterSleep(ms, cb) {
return setTimeout(cb, ms);
}
function afterTick(fn) {
tick().then(fn);
}
const ELEMENT_NODE = 1;
const DOCUMENT_NODE = 9;
const DOCUMENT_FRAGMENT_NODE = 11;
function isHTMLElement$1(node) {
return isObject(node) && node.nodeType === ELEMENT_NODE && typeof node.nodeName === "string";
}
function isDocument(node) {
return isObject(node) && node.nodeType === DOCUMENT_NODE;
}
function isWindow(node) {
return isObject(node) && node.constructor?.name === "VisualViewport";
}
function isNode(node) {
return isObject(node) && node.nodeType !== void 0;
}
function isShadowRoot(node) {
return isNode(node) && node.nodeType === DOCUMENT_FRAGMENT_NODE && "host" in node;
}
function contains(parent, child) {
if (!parent || !child)
return false;
if (!isHTMLElement$1(parent) || !isHTMLElement$1(child))
return false;
const rootNode = child.getRootNode?.();
if (parent === child)
return true;
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 getDocument(node) {
if (isDocument(node))
return node;
if (isWindow(node))
return node.document;
return node?.ownerDocument ?? document;
}
function getWindow(node) {
if (isShadowRoot(node))
return getWindow(node.host);
if (isDocument(node))
return node.defaultView ?? window;
if (isHTMLElement$1(node))
return node.ownerDocument?.defaultView ?? window;
return window;
}
function getActiveElement(rootNode) {
let activeElement = rootNode.activeElement;
while (activeElement?.shadowRoot) {
const el = activeElement.shadowRoot.activeElement;
if (el === activeElement)
break;
else
activeElement = el;
}
return activeElement;
}
class DOMContext {
element;
#root = derived(() => {
if (!this.element.current) return document;
const rootNode = this.element.current.getRootNode() ?? document;
return rootNode;
});
get root() {
return this.#root();
}
set root($$value) {
return this.#root($$value);
}
constructor(element) {
if (typeof element === "function") {
this.element = boxWith(element);
} else {
this.element = element;
}
}
getDocument = () => {
return getDocument(this.root);
};
getWindow = () => {
return this.getDocument().defaultView ?? window;
};
getActiveElement = () => {
return getActiveElement(this.root);
};
isActiveElement = (node) => {
return node === this.getActiveElement();
};
getElementById(id) {
return this.root.getElementById(id);
}
querySelector = (selector) => {
if (!this.root) return null;
return this.root.querySelector(selector);
};
querySelectorAll = (selector) => {
if (!this.root) return [];
return this.root.querySelectorAll(selector);
};
setTimeout = (callback, delay) => {
return this.getWindow().setTimeout(callback, delay);
};
clearTimeout = (timeoutId) => {
return this.getWindow().clearTimeout(timeoutId);
};
}
const ARROW_DOWN = "ArrowDown";
const ARROW_LEFT = "ArrowLeft";
const ARROW_RIGHT = "ArrowRight";
const ARROW_UP = "ArrowUp";
const END = "End";
const ENTER = "Enter";
const ESCAPE = "Escape";
const HOME = "Home";
const PAGE_DOWN = "PageDown";
const PAGE_UP = "PageUp";
const SPACE = " ";
const TAB = "Tab";
function getElemDirection(elem) {
const style = window.getComputedStyle(elem);
const direction = style.getPropertyValue("direction");
return direction;
}
function getNextKey(dir = "ltr", orientation = "horizontal") {
return {
horizontal: dir === "rtl" ? ARROW_LEFT : ARROW_RIGHT,
vertical: ARROW_DOWN
}[orientation];
}
function getPrevKey(dir = "ltr", orientation = "horizontal") {
return {
horizontal: dir === "rtl" ? ARROW_RIGHT : ARROW_LEFT,
vertical: ARROW_UP
}[orientation];
}
function getDirectionalKeys(dir = "ltr", orientation = "horizontal") {
if (!["ltr", "rtl"].includes(dir))
dir = "ltr";
if (!["horizontal", "vertical"].includes(orientation))
orientation = "horizontal";
return {
nextKey: getNextKey(dir, orientation),
prevKey: getPrevKey(dir, orientation)
};
}
const isBrowser = typeof document !== "undefined";
const isIOS = getIsIOS();
function getIsIOS() {
return isBrowser && window?.navigator?.userAgent && (/iP(ad|hone|od)/.test(window.navigator.userAgent) || // The new iPad Pro Gen3 does not identify itself as iPad, but as Macintosh.
window?.navigator?.maxTouchPoints > 2 && /iPad|Macintosh/.test(window?.navigator.userAgent));
}
function isHTMLElement(element) {
return element instanceof HTMLElement;
}
function isElement(element) {
return element instanceof Element;
}
function isElementOrSVGElement(element) {
return element instanceof Element || element instanceof SVGElement;
}
function isNotNull(value) {
return value !== null;
}
function isSelectableInput(element) {
return element instanceof HTMLInputElement && "select" in element;
}
class RovingFocusGroup {
#opts;
#currentTabStopId = box(null);
constructor(opts) {
this.#opts = opts;
}
getCandidateNodes() {
return [];
}
focusFirstCandidate() {
const items = this.getCandidateNodes();
if (!items.length)
return;
items[0]?.focus();
}
handleKeydown(node, e, both = false) {
const rootNode = this.#opts.rootNode.current;
if (!rootNode || !node)
return;
const items = this.getCandidateNodes();
if (!items.length)
return;
const currentIndex = items.indexOf(node);
const dir = getElemDirection(rootNode);
const { nextKey, prevKey } = getDirectionalKeys(dir, this.#opts.orientation.current);
const loop = this.#opts.loop.current;
const keyToIndex = {
[nextKey]: currentIndex + 1,
[prevKey]: currentIndex - 1,
[HOME]: 0,
[END]: items.length - 1
};
if (both) {
const altNextKey = nextKey === ARROW_DOWN ? ARROW_RIGHT : ARROW_DOWN;
const altPrevKey = prevKey === ARROW_UP ? ARROW_LEFT : ARROW_UP;
keyToIndex[altNextKey] = currentIndex + 1;
keyToIndex[altPrevKey] = currentIndex - 1;
}
let itemIndex = keyToIndex[e.key];
if (itemIndex === void 0)
return;
e.preventDefault();
if (itemIndex < 0 && loop) {
itemIndex = items.length - 1;
} else if (itemIndex === items.length && loop) {
itemIndex = 0;
}
const itemToFocus = items[itemIndex];
if (!itemToFocus)
return;
itemToFocus.focus();
this.#currentTabStopId.current = itemToFocus.id;
this.#opts.onCandidateFocus?.(itemToFocus);
return itemToFocus;
}
getTabIndex(node) {
const items = this.getCandidateNodes();
const anyActive = this.#currentTabStopId.current !== null;
if (node && !anyActive && items[0] === node) {
this.#currentTabStopId.current = node.id;
return 0;
} else if (node?.id === this.#currentTabStopId.current) {
return 0;
}
return -1;
}
setCurrentTabStopId(id) {
this.#currentTabStopId.current = id;
}
focusCurrentTabStop() {
const currentTabStopId = this.#currentTabStopId.current;
if (!currentTabStopId)
return;
const currentTabStop = this.#opts.rootNode.current?.querySelector(`#${currentTabStopId}`);
if (!currentTabStop || !isHTMLElement(currentTabStop))
return;
currentTabStop.focus();
}
}
class AnimationsComplete {
#opts;
#currentFrame = null;
constructor(opts) {
this.#opts = opts;
}
#cleanup() {
if (!this.#currentFrame)
return;
window.cancelAnimationFrame(this.#currentFrame);
this.#currentFrame = null;
}
run(fn) {
this.#cleanup();
const node = this.#opts.ref.current;
if (!node)
return;
if (typeof node.getAnimations !== "function") {
this.#executeCallback(fn);
return;
}
this.#currentFrame = window.requestAnimationFrame(() => {
const animations = node.getAnimations();
if (animations.length === 0) {
this.#executeCallback(fn);
return;
}
Promise.allSettled(animations.map((animation) => animation.finished)).then(() => {
this.#executeCallback(fn);
});
});
}
#executeCallback(fn) {
const execute = () => {
fn();
};
if (this.#opts.afterTick) {
afterTick(execute);
} else {
execute();
}
}
}
class PresenceManager {
#opts;
#enabled;
#afterAnimations;
#shouldRender = false;
constructor(opts) {
this.#opts = opts;
this.#shouldRender = opts.open.current;
this.#enabled = opts.enabled ?? true;
this.#afterAnimations = new AnimationsComplete({ ref: this.#opts.ref, afterTick: this.#opts.open });
watch(() => this.#opts.open.current, (isOpen) => {
if (isOpen) this.#shouldRender = true;
if (!this.#enabled) return;
this.#afterAnimations.run(() => {
if (isOpen === this.#opts.open.current) {
if (!this.#opts.open.current) {
this.#shouldRender = false;
}
this.#opts.onComplete?.();
}
});
});
}
get shouldRender() {
return this.#shouldRender;
}
}
function noop() {
}
const BitsConfigContext = new Context("BitsConfig");
function getBitsConfig() {
const fallback = new BitsConfigState(null, {});
return BitsConfigContext.getOr(fallback).opts;
}
class BitsConfigState {
opts;
constructor(parent, opts) {
const resolveConfigOption = createConfigResolver(parent, opts);
this.opts = {
defaultPortalTo: resolveConfigOption((config) => config.defaultPortalTo),
defaultLocale: resolveConfigOption((config) => config.defaultLocale)
};
}
}
function createConfigResolver(parent, currentOpts) {
return (getter) => {
const configOption = boxWith(() => {
const value = getter(currentOpts)?.current;
if (value !== void 0)
return value;
if (parent === null)
return void 0;
return getter(parent.opts)?.current;
});
return configOption;
};
}
function createPropResolver(configOption, fallback) {
return (getProp) => {
const config = getBitsConfig();
return boxWith(() => {
const propValue = getProp();
if (propValue !== void 0)
return propValue;
const option = configOption(config).current;
if (option !== void 0)
return option;
return fallback;
});
};
}
const resolvePortalToProp = createPropResolver((config) => config.defaultPortalTo, "body");
function Portal($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let { to: toProp, children, disabled } = $$props;
const to = resolvePortalToProp(() => toProp);
getAllContexts();
let target = getTarget();
function getTarget() {
if (!isBrowser || disabled) return null;
let localTarget = null;
if (typeof to.current === "string") {
const target2 = document.querySelector(to.current);
localTarget = target2;
} else {
localTarget = to.current;
}
return localTarget;
}
let instance;
function unmountInstance() {
if (instance) {
unmount();
instance = null;
}
}
watch([() => target, () => disabled], ([target2, disabled2]) => {
if (!target2 || disabled2) {
unmountInstance();
return;
}
instance = mount();
return () => {
unmountInstance();
};
});
if (disabled) {
$$renderer2.push("<!--[-->");
children?.($$renderer2);
$$renderer2.push(`<!---->`);
} else {
$$renderer2.push("<!--[!-->");
}
$$renderer2.push(`<!--]-->`);
});
}
class CustomEventDispatcher {
eventName;
options;
constructor(eventName, options = { bubbles: true, cancelable: true }) {
this.eventName = eventName;
this.options = options;
}
createEvent(detail) {
return new CustomEvent(this.eventName, {
...this.options,
detail
});
}
dispatch(element, detail) {
const event = this.createEvent(detail);
element.dispatchEvent(event);
return event;
}
listen(element, callback, options) {
const handler = (event) => {
callback(event);
};
return on(element, this.eventName, handler, options);
}
}
function debounce(fn, wait = 500) {
let timeout = null;
const debounced = (...args) => {
if (timeout !== null) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
fn(...args);
}, wait);
};
debounced.destroy = () => {
if (timeout !== null) {
clearTimeout(timeout);
timeout = null;
}
};
return debounced;
}
function isOrContainsTarget(node, target) {
return node === target || node.contains(target);
}
function getOwnerDocument(el) {
return el?.ownerDocument ?? document;
}
function isClickTrulyOutside(event, contentNode) {
const { clientX, clientY } = event;
const rect = contentNode.getBoundingClientRect();
return clientX < rect.left || clientX > rect.right || clientY < rect.top || clientY > rect.bottom;
}
const FIRST_KEYS = [ARROW_DOWN, PAGE_UP, HOME];
const LAST_KEYS = [ARROW_UP, PAGE_DOWN, END];
const FIRST_LAST_KEYS = [...FIRST_KEYS, ...LAST_KEYS];
function focus(element, { select = false } = {}) {
if (!element || !element.focus)
return;
const doc = getDocument(element);
if (doc.activeElement === element)
return;
const previouslyFocusedElement = doc.activeElement;
element.focus({ preventScroll: true });
if (element !== previouslyFocusedElement && isSelectableInput(element) && select) {
element.select();
}
}
function focusFirst(candidates, { select = false } = {}, getActiveElement2) {
const previouslyFocusedElement = getActiveElement2();
for (const candidate of candidates) {
focus(candidate, { select });
if (getActiveElement2() !== previouslyFocusedElement)
return true;
}
}
let isUsingKeyboard = false;
class IsUsingKeyboard {
static _refs = 0;
// Reference counting to avoid multiple listeners.
static _cleanup;
constructor() {
}
get current() {
return isUsingKeyboard;
}
set current(value) {
isUsingKeyboard = value;
}
}
function getTabbableOptions() {
return {
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 getTabbableFrom(currentNode, direction) {
if (!isTabbable(currentNode, getTabbableOptions())) {
return getTabbableFromFocusable(currentNode, direction);
}
const doc = getDocument(currentNode);
const allTabbable = tabbable(doc.body, getTabbableOptions());
if (direction === "prev")
allTabbable.reverse();
const activeIndex = allTabbable.indexOf(currentNode);
if (activeIndex === -1)
return doc.body;
const nextTabbableElements = allTabbable.slice(activeIndex + 1);
return nextTabbableElements[0];
}
function getTabbableFromFocusable(currentNode, direction) {
const doc = getDocument(currentNode);
if (!isFocusable(currentNode, getTabbableOptions()))
return doc.body;
const allFocusable = focusable(doc.body, getTabbableOptions());
if (direction === "prev")
allFocusable.reverse();
const activeIndex = allFocusable.indexOf(currentNode);
if (activeIndex === -1)
return doc.body;
const nextFocusableElements = allFocusable.slice(activeIndex + 1);
return nextFocusableElements.find((node) => isTabbable(node, getTabbableOptions())) ?? doc.body;
}
function getNextMatch(values, search, currentMatch) {
const lowerSearch = search.toLowerCase();
if (lowerSearch.endsWith(" ")) {
const searchWithoutSpace = lowerSearch.slice(0, -1);
const matchesWithoutSpace = values.filter((value) => value.toLowerCase().startsWith(searchWithoutSpace));
if (matchesWithoutSpace.length <= 1) {
return getNextMatch(values, searchWithoutSpace, currentMatch);
}
const currentMatchLowercase = currentMatch?.toLowerCase();
if (currentMatchLowercase && currentMatchLowercase.startsWith(searchWithoutSpace) && currentMatchLowercase.charAt(searchWithoutSpace.length) === " " && search.trim() === searchWithoutSpace) {
return currentMatch;
}
const spacedMatches = values.filter((value) => value.toLowerCase().startsWith(lowerSearch));
if (spacedMatches.length > 0) {
const currentMatchIndex2 = currentMatch ? values.indexOf(currentMatch) : -1;
let wrappedMatches = wrapArray(spacedMatches, Math.max(currentMatchIndex2, 0));
const nextMatch2 = wrappedMatches.find((match) => match !== currentMatch);
return nextMatch2 || currentMatch;
}
}
const isRepeated = search.length > 1 && Array.from(search).every((char) => char === search[0]);
const normalizedSearch = isRepeated ? search[0] : search;
const normalizedLowerSearch = normalizedSearch.toLowerCase();
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(normalizedLowerSearch));
return nextMatch !== currentMatch ? nextMatch : void 0;
}
function wrapArray(array, startIndex) {
return array.map((_, index) => array[(startIndex + index) % array.length]);
}
const defaultOptions = { afterMs: 1e4, onChange: noop };
function boxAutoReset(defaultValue, options) {
const { afterMs, onChange, getWindow: getWindow2 } = { ...defaultOptions, ...options };
let timeout = null;
let value = defaultValue;
function resetAfter() {
return getWindow2().setTimeout(
() => {
value = defaultValue;
onChange?.(defaultValue);
},
afterMs
);
}
return boxWith(() => value, (v) => {
value = v;
onChange?.(v);
if (timeout) getWindow2().clearTimeout(timeout);
timeout = resetAfter();
});
}
class DOMTypeahead {
#opts;
#search;
#onMatch = derived(() => {
if (this.#opts.onMatch) return this.#opts.onMatch;
return (node) => node.focus();
});
#getCurrentItem = derived(() => {
if (this.#opts.getCurrentItem) return this.#opts.getCurrentItem;
return this.#opts.getActiveElement;
});
constructor(opts) {
this.#opts = opts;
this.#search = boxAutoReset("", { afterMs: 1e3, getWindow: opts.getWindow });
this.handleTypeaheadSearch = this.handleTypeaheadSearch.bind(this);
this.resetTypeahead = this.resetTypeahead.bind(this);
}
handleTypeaheadSearch(key, candidates) {
if (!candidates.length) return;
this.#search.current = this.#search.current + key;
const currentItem = this.#getCurrentItem()();
const currentMatch = candidates.find((item) => item === currentItem)?.textContent?.trim() ?? "";
const values = candidates.map((item) => item.textContent?.trim() ?? "");
const nextMatch = getNextMatch(values, this.#search.current, currentMatch);
const newItem = candidates.find((item) => item.textContent?.trim() === nextMatch);
if (newItem) this.#onMatch()(newItem);
return newItem;
}
resetTypeahead() {
this.#search.current = "";
}
get search() {
return this.#search.current;
}
}
class GraceArea {
#opts;
#enabled;
#isPointerInTransit;
#pointerGraceArea = null;
constructor(opts) {
this.#opts = opts;
this.#enabled = derived(() => this.#opts.enabled());
this.#isPointerInTransit = boxAutoReset(false, {
afterMs: opts.transitTimeout ?? 300,
onChange: (value) => {
if (!this.#enabled()) return;
this.#opts.setIsPointerInTransit?.(value);
},
getWindow: () => getWindow(this.#opts.triggerNode())
});
watch([opts.triggerNode, opts.contentNode, opts.enabled], ([triggerNode, contentNode, enabled]) => {
if (!triggerNode || !contentNode || !enabled) return;
const handleTriggerLeave = (e) => {
this.#createGraceArea(e, contentNode);
};
const handleContentLeave = (e) => {
this.#createGraceArea(e, triggerNode);
};
return executeCallbacks(on(triggerNode, "pointerleave", handleTriggerLeave), on(contentNode, "pointerleave", handleContentLeave));
});
watch(() => this.#pointerGraceArea, () => {
const handleTrackPointerGrace = (e) => {
if (!this.#pointerGraceArea) return;
const target = e.target;
if (!isElement(target)) return;
const pointerPosition = { x: e.clientX, y: e.clientY };
const hasEnteredTarget = opts.triggerNode()?.contains(target) || opts.contentNode()?.contains(target);
const isPointerOutsideGraceArea = !isPointInPolygon(pointerPosition, this.#pointerGraceArea);
if (hasEnteredTarget) {
this.#removeGraceArea();
} else if (isPointerOutsideGraceArea) {
this.#removeGraceArea();
opts.onPointerExit();
}
};
const doc = getDocument(opts.triggerNode() ?? opts.contentNode());
if (!doc) return;
return on(doc, "pointermove", handleTrackPointerGrace);
});
}
#removeGraceArea() {
this.#pointerGraceArea = null;
this.#isPointerInTransit.current = false;
}
#createGraceArea(e, hoverTarget) {
const currentTarget = e.currentTarget;
if (!isHTMLElement(currentTarget)) return;
const exitPoint = { x: e.clientX, y: e.clientY };
const exitSide = getExitSideFromRect(exitPoint, currentTarget.getBoundingClientRect());
const paddedExitPoints = getPaddedExitPoints(exitPoint, exitSide);
const hoverTargetPoints = getPointsFromRect(hoverTarget.getBoundingClientRect());
const graceArea = getHull([...paddedExitPoints, ...hoverTargetPoints]);
this.#pointerGraceArea = graceArea;
this.#isPointerInTransit.current = true;
}
}
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 tipPadding = padding * 1.5;
switch (exitSide) {
case "top":
return [
{ x: exitPoint.x - padding, y: exitPoint.y + padding },
{ x: exitPoint.x, y: exitPoint.y - tipPadding },
{ x: exitPoint.x + padding, y: exitPoint.y + padding }
];
case "bottom":
return [
{ x: exitPoint.x - padding, y: exitPoint.y - padding },
{ x: exitPoint.x, y: exitPoint.y + tipPadding },
{ x: exitPoint.x + padding, y: exitPoint.y - padding }
];
case "left":
return [
{ x: exitPoint.x + padding, y: exitPoint.y - padding },
{ x: exitPoint.x - tipPadding, y: exitPoint.y },
{ x: exitPoint.x + padding, y: exitPoint.y + padding }
];
case "right":
return [
{ x: exitPoint.x - padding, y: exitPoint.y - padding },
{ x: exitPoint.x + tipPadding, y: exitPoint.y },
{ x: exitPoint.x - padding, y: exitPoint.y + padding }
];
}
}
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 xi = polygon[i].x;
const yi = polygon[i].y;
const xj = polygon[j].x;
const yj = polygon[j].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);
}
const CONTEXT_MENU_TRIGGER_ATTR = "data-context-menu-trigger";
const CONTEXT_MENU_CONTENT_ATTR = "data-context-menu-content";
const MenuRootContext = new Context("Menu.Root");
const MenuMenuContext = new Context("Menu.Root | Menu.Sub");
const MenuContentContext = new Context("Menu.Content");
const MenuOpenEvent = new CustomEventDispatcher("bitsmenuopen", { bubbles: false, cancelable: true });
const menuAttrs = createBitsAttrs({
component: "menu",
parts: [
"trigger",
"content",
"sub-trigger",
"item",
"group",
"group-heading",
"checkbox-group",
"checkbox-item",
"radio-group",
"radio-item",
"separator",
"sub-content",
"arrow"
]
});
class MenuRootState {
static create(opts) {
const root = new MenuRootState(opts);
return MenuRootContext.set(root);
}
opts;
isUsingKeyboard = new IsUsingKeyboard();
ignoreCloseAutoFocus = false;
isPointerInTransit = false;
constructor(opts) {
this.opts = opts;
}
getBitsAttr = (part) => {
return menuAttrs.getAttr(part, this.opts.variant.current);
};
}
class MenuMenuState {
static create(opts, root) {
return MenuMenuContext.set(new MenuMenuState(opts, root, null));
}
opts;
root;
parentMenu;
contentId = boxWith(() => "");
contentNode = null;
contentPresence;
triggerNode = null;
constructor(opts, root, parentMenu) {
this.opts = opts;
this.root = root;
this.parentMenu = parentMenu;
this.contentPresence = new PresenceManager({
ref: boxWith(() => this.contentNode),
open: this.opts.open,
onComplete: () => {
this.opts.onOpenChangeComplete.current(this.opts.open.current);
}
});
if (parentMenu) {
watch(() => parentMenu.opts.open.current, () => {
if (parentMenu.opts.open.current) return;
this.opts.open.current = false;
});
}
}
toggleOpen() {
this.opts.open.current = !this.opts.open.current;
}
onOpen() {
this.opts.open.current = true;
}
onClose() {
this.opts.open.current = false;
}
}
class MenuContentState {
static create(opts) {
return MenuContentContext.set(new MenuContentState(opts, MenuMenuContext.get()));
}
opts;
parentMenu;
rovingFocusGroup;
domContext;
attachment;
search = "";
#timer = 0;
#handleTypeaheadSearch;
mounted = false;
#isSub;
constructor(opts, parentMenu) {
this.opts = opts;
this.parentMenu = parentMenu;
this.domContext = new DOMContext(opts.ref);
this.attachment = attachRef(this.opts.ref, (v) => {
if (this.parentMenu.contentNode !== v) {
this.parentMenu.contentNode = v;
}
});
parentMenu.contentId = opts.id;
this.#isSub = opts.isSub ?? false;
this.onkeydown = this.onkeydown.bind(this);
this.onblur = this.onblur.bind(this);
this.onfocus = this.onfocus.bind(this);
this.handleInteractOutside = this.handleInteractOutside.bind(this);
new GraceArea({
contentNode: () => this.parentMenu.contentNode,
triggerNode: () => this.parentMenu.triggerNode,
enabled: () => this.parentMenu.opts.open.current && Boolean(this.parentMenu.triggerNode?.hasAttribute(this.parentMenu.root.getBitsAttr("sub-trigger"))),
onPointerExit: () => {
this.parentMenu.opts.open.current = false;
},
setIsPointerInTransit: (value) => {
this.parentMenu.root.isPointerInTransit = value;
}
});
this.#handleTypeaheadSearch = new DOMTypeahead({
getActiveElement: () => this.domContext.getActiveElement(),
getWindow: () => this.domContext.getWindow()
}).handleTypeaheadSearch;
this.rovingFocusGroup = new RovingFocusGroup({
rootNode: boxWith(() => this.parentMenu.contentNode),
candidateAttr: this.parentMenu.root.getBitsAttr("item"),
loop: this.opts.loop,
orientation: boxWith(() => "vertical")
});
watch(() => this.parentMenu.contentNode, (contentNode) => {
if (!contentNode) return;
const handler = () => {
afterTick(() => {
if (!this.parentMenu.root.isUsingKeyboard.current) return;
this.rovingFocusGroup.focusFirstCandidate();
});
};
return MenuOpenEvent.listen(contentNode, handler);
});
}
#getCandidateNodes() {
const node = this.parentMenu.contentNode;
if (!node) return [];
const candidates = Array.from(node.querySelectorAll(`[${this.parentMenu.root.getBitsAttr("item")}]:not([data-disabled])`));
return candidates;
}
#isPointerMovingToSubmenu() {
return this.parentMenu.root.isPointerInTransit;
}
onCloseAutoFocus = (e) => {
this.opts.onCloseAutoFocus.current?.(e);
if (e.defaultPrevented || this.#isSub) return;
if (this.parentMenu.triggerNode && isTabbable(this.parentMenu.triggerNode)) {
e.preventDefault();
this.parentMenu.triggerNode.focus();
}
};
handleTabKeyDown(e) {
let rootMenu = this.parentMenu;
while (rootMenu.parentMenu !== null) {
rootMenu = rootMenu.parentMenu;
}
if (!rootMenu.triggerNode) return;
e.preventDefault();
const nodeToFocus = getTabbableFrom(rootMenu.triggerNode, e.shiftKey ? "prev" : "next");
if (nodeToFocus) {
this.parentMenu.root.ignoreCloseAutoFocus = true;
rootMenu.onClose();
afterTick(() => {
nodeToFocus.focus();
afterTick(() => {
this.parentMenu.root.ignoreCloseAutoFocus = false;
});
});
} else {
this.domContext.getDocument().body.focus();
}
}
onkeydown(e) {
if (e.defaultPrevented) return;
if (e.key === TAB) {
this.handleTabKeyDown(e);
return;
}
const target = e.target;
const currentTarget = e.currentTarget;
if (!isHTMLElement(target) || !isHTMLElement(currentTarget)) return;
const isKeydownInside = target.closest(`[${this.parentMenu.root.getBitsAttr("content")}]`)?.id === this.parentMenu.contentId.current;
const isModifierKey = e.ctrlKey || e.altKey || e.metaKey;
const isCharacterKey = e.key.length === 1;
const kbdFocusedEl = this.rovingFocusGroup.handleKeydown(target, e);
if (kbdFocusedEl) return;
if (e.code === "Space") return;
const candidateNodes = this.#getCandidateNodes();
if (isKeydownInside) {
if (!isModifierKey && isCharacterKey) {
this.#handleTypeaheadSearch(e.key, candidateNodes);
}
}
if (e.target?.id !== this.parentMenu.contentId.current) return;
if (!FIRST_LAST_KEYS.includes(e.key)) return;
e.preventDefault();
if (LAST_KEYS.includes(e.key)) {
candidateNodes.reverse();
}
focusFirst(candidateNodes, { select: false }, () => this.domContext.getActiveElement());
}
onblur(e) {
if (!isElement(e.currentTarget)) return;
if (!isElement(e.target)) return;
if (!e.currentTarget.contains?.(e.target)) {
this.domContext.getWindow().clearTimeout(this.#timer);
this.search = "";
}
}
onfocus(_) {
if (!this.parentMenu.root.isUsingKeyboard.current) return;
afterTick(() => this.rovingFocusGroup.focusFirstCandidate());
}
onItemEnter() {
return this.#isPointerMovingToSubmenu();
}
onItemLeave(e) {
if (e.currentTarget.hasAttribute(this.parentMenu.root.getBitsAttr("sub-trigger"))) return;
if (this.#isPointerMovingToSubmenu() || this.parentMenu.root.isUsingKeyboard.current) return;
const contentNode = this.parentMenu.contentNode;
contentNode?.focus();
this.rovingFocusGroup.setCurrentTabStopId("");
}
onTriggerLeave() {
if (this.#isPointerMovingToSubmenu()) return true;
return false;
}
handleInteractOutside(e) {
if (!isElementOrSVGElement(e.target)) return;
const triggerId = this.parentMenu.triggerNode?.id;
if (e.target.id === triggerId) {
e.preventDefault();
return;
}
if (e.target.closest(`#${triggerId}`)) {
e.preventDefault();
}
}
get shouldRender() {
return this.parentMenu.contentPresence.shouldRender;
}
#snippetProps = derived(() => ({ open: this.parentMenu.opts.open.current }));
get snippetProps() {
return this.#snippetProps();
}
set snippetProps($$value) {
return this.#snippetProps($$value);
}
#props = derived(() => ({
id: this.opts.id.current,
role: "menu",
"aria-orientation": "vertical",
[this.parentMenu.root.getBitsAttr("content")]: "",
"data-state": getDataOpenClosed(this.parentMenu.opts.open.current),
onkeydown: this.onkeydown,
onblur: this.onblur,
onfocus: this.onfocus,
dir: this.parentMenu.root.opts.dir.current,
style: { pointerEvents: "auto", contain: "layout style" },
...this.attachment
}));
get props() {
return this.#props();
}
set props($$value) {
return this.#props($$value);
}
popperProps = { onCloseAutoFocus: (e) => this.onCloseAutoFocus(e) };
}
class MenuSeparatorState {
static create(opts) {
return new MenuSeparatorState(opts, MenuRootContext.get());
}
opts;
root;
attachment;
constructor(opts, root) {
this.opts = opts;
this.root = root;
this.attachment = attachRef(this.opts.ref);
}
#props = derived(() => ({
id: this.opts.id.current,
role: "group",
[this.root.getBitsAttr("separator")]: "",
...this.attachment
}));
get props() {
return this.#props();
}
set props($$value) {
return this.#props($$value);
}
}
class DropdownMenuTriggerState {
static create(opts) {
return new DropdownMenuTriggerState(opts, MenuMenuContext.get());
}
opts;
parentMenu;
attachment;
constructor(opts, parentMenu) {
this.opts = opts;
this.parentMenu = parentMenu;
this.attachment = attachRef(this.opts.ref, (v) => this.parentMenu.triggerNode = v);
}
onclick = (e) => {
if (this.opts.disabled.current || e.detail !== 0) return;
this.parentMenu.toggleOpen();
e.preventDefault();
};
onpointerdown = (e) => {
if (this.opts.disabled.current) return;
if (e.pointerType === "touch") return e.preventDefault();
if (e.button === 0 && e.ctrlKey === false) {
this.parentMenu.toggleOpen();
if (!this.parentMenu.opts.open.current) e.preventDefault();
}
};
onpointerup = (e) => {
if (this.opts.disabled.current) return;
if (e.pointerType === "touch") {
e.preventDefault();
this.parentMenu.toggleOpen();
}
};
onkeydown = (e) => {
if (this.opts.disabled.current) return;
if (e.key === SPACE || e.key === ENTER) {
this.parentMenu.toggleOpen();
e.preventDefault();
return;
}
if (e.key === ARROW_DOWN) {
this.parentMenu.onOpen();
e.preventDefault();
}
};
#ariaControls = derived(() => {
if (this.parentMenu.opts.open.current && this.parentMenu.contentId.current) return this.parentMenu.contentId.current;
return void 0;
});
#props = derived(() => ({
id: this.opts.id.current,
disabled: this.opts.disabled.current,
"aria-haspopup": "menu",
"aria-expanded": boolToStr(this.parentMenu.opts.open.current),
"aria-controls": this.#ariaControls(),
"data-disabled": boolToEmptyStrOrUndef(this.opts.disabled.current),
"data-state": getDataOpenClosed(this.parentMenu.opts.open.current),
[this.parentMenu.root.getBitsAttr("trigger")]: "",
//
onclick: this.onclick,
onpointerdown: this.onpointerdown,
onpointerup: this.onpointerup,
onkeydown: this.onkeydown,
...this.attachment
}));
get props() {
return this.#props();
}
set props($$value) {
return this.#props($$value);
}
}
globalThis.bitsDismissableLayers ??= /* @__PURE__ */ new Map();
class DismissibleLayerState {
static create(opts) {
return new DismissibleLayerState(opts);
}
opts;
#interactOutsideProp;
#behaviorType;
#interceptedEvents = { pointerdown: false };
#isResponsibleLayer = false;
#isFocusInsideDOMTree = false;
#documentObj = void 0;
#onFocusOutside;
#unsubClickListener = noop;
constructor(opts) {
this.opts = opts;
this.#behaviorType = opts.interactOutsideBehavior;
this.#interactOutsideProp = opts.onInteractOutside;
this.#onFocusOutside = opts.onFocusOutside;
let unsubEvents = noop;
const cleanup = () => {
this.#resetState();
globalThis.bitsDismissableLayers.delete(this);
this.#handleInteractOutside.destroy();
unsubEvents();
};
watch([() => this.opts.enabled.current, () => this.opts.ref.current], () => {
if (!this.opts.enabled.current || !this.opts.ref.current) return;
afterSleep(1, () => {
if (!this.opts.ref.current) return;
globalThis.bitsDismissableLayers.set(this, this.#behaviorType);
unsubEvents();
unsubEvents = this.#addEventListeners();
});
return cleanup;
});
}
#handleFocus = (event) => {
if (event.defaultPrevented) return;
if (!this.opts.ref.current) return;
afterTick(() => {
if (!this.opts.ref.current || this.#isTargetWithinLayer(event.target)) return;
if (event.target && !this.#isFocusInsideDOMTree) {
this.#onFocusOutside.current?.(event);
}
});
};
#addEventListeners() {
return executeCallbacks(
/**
* CAPTURE INTERACTION START
* mark interaction-start event as intercepted.
* mark responsible layer during interaction start
* to avoid checking if is responsible layer during interaction end
* when a new floating element may have been opened.
*/
on(this.#documentObj, "pointerdown", executeCallbacks(this.#markInterceptedEvent, this.#markResponsibleLayer), { capture: true }),
/**
* BUBBLE INTERACTION START
* Mark interaction-start event as non-intercepted. Debounce `onInteractOutsideStart`
* to avoid prematurely checking if other events were intercepted.
*/
on(this.#documentObj, "pointerdown", executeCallbacks(this.#markNonInterceptedEvent, this.#handleInteractOutside)),
/**
* HANDLE FOCUS OUTSIDE
*/
on(this.#documentObj, "focusin", this.#handleFocus)
);
}
#handleDismiss = (e) => {
let event = e;
if (event.defaultPrevented) {
event = createWrappedEvent(e);
}
this.#interactOutsideProp.current(e);
};
#handleInteractOutside = debounce(
(e) => {
if (!this.opts.ref.current) {
this.#unsubClickListener();
return;
}
const isEventValid = this.opts.isValidEvent.current(e, this.opts.ref.current) || isValidEvent(e, this.opts.ref.current);
if (!this.#isResponsibleLayer || this.#isAnyEventIntercepted() || !isEventValid) {
this.#unsubClickListener();
return;
}
let event = e;
if (event.defaultPrevented) {
event = createWrappedEvent(event);
}
if (this.#behaviorType.current !== "close" && this.#behaviorType.current !== "defer-otherwise-close") {
this.#unsubClickListener();
return;
}
if (e.pointerType === "touch") {
this.#unsubClickListener();
this.#unsubClickListener = on(this.#documentObj, "click", this.#handleDismiss, { once: true });
} else {
this.#interactOutsideProp.current(event);
}
},
10
);
#markInterceptedEvent = (e) => {
this.#interceptedEvents[e.type] = true;
};
#markNonInterceptedEvent = (e) => {
this.#interceptedEvents[e.type] = false;
};
#markResponsibleLayer = () => {
if (!this.opts.ref.current) return;
this.#isResponsibleLayer = isResponsibleLayer(this.opts.ref.current);
};
#isTargetWithinLayer = (target) => {
if (!this.opts.ref.current) return false;
return isOrContainsTarget(this.opts.ref.current, target);
};
#resetState = debounce(
() => {
for (const eventType in this.#interceptedEvents) {
this.#interceptedEvents[eventType] = false;
}
this.#isResponsibleLayer = false;
},
20
);
#isAnyEventIntercepted() {
const i = Object.values(this.#interceptedEvents).some(Boolean);
return i;
}
#onfocuscapture = () => {
this.#isFocusInsideDOMTree = true;
};
#onblurcapture = () => {
this.#isFocusInsideDOMTree = false;
};
props = {
onfocuscapture: this.#onfocuscapture,
onblurcapture: this.#onblurcapture
};
}
function getTopMostDismissableLayer(layersArr = [...globalThis.bitsDismissableLayers]) {
return layersArr.findLast(([_, { current: behaviorType }]) => behaviorType === "close" || behaviorType === "ignore");
}
function isResponsibleLayer(node) {
const layersArr = [...globalThis.bitsDismissableLayers];
const topMostLayer = getTopMostDismissableLayer(layersArr);
if (topMostLayer) return topMostLayer[0].opts.ref.current === node;
const [firstLayerNode] = layersArr[0];
return firstLayerNode.opts.ref.current === node;
}
function isValidEvent(e, node) {
const target = e.target;
if (!isElementOrSVGElement(target)) return false;
const targetIsContextMenuTrigger = Boolean(target.closest(`[${CONTEXT_MENU_TRIGGER_ATTR}]`));
if ("button" in e && e.button > 0 && !targetIsContextMenuTrigger) return false;
if ("button" in e && e.button === 0 && targetIsContextMenuTrigger) return true;
const nodeIsContextMenu = Boolean(node.closest(`[${CONTEXT_MENU_CONTENT_ATTR}]`));
if (targetIsContextMenuTrigger && nodeIsContextMenu) return false;
const ownerDocument = getOwnerDocument(target);
const isValid = ownerDocument.documentElement.contains(target) && !isOrContainsTarget(node, target) && isClickTrulyOutside(e, node);
return isValid;
}
function createWrappedEvent(e) {
const capturedCurrentTarget = e.currentTarget;
const capturedTarget = e.target;
let newEvent;
if (e instanceof PointerEvent) {
newEvent = new PointerEvent(e.type, e);
} else {
newEvent = new PointerEvent("pointerdown", e);
}
let isPrevented = false;
const wrappedEvent = new Proxy(newEvent, {
get: (target, prop) => {
if (prop === "currentTarget") {
return capturedCurrentTarget;
}
if (prop === "target") {
return capturedTarget;
}
if (prop === "preventDefault") {
return () => {
isPrevented = true;
if (typeof target.preventDefault === "function") {
target.preventDefault();
}
};
}
if (prop === "defaultPrevented") {
return isPrevented;
}
if (prop in target) {
return target[prop];
}
return e[prop];
}
});
return wrappedEvent;
}
function Dismissible_layer($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let {
interactOutsideBehavior = "close",
onInteractOutside = noop,
onFocusOutside = noop,
id,
children,
enabled,
isValidEvent: isValidEvent2 = () => false,
ref
} = $$props;
const dismissibleLayerState = DismissibleLayerState.create({
id: boxWith(() => id),
interactOutsideBehavior: boxWith(() => interactOutsideBehavior),
onInteractOutside: boxWith(() => onInteractOutside),
enabled: boxWith(() => enabled),
onFocusOutside: boxWith(() => onFocusOutside),
isValidEvent: boxWith(() => isValidEvent2),
ref
});
children?.($$renderer2, { props: dismissibleLayerState.props });
$$renderer2.push(`<!---->`);
});
}
globalThis.bitsEscapeLayers ??= /* @__PURE__ */ new Map();
class EscapeLayerState {
static create(opts) {
return new EscapeLayerState(opts);
}
opts;
domContext;
constructor(opts) {
this.opts = opts;
this.domContext = new DOMContext(this.opts.ref);
let unsubEvents = noop;
watch(() => opts.enabled.current, (enabled) => {
if (enabled) {
globalThis.bitsEscapeLayers.set(this, opts.escapeKeydownBehavior);
unsubEvents = this.#addEventListener();
}
return () => {
unsubEvents();
globalThis.bitsEscapeLayers.delete(this);
};
});
}
#addEventListener = () => {
return on(this.domContext.getDocument(), "keydown", this.#onkeydown, { passive: false });
};
#onkeydown = (e) => {
if (e.key !== ESCAPE || !isResponsibleEscapeLayer(this)) return;
const clonedEvent = new KeyboardEvent(e.type, e);
e.preventDefault();
const behaviorType = this.opts.escapeKeydownBehavior.current;
if (behaviorType !== "close" && behaviorType !== "defer-otherwise-close") return;
this.opts.onEscapeKeydown.current(clonedEvent);
};
}
function isResponsibleEscapeLayer(instance) {
const layersArr = [...globalThis.bitsEscapeLayers];
const topMostLayer = layersArr.findLast(([_, { current: behaviorType }]) => behaviorType === "close" || behaviorType === "ignore");
if (topMostLayer) return topMostLayer[0] === instance;
const [firstLayerNode] = layersArr[0];
return firstLayerNode === instance;
}
function Escape_layer($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let {
escapeKeydownBehavior = "close",
onEscapeKeydown = noop,
children,
enabled,
ref
} = $$props;
EscapeLayerState.create({
escapeKeydownBehavior: boxWith(() => escapeKeydownBehavior),
onEscapeKeydown: boxWith(() => onEscapeKeydown),
enabled: boxWith(() => enabled),
ref
});
children?.($$renderer2);
$$renderer2.push(`<!---->`);
});
}
class FocusScopeManager {
static instance;
#scopeStack = simpleBox([]);
#focusHistory = /* @__PURE__ */ new WeakMap();
#preFocusHistory = /* @__PURE__ */ new WeakMap();
static getInstance() {
if (!this.instance) {
this.instance = new FocusScopeManager();
}
return this.instance;
}
register(scope) {
const current = this.getActive();
if (current && current !== scope) {
current.pause();
}
const activeElement = document.activeElement;
if (activeElement && activeElement !== document.body) {
this.#preFocusHistory.set(scope, activeElement);
}
this.#scopeStack.current = this.#scopeStack.current.filter((s) => s !== scope);
this.#scopeStack.current.unshift(scope);
}
unregister(scope) {
this.#scopeStack.current = this.#scopeStack.current.filter((s) => s !== scope);
const next = this.getActive();
if (next) {
next.resume();
}
}
getActive() {
return this.#scopeStack.current[0];
}
setFocusMemory(scope, element) {
this.#focusHistory.set(scope, element);
}
getFocusMemory(scope) {
return this.#focusHistory.get(scope);
}
isActiveScope(scope) {
return this.getActive() === scope;
}
setPreFocusMemory(scope, element) {
this.#preFocusHistory.set(scope, element);
}
getPreFocusMemory(scope) {
return this.#preFocusHistory.get(scope);
}
clearPreFocusMemory(scope) {
this.#preFocusHistory.delete(scope);
}
}
class FocusScope {
#paused = false;
#container = null;
#manager = FocusScopeManager.getInstance();
#cleanupFns = [];
#opts;
constructor(opts) {
this.#opts = opts;
}
get paused() {
return this.#paused;
}
pause() {
this.#paused = true;
}
resume() {
this.#paused = false;
}
#cleanup() {
for (const fn of this.#cleanupFns) {
fn();
}
this.#cleanupFns = [];
}
mount(container) {
if (this.#container) {
this.unmount();
}
this.#container = container;
this.#manager.register(this);
this.#setupEventListeners();
this.#handleOpenAutoFocus();
}
unmount() {
if (!this.#container) return;
this.#cleanup();
this.#handleCloseAutoFocus();
this.#manager.unregister(this);
this.#manager.clearPreFocusMemory(this);
this.#container = null;
}
#handleOpenAutoFocus() {
if (!this.#container) return;
const event = new CustomEvent("focusScope.onOpenAutoFocus", { bubbles: false, cancelable: true });
this.#opts.onOpenAutoFocus.current(event);
if (!event.defaultPrevented) {
requestAnimationFrame(() => {
if (!this.#container) return;
const firstTabbable = this.#getFirstTabbable();
if (firstTabbable) {
firstTabbable.focus();
this.#manager.setFocusMemory(this, firstTabbable);
} else {
this.#container.focus();
}
});
}
}
#handleCloseAutoFocus() {
const event = new CustomEvent("focusScope.onCloseAutoFocus", { bubbles: false, cancelable: true });
this.#opts.onCloseAutoFocus.current?.(event);
if (!event.defaultPrevented) {
const preFocusedElement = this.#manager.getPreFocusMemory(this);
if (preFocusedElement && document.contains(preFocusedElement)) {
try {
preFocusedElement.focus();
} catch {
document.body.focus();
}
}
}
}
#setupEventListeners() {
if (!this.#container || !this.#opts.trap.current) return;
const container = this.#container;
const doc = container.ownerDocument;
const handleFocus = (e) => {
if (this.#paused || !this.#manager.isActiveScope(this)) return;
const target = e.target;
if (!target) return;
const isInside = container.contains(target);
if (isInside) {
this.#manager.setFocusMemory(this, target);
} else {
const lastFocused = this.#manager.getFocusMemory(this);
if (lastFocused && container.contains(lastFocused) && isFocusable(lastFocused)) {
e.preventDefault();
lastFocused.focus();
} else {
const firstTabbable = this.#getFirstTabbable();
const firstFocusable = this.#getAllFocusables()[0];
(firstTabbable || firstFocusable || container).focus();
}
}
};
const handleKeydown = (e) => {
if (!this.#opts.loop || this.#paused || e.key !== "Tab") return;
if (!this.#manager.isActiveScope(this)) return;
const tabbables = this.#getTabbables();
if (tabbables.length === 0) return;
const first = tabbables[0];
const last = tabbables[tabbables.length - 1];
if (!e.shiftKey && doc.activeElement === last) {
e.preventDefault();
first.focus();
} else if (e.shiftKey && doc.activeElement === first) {
e.preventDefault();
last.focus();
}
};
this.#cleanupFns.push(on(doc, "focusin", handleFocus, { capture: true }), on(container, "keydown", handleKeydown));
const observer = new MutationObserver(() => {
const lastFocused = this.#manager.getFocusMemory(this);
if (lastFocused && !container.contains(lastFocused)) {
const firstTabbable = this.#getFirstTabbable();
const firstFocusable = this.#getAllFocusables()[0];
const elementToFocus = firstTabbable || firstFocusable;
if (elementToFocus) {
elementToFocus.focus();
this.#manager.setFocusMemory(this, elementToFocus);
} else {
container.focus();
}
}
});
observer.observe(container, { childList: true, subtree: true });
this.#cleanupFns.push(() => observer.disconnect());
}
#getTabbables() {
if (!this.#container) return [];
return tabbable(this.#container, { includeContainer: false, getShadowRoot: true });
}
#getFirstTabbable() {
const tabbables = this.#getTabbables();
return tabbables[0] || null;
}
#getAllFocusables() {
if (!this.#container) return [];
return focusable(this.#container, { includeContainer: false, getShadowRoot: true });
}
static use(opts) {
let scope = null;
watch([() => opts.ref.current, () => opts.enabled.current], ([ref, enabled]) => {
if (ref && enabled) {
if (!scope) {
scope = new FocusScope(opts);
}
scope.mount(ref);
} else if (scope) {
scope.unmount();
scope = null;
}
});
return {
get props() {
return { tabindex: -1 };
}
};
}
}
function Focus_scope($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let {
enabled = false,
trapFocus = false,
loop = false,
onCloseAutoFocus = noop,
onOpenAutoFocus = noop,
focusScope,
ref
} = $$props;
const focusScopeState = FocusScope.use({
enabled: boxWith(() => enabled),
trap: boxWith(() => trapFocus),
loop,
onCloseAutoFocus: boxWith(() => onCloseAutoFocus),
onOpenAutoFocus: boxWith(() => onOpenAutoFocus),
ref
});
focusScope?.($$renderer2, { props: focusScopeState.props });
$$renderer2.push(`<!---->`);
});
}
globalThis.bitsTextSelectionLayers ??= /* @__PURE__ */ new Map();
class TextSelectionLayerState {
static create(opts) {
return new TextSelectionLayerState(opts);
}
opts;
domContext;
#unsubSelectionLock = noop;
constructor(opts) {
this.opts = opts;
this.domContext = new DOMContext(opts.ref);
let unsubEvents = noop;
watch(() => this.opts.enabled.current, (isEnabled) => {
if (isEnabled) {
globalThis.bitsTextSelectionLayers.set(this, this.opts.enabled);
unsubEvents();
unsubEvents = this.#addEventListeners();
}
return () => {
unsubEvents();
this.#resetSelectionLock();
globalThis.bitsTextSelectionLayers.delete(this);
};
});
}
#addEventListeners() {
return executeCallbacks(on(this.domContext.getDocument(), "pointerdown", this.#pointerdown), on(this.domContext.getDocument(), "pointerup", composeHandlers(this.#resetSelectionLock, this.opts.onPointerUp.current)));
}
#pointerdown = (e) => {
const node = this.opts.ref.current;
const target = e.target;
if (!isHTMLElement(node) || !isHTMLElement(target) || !this.opts.enabled.current) return;
if (!isHighestLayer(this) || !contains(node, target)) return;
this.opts.onPointerDown.current(e);
if (e.defaultPrevented) return;
this.#unsubSelectionLock = preventTextSelectionOverflow(node, this.domContext.getDocument().body);
};
#resetSelectionLock = () => {
this.#unsubSelectionLock();
this.#unsubSelectionLock = noop;
};
}
const getUserSelect = (node) => node.style.userSelect || node.style.webkitUserSelect;
function preventTextSelectionOverflow(node, body) {
const originalBodyUserSelect = getUserSelect(body);
const originalNodeUserSelect = getUserSelect(node);
setUserSelect(body, "none");
setUserSelect(node, "text");
return () => {
setUserSelect(body, originalBodyUserSelect);
setUserSelect(node, originalNodeUserSelect);
};
}
function setUserSelect(node, value) {
node.style.userSelect = value;
node.style.webkitUserSelect = value;
}
function isHighestLayer(instance) {
const layersArr = [...globalThis.bitsTextSelectionLayers];
if (!layersArr.length) return false;
const highestLayer = layersArr.at(-1);
if (!highestLayer) return false;
return highestLayer[0] === instance;
}
function Text_selection_layer($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let {
preventOverflowTextSelection = true,
onPointerDown = noop,
onPointerUp = noop,
id,
children,
enabled,
ref
} = $$props;
TextSelectionLayerState.create({
id: boxWith(() => id),
onPointerDown: boxWith(() => onPointerDown),
onPointerUp: boxWith(() => onPointerUp),
enabled: boxWith(() => enabled && preventOverflowTextSelection),
ref
});
children?.($$renderer2);
$$renderer2.push(`<!---->`);
});
}
globalThis.bitsIdCounter ??= { current: 0 };
function useId(prefix = "bits") {
globalThis.bitsIdCounter.current++;
return `${prefix}-${globalThis.bitsIdCounter.current}`;
}
class SharedState {
#factory;
#subscribers = 0;
#state;
#scope;
constructor(factory) {
this.#factory = factory;
}
#dispose() {
this.#subscribers -= 1;
if (this.#scope && this.#subscribers <= 0) {
this.#scope();
this.#state = void 0;
this.#scope = void 0;
}
}
get(...args) {
this.#subscribers += 1;
if (this.#state === void 0) {
this.#scope = () => {
};
}
return this.#state;
}
}
const lockMap = new SvelteMap();
let initialBodyStyle = null;
let cleanupTimeoutId = null;
let isInCleanupTransition = false;
const anyLocked = boxWith(() => {
for (const value of lockMap.values()) {
if (value) return true;
}
return false;
});
let cleanupScheduledAt = null;
const bodyLockStackCount = new SharedState(() => {
function resetBodyStyle() {
return;
}
function cancelPendingCleanup() {
if (cleanupTimeoutId === null) return;
window.clearTimeout(cleanupTimeoutId);
cleanupTimeoutId = null;
}
function scheduleCleanupIfNoNewLocks(delay, callback) {
cancelPendingCleanup();
isInCleanupTransition = true;
cleanupScheduledAt = Date.now();
const currentCleanupId = cleanupScheduledAt;
const cleanupFn = () => {
cleanupTimeoutId = null;
if (cleanupScheduledAt !== currentCleanupId) return;
if (!isAnyLocked(lockMap)) {
isInCleanupTransition = false;
callback();
} else {
isInCleanupTransition = false;
}
};
const actualDelay = delay === null ? 24 : delay;
cleanupTimeoutId = window.setTimeout(cleanupFn, actualDelay);
}
function ensureInitialStyleCaptured() {
if (initialBodyStyle === null && lockMap.size === 0 && !isInCleanupTransition) {
initialBodyStyle = document.body.getAttribute("style");
}
}
watch(() => anyLocked.current, () => {
if (!anyLocked.current) return;
ensureInitialStyleCaptured();
isInCleanupTransition = false;
const htmlStyle = getComputedStyle(document.documentElement);
const bodyStyle = getComputedStyle(document.body);
const hasStableGutter = htmlStyle.scrollbarGutter?.includes("stable") || bodyStyle.scrollbarGutter?.includes("stable");
const verticalScrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
const paddingRight = Number.parseInt(bodyStyle.paddingRight ?? "0", 10);
const config = {
padding: paddingRight + verticalScrollbarWidth,
margin: Number.parseInt(bodyStyle.marginRight ?? "0", 10)
};
if (verticalScrollbarWidth > 0 && !hasStableGutter) {
document.body.style.paddingRight = `${config.padding}px`;
document.body.style.marginRight = `${config.margin}px`;
document.body.style.setProperty("--scrollbar-width", `${verticalScrollbarWidth}px`);
}
document.body.style.overflow = "hidden";
if (isIOS) {
on(
document,
"touchmove",
(e) => {
if (e.target !== document.documentElement) return;
if (e.touches.length > 1) return;
e.preventDefault();
},
{ passive: false }
);
}
afterTick(() => {
document.body.style.pointerEvents = "none";
document.body.style.overflow = "hidden";
});
});
return {
get lockMap() {
return lockMap;
},
resetBodyStyle,
scheduleCleanupIfNoNewLocks,
cancelPendingCleanup,
ensureInitialStyleCaptured
};
});
class BodyScrollLock {
#id = useId();
#initialState;
#restoreScrollDelay = () => null;
#countState;
locked;
constructor(initialState, restoreScrollDelay = () => null) {
this.#initialState = initialState;
this.#restoreScrollDelay = restoreScrollDelay;
this.#countState = bodyLockStackCount.get();
if (!this.#countState) return;
this.#countState.cancelPendingCleanup();
this.#countState.ensureInitialStyleCaptured();
this.#countState.lockMap.set(this.#id, this.#initialState ?? false);
this.locked = boxWith(() => this.#countState.lockMap.get(this.#id) ?? false, (v) => this.#countState.lockMap.set(this.#id, v));
}
}
function isAnyLocked(map) {
for (const [_, value] of map) {
if (value) return true;
}
return false;
}
function Scroll_lock($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let { preventScroll = true, restoreScrollDelay = null } = $$props;
if (preventScroll) {
new BodyScrollLock(preventScroll, () => restoreScrollDelay);
}
});
}
const avatarAttrs = createBitsAttrs({ component: "avatar", parts: ["root", "image", "fallback"] });
const AvatarRootContext = new Context("Avatar.Root");
class AvatarRootState {
static create(opts) {
return AvatarRootContext.set(new AvatarRootState(opts));
}
opts;
domContext;
attachment;
constructor(opts) {
this.opts = opts;
this.domContext = new DOMContext(this.opts.ref);
this.loadImage = this.loadImage.bind(this);
this.attachment = attachRef(this.opts.ref);
}
loadImage(src, crossorigin, referrerPolicy) {
if (this.opts.loadingStatus.current === "loaded") return;
let imageTimerId;
const image = new Image();
image.src = src;
if (crossorigin !== void 0) image.crossOrigin = crossorigin;
if (referrerPolicy) image.referrerPolicy = referrerPolicy;
this.opts.loadingStatus.current = "loading";
image.onload = () => {
imageTimerId = this.domContext.setTimeout(
() => {
this.opts.loadingStatus.current = "loaded";
},
this.opts.delayMs.current
);
};
image.onerror = () => {
this.opts.loadingStatus.current = "error";
};
return () => {
if (!imageTimerId) return;
this.domContext.clearTimeout(imageTimerId);
};
}
#props = derived(() => ({
id: this.opts.id.current,
[avatarAttrs.root]: "",
"data-status": this.opts.loadingStatus.current,
...this.attachment
}));
get props() {
return this.#props();
}
set props($$value) {
return this.#props($$value);
}
}
class AvatarFallbackState {
static create(opts) {
return new AvatarFallbackState(opts, AvatarRootContext.get());
}
opts;
root;
attachment;
constructor(opts, root) {
this.opts = opts;
this.root = root;
this.attachment = attachRef(this.opts.ref);
}
#style = derived(() => this.root.opts.loadingStatus.current === "loaded" ? { display: "none" } : void 0);
get style() {
return this.#style();
}
set style($$value) {
return this.#style($$value);
}
#props = derived(() => ({
style: this.style,
"data-status": this.root.opts.loadingStatus.current,
[avatarAttrs.fallback]: "",
...this.attachment
}));
get props() {
return this.#props();
}
set props($$value) {
return this.#props($$value);
}
}
function Avatar$1($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
const uid = props_id($$renderer2);
let {
delayMs = 0,
loadingStatus = "loading",
onLoadingStatusChange,
child,
children,
id = createId(uid),
ref = null,
$$slots,
$$events,
...restProps
} = $$props;
const rootState = AvatarRootState.create({
delayMs: boxWith(() => delayMs),
loadingStatus: boxWith(() => loadingStatus, (v) => {
if (loadingStatus !== v) {
loadingStatus = v;
onLoadingStatusChange?.(v);
}
}),
id: boxWith(() => id),
ref: boxWith(() => ref, (v) => ref = v)
});
const mergedProps = mergeProps(restProps, rootState.props);
if (child) {
$$renderer2.push("<!--[-->");
child($$renderer2, { props: mergedProps });
$$renderer2.push(`<!---->`);
} else {
$$renderer2.push("<!--[!-->");
$$renderer2.push(`<div${attributes({ ...mergedProps })}>`);
children?.($$renderer2);
$$renderer2.push(`<!----></div>`);
}
$$renderer2.push(`<!--]-->`);
bind_props($$props, { loadingStatus, ref });
});
}
function Avatar_fallback$1($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
const uid = props_id($$renderer2);
let {
children,
child,
id = createId(uid),
ref = null,
$$slots,
$$events,
...restProps
} = $$props;
const fallbackState = AvatarFallbackState.create({
id: boxWith(() => id),
ref: boxWith(() => ref, (v) => ref = v)
});
const mergedProps = mergeProps(restProps, fallbackState.props);
if (child) {
$$renderer2.push("<!--[-->");
child($$renderer2, { props: mergedProps });
$$renderer2.push(`<!---->`);
} else {
$$renderer2.push("<!--[!-->");
$$renderer2.push(`<span${attributes({ ...mergedProps })}>`);
children?.($$renderer2);
$$renderer2.push(`<!----></span>`);
}
$$renderer2.push(`<!--]-->`);
bind_props($$props, { ref });
});
}
function Hidden_input($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let { value = void 0, $$slots, $$events, ...restProps } = $$props;
const mergedProps = mergeProps(restProps, {
"aria-hidden": "true",
tabindex: -1,
style: srOnlyStylesString
});
if (mergedProps.type === "checkbox") {
$$renderer2.push("<!--[-->");
$$renderer2.push(`<input${attributes({ ...mergedProps, value }, void 0, void 0, void 0, 4)}/>`);
} else {
$$renderer2.push("<!--[!-->");
$$renderer2.push(`<input${attributes({ value, ...mergedProps }, void 0, void 0, void 0, 4)}/>`);
}
$$renderer2.push(`<!--]-->`);
bind_props($$props, { value });
});
}
function get(valueOrGetValue) {
return typeof valueOrGetValue === "function" ? valueOrGetValue() : valueOrGetValue;
}
function getDPR(element) {
if (typeof window === "undefined") return 1;
const win = element.ownerDocument.defaultView || window;
return win.devicePixelRatio || 1;
}
function roundByDPR(element, value) {
const dpr = getDPR(element);
return Math.round(value * dpr) / dpr;
}
function getFloatingContentCSSVars(name) {
return {
[`--bits-${name}-content-transform-origin`]: `var(--bits-floating-transform-origin)`,
[`--bits-${name}-content-available-width`]: `var(--bits-floating-available-width)`,
[`--bits-${name}-content-available-height`]: `var(--bits-floating-available-height)`,
[`--bits-${name}-anchor-width`]: `var(--bits-floating-anchor-width)`,
[`--bits-${name}-anchor-height`]: `var(--bits-floating-anchor-height)`
};
}
function useFloating(options) {
const openOption = get(options.open) ?? true;
const middlewareOption = get(options.middleware);
const transformOption = get(options.transform) ?? true;
const placementOption = get(options.placement) ?? "bottom";
const strategyOption = get(options.strategy) ?? "absolute";
const sideOffsetOption = get(options.sideOffset) ?? 0;
const alignOffsetOption = get(options.alignOffset) ?? 0;
const reference = options.reference;
let x = 0;
let y = 0;
const floating = simpleBox(null);
let strategy = strategyOption;
let placement = placementOption;
let middlewareData = {};
let isPositioned = false;
const floatingStyles = (() => {
const xVal = floating.current ? roundByDPR(floating.current, x) : x;
const yVal = floating.current ? roundByDPR(floating.current, y) : y;
if (transformOption) {
return {
position: strategy,
left: "0",
top: "0",
transform: `translate(${xVal}px, ${yVal}px)`,
...floating.current && getDPR(floating.current) >= 1.5 && { willChange: "transform" }
};
}
return { position: strategy, left: `${xVal}px`, top: `${yVal}px` };
})();
function update() {
if (reference.current === null || floating.current === null) return;
computePosition(reference.current, floating.current, {
middleware: middlewareOption,
placement: placementOption,
strategy: strategyOption
}).then((position) => {
if (!openOption && x !== 0 && y !== 0) {
const maxExpectedOffset = Math.max(Math.abs(sideOffsetOption), Math.abs(alignOffsetOption), 15);
if (position.x <= maxExpectedOffset && position.y <= maxExpectedOffset) return;
}
x = position.x;
y = position.y;
strategy = position.strategy;
placement = position.placement;
middlewareData = position.middlewareData;
isPositioned = true;
});
}
return {
floating,
reference,
get strategy() {
return strategy;
},
get placement() {
return placement;
},
get middlewareData() {
return middlewareData;
},
get isPositioned() {
return isPositioned;
},
get floatingStyles() {
return floatingStyles;
},
get update() {
return update;
}
};
}
const OPPOSITE_SIDE = { top: "bottom", right: "left", bottom: "top", left: "right" };
const FloatingRootContext = new Context("Floating.Root");
const FloatingContentContext = new Context("Floating.Content");
const FloatingTooltipRootContext = new Context("Floating.Root");
class FloatingRootState {
static create(tooltip = false) {
return tooltip ? FloatingTooltipRootContext.set(new FloatingRootState()) : FloatingRootContext.set(new FloatingRootState());
}
anchorNode = simpleBox(null);
customAnchorNode = simpleBox(null);
triggerNode = simpleBox(null);
constructor() {
}
}
class FloatingContentState {
static create(opts, tooltip = false) {
return tooltip ? FloatingContentContext.set(new FloatingContentState(opts, FloatingTooltipRootContext.get())) : FloatingContentContext.set(new FloatingContentState(opts, FloatingRootContext.get()));
}
opts;
root;
// nodes
contentRef = simpleBox(null);
wrapperRef = simpleBox(null);
arrowRef = simpleBox(null);
contentAttachment = attachRef(this.contentRef);
wrapperAttachment = attachRef(this.wrapperRef);
arrowAttachment = attachRef(this.arrowRef);
// ids
arrowId = simpleBox(useId());
#transformedStyle = derived(() => {
if (typeof this.opts.style === "string") return cssToStyleObj(this.opts.style);
if (!this.opts.style) return {};
});
#updatePositionStrategy = void 0;
#arrowSize = new ElementSize(() => this.arrowRef.current ?? void 0);
#arrowWidth = derived(() => this.#arrowSize?.width ?? 0);
#arrowHeight = derived(() => this.#arrowSize?.height ?? 0);
#desiredPlacement = derived(() => this.opts.side?.current + (this.opts.align.current !== "center" ? `-${this.opts.align.current}` : ""));
#boundary = derived(() => Array.isArray(this.opts.collisionBoundary.current) ? this.opts.collisionBoundary.current : [this.opts.collisionBoundary.current]);
#hasExplicitBoundaries = derived(() => this.#boundary().length > 0);
get hasExplicitBoundaries() {
return this.#hasExplicitBoundaries();
}
set hasExplicitBoundaries($$value) {
return this.#hasExplicitBoundaries($$value);
}
#detectOverflowOptions = derived(() => ({
padding: this.opts.collisionPadding.current,
boundary: this.#boundary().filter(isNotNull),
altBoundary: this.hasExplicitBoundaries
}));
get detectOverflowOptions() {
return this.#detectOverflowOptions();
}
set detectOverflowOptions($$value) {
return this.#detectOverflowOptions($$value);
}
#availableWidth = void 0;
#availableHeight = void 0;
#anchorWidth = void 0;
#anchorHeight = void 0;
#middleware = derived(() => [
offset({
mainAxis: this.opts.sideOffset.current + this.#arrowHeight(),
alignmentAxis: this.opts.alignOffset.current
}),
this.opts.avoidCollisions.current && shift({
mainAxis: true,
crossAxis: false,
limiter: this.opts.sticky.current === "partial" ? limitShift() : void 0,
...this.detectOverflowOptions
}),
this.opts.avoidCollisions.current && flip({ ...this.detectOverflowOptions }),
size({
...this.detectOverflowOptions,
apply: ({ rects, availableWidth, availableHeight }) => {
const { width: anchorWidth, height: anchorHeight } = rects.reference;
this.#availableWidth = availableWidth;
this.#availableHeight = availableHeight;
this.#anchorWidth = anchorWidth;
this.#anchorHeight = anchorHeight;
}
}),
this.arrowRef.current && arrow({
element: this.arrowRef.current,
padding: this.opts.arrowPadding.current
}),
transformOrigin({
arrowWidth: this.#arrowWidth(),
arrowHeight: this.#arrowHeight()
}),
this.opts.hideWhenDetached.current && hide({ strategy: "referenceHidden", ...this.detectOverflowOptions })
].filter(Boolean));
get middleware() {
return this.#middleware();
}
set middleware($$value) {
return this.#middleware($$value);
}
floating;
#placedSide = derived(() => getSideFromPlacement(this.floating.placement));
get placedSide() {
return this.#placedSide();
}
set placedSide($$value) {
return this.#placedSide($$value);
}
#placedAlign = derived(() => getAlignFromPlacement(this.floating.placement));
get placedAlign() {
return this.#placedAlign();
}
set placedAlign($$value) {
return this.#placedAlign($$value);
}
#arrowX = derived(() => this.floating.middlewareData.arrow?.x ?? 0);
get arrowX() {
return this.#arrowX();
}
set arrowX($$value) {
return this.#arrowX($$value);
}
#arrowY = derived(() => this.floating.middlewareData.arrow?.y ?? 0);
get arrowY() {
return this.#arrowY();
}
set arrowY($$value) {
return this.#arrowY($$value);
}
#cannotCenterArrow = derived(() => this.floating.middlewareData.arrow?.centerOffset !== 0);
get cannotCenterArrow() {
return this.#cannotCenterArrow();
}
set cannotCenterArrow($$value) {
return this.#cannotCenterArrow($$value);
}
contentZIndex;
#arrowBaseSide = derived(() => OPPOSITE_SIDE[this.placedSide]);
get arrowBaseSide() {
return this.#arrowBaseSide();
}
set arrowBaseSide($$value) {
return this.#arrowBaseSide($$value);
}
#wrapperProps = derived(() => ({
id: this.opts.wrapperId.current,
"data-bits-floating-content-wrapper": "",
style: {
...this.floating.floatingStyles,
transform: this.floating.isPositioned ? this.floating.floatingStyles.transform : "translate(0, -200%)",
minWidth: "max-content",
zIndex: this.contentZIndex,
"--bits-floating-transform-origin": `${this.floating.middlewareData.transformOrigin?.x} ${this.floating.middlewareData.transformOrigin?.y}`,
"--bits-floating-available-width": `${this.#availableWidth}px`,
"--bits-floating-available-height": `${this.#availableHeight}px`,
"--bits-floating-anchor-width": `${this.#anchorWidth}px`,
"--bits-floating-anchor-height": `${this.#anchorHeight}px`,
...this.floating.middlewareData.hide?.referenceHidden && { visibility: "hidden", "pointer-events": "none" },
...this.#transformedStyle()
},
dir: this.opts.dir.current,
...this.wrapperAttachment
}));
get wrapperProps() {
return this.#wrapperProps();
}
set wrapperProps($$value) {
return this.#wrapperProps($$value);
}
#props = derived(() => ({
"data-side": this.placedSide,
"data-align": this.placedAlign,
style: styleToString({ ...this.#transformedStyle() }),
...this.contentAttachment
}));
get props() {
return this.#props();
}
set props($$value) {
return this.#props($$value);
}
#arrowStyle = derived(() => ({
position: "absolute",
left: this.arrowX ? `${this.arrowX}px` : void 0,
top: this.arrowY ? `${this.arrowY}px` : void 0,
[this.arrowBaseSide]: 0,
"transform-origin": { top: "", right: "0 0", bottom: "center 0", left: "100% 0" }[this.placedSide],
transform: {
top: "translateY(100%)",
right: "translateY(50%) rotate(90deg) translateX(-50%)",
bottom: "rotate(180deg)",
left: "translateY(50%) rotate(-90deg) translateX(50%)"
}[this.placedSide],
visibility: this.cannotCenterArrow ? "hidden" : void 0
}));
get arrowStyle() {
return this.#arrowStyle();
}
set arrowStyle($$value) {
return this.#arrowStyle($$value);
}
constructor(opts, root) {
this.opts = opts;
this.root = root;
this.#updatePositionStrategy = opts.updatePositionStrategy;
if (opts.customAnchor) {
this.root.customAnchorNode.current = opts.customAnchor.current;
}
watch(() => opts.customAnchor.current, (customAnchor) => {
this.root.customAnchorNode.current = customAnchor;
});
this.floating = useFloating({
strategy: () => this.opts.strategy.current,
placement: () => this.#desiredPlacement(),
middleware: () => this.middleware,
reference: this.root.anchorNode,
open: () => this.opts.enabled.current,
sideOffset: () => this.opts.sideOffset.current,
alignOffset: () => this.opts.alignOffset.current
});
watch(() => this.contentRef.current, (contentNode) => {
if (!contentNode || !this.opts.enabled.current) return;
const win = getWindow(contentNode);
const rafId = win.requestAnimationFrame(() => {
if (this.contentRef.current !== contentNode || !this.opts.enabled.current) return;
const zIndex = win.getComputedStyle(contentNode).zIndex;
if (zIndex !== this.contentZIndex) {
this.contentZIndex = zIndex;
}
});
return () => {
win.cancelAnimationFrame(rafId);
};
});
}
}
class FloatingAnchorState {
static create(opts, tooltip = false) {
return tooltip ? new FloatingAnchorState(opts, FloatingTooltipRootContext.get()) : new FloatingAnchorState(opts, FloatingRootContext.get());
}
opts;
root;
constructor(opts, root) {
this.opts = opts;
this.root = root;
if (opts.virtualEl && opts.virtualEl.current) {
root.triggerNode = boxFrom(opts.virtualEl.current);
} else {
root.triggerNode = opts.ref;
}
}
}
function transformOrigin(options) {
return {
name: "transformOrigin",
options,
fn(data) {
const { placement, rects, middlewareData } = data;
const cannotCenterArrow = middlewareData.arrow?.centerOffset !== 0;
const isArrowHidden = cannotCenterArrow;
const arrowWidth = isArrowHidden ? 0 : options.arrowWidth;
const arrowHeight = isArrowHidden ? 0 : options.arrowHeight;
const [placedSide, placedAlign] = getSideAndAlignFromPlacement(placement);
const noArrowAlign = { start: "0%", center: "50%", end: "100%" }[placedAlign];
const arrowXCenter = (middlewareData.arrow?.x ?? 0) + arrowWidth / 2;
const arrowYCenter = (middlewareData.arrow?.y ?? 0) + arrowHeight / 2;
let x = "";
let y = "";
if (placedSide === "bottom") {
x = isArrowHidden ? noArrowAlign : `${arrowXCenter}px`;
y = `${-arrowHeight}px`;
} else if (placedSide === "top") {
x = isArrowHidden ? noArrowAlign : `${arrowXCenter}px`;
y = `${rects.floating.height + arrowHeight}px`;
} else if (placedSide === "right") {
x = `${-arrowHeight}px`;
y = isArrowHidden ? noArrowAlign : `${arrowYCenter}px`;
} else if (placedSide === "left") {
x = `${rects.floating.width + arrowHeight}px`;
y = isArrowHidden ? noArrowAlign : `${arrowYCenter}px`;
}
return { data: { x, y } };
}
};
}
function getSideAndAlignFromPlacement(placement) {
const [side, align = "center"] = placement.split("-");
return [side, align];
}
function getSideFromPlacement(placement) {
return getSideAndAlignFromPlacement(placement)[0];
}
function getAlignFromPlacement(placement) {
return getSideAndAlignFromPlacement(placement)[1];
}
function Floating_layer($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let { children, tooltip = false } = $$props;
FloatingRootState.create(tooltip);
children?.($$renderer2);
$$renderer2.push(`<!---->`);
});
}
function Floating_layer_anchor($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let { id, children, virtualEl, ref, tooltip = false } = $$props;
FloatingAnchorState.create(
{
id: boxWith(() => id),
virtualEl: boxWith(() => virtualEl),
ref
},
tooltip
);
children?.($$renderer2);
$$renderer2.push(`<!---->`);
});
}
function Floating_layer_content($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let {
content,
side = "bottom",
sideOffset = 0,
align = "center",
alignOffset = 0,
id,
arrowPadding = 0,
avoidCollisions = true,
collisionBoundary = [],
collisionPadding = 0,
hideWhenDetached = false,
onPlaced = () => {
},
sticky = "partial",
updatePositionStrategy = "optimized",
strategy = "fixed",
dir = "ltr",
style = {},
wrapperId = useId(),
customAnchor = null,
enabled,
tooltip = false
} = $$props;
const contentState = FloatingContentState.create(
{
side: boxWith(() => side),
sideOffset: boxWith(() => sideOffset),
align: boxWith(() => align),
alignOffset: boxWith(() => alignOffset),
id: boxWith(() => id),
arrowPadding: boxWith(() => arrowPadding),
avoidCollisions: boxWith(() => avoidCollisions),
collisionBoundary: boxWith(() => collisionBoundary),
collisionPadding: boxWith(() => collisionPadding),
hideWhenDetached: boxWith(() => hideWhenDetached),
onPlaced: boxWith(() => onPlaced),
sticky: boxWith(() => sticky),
updatePositionStrategy: boxWith(() => updatePositionStrategy),
strategy: boxWith(() => strategy),
dir: boxWith(() => dir),
style: boxWith(() => style),
enabled: boxWith(() => enabled),
wrapperId: boxWith(() => wrapperId),
customAnchor: boxWith(() => customAnchor)
},
tooltip
);
const mergedProps = mergeProps(contentState.wrapperProps, { style: { pointerEvents: "auto" } });
content?.($$renderer2, { props: contentState.props, wrapperProps: mergedProps });
$$renderer2.push(`<!---->`);
});
}
function Floating_layer_content_static($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let { content } = $$props;
content?.($$renderer2, { props: {}, wrapperProps: {} });
$$renderer2.push(`<!---->`);
});
}
function Popper_content($$renderer, $$props) {
let {
content,
isStatic = false,
onPlaced,
$$slots,
$$events,
...restProps
} = $$props;
if (isStatic) {
$$renderer.push("<!--[-->");
Floating_layer_content_static($$renderer, { content });
} else {
$$renderer.push("<!--[!-->");
Floating_layer_content($$renderer, spread_props([{ content, onPlaced }, restProps]));
}
$$renderer.push(`<!--]-->`);
}
function Popper_layer_inner($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let {
popper,
onEscapeKeydown,
escapeKeydownBehavior,
preventOverflowTextSelection,
id,
onPointerDown,
onPointerUp,
side,
sideOffset,
align,
alignOffset,
arrowPadding,
avoidCollisions,
collisionBoundary,
collisionPadding,
sticky,
hideWhenDetached,
updatePositionStrategy,
strategy,
dir,
preventScroll,
wrapperId,
style,
onPlaced,
onInteractOutside,
onCloseAutoFocus,
onOpenAutoFocus,
onFocusOutside,
interactOutsideBehavior = "close",
loop,
trapFocus = true,
isValidEvent: isValidEvent2 = () => false,
customAnchor = null,
isStatic = false,
enabled,
ref,
tooltip = false,
contentPointerEvents = "auto",
$$slots,
$$events,
...restProps
} = $$props;
{
let content = function($$renderer3, { props: floatingProps, wrapperProps }) {
if (restProps.forceMount && enabled) {
$$renderer3.push("<!--[-->");
Scroll_lock($$renderer3, { preventScroll });
} else if (!restProps.forceMount) {
$$renderer3.push("<!--[1-->");
Scroll_lock($$renderer3, { preventScroll });
} else {
$$renderer3.push("<!--[!-->");
}
$$renderer3.push(`<!--]--> `);
{
let focusScope = function($$renderer4, { props: focusScopeProps }) {
Escape_layer($$renderer4, {
onEscapeKeydown,
escapeKeydownBehavior,
enabled,
ref,
children: ($$renderer5) => {
{
let children = function($$renderer6, { props: dismissibleProps }) {
Text_selection_layer($$renderer6, {
id,
preventOverflowTextSelection,
onPointerDown,
onPointerUp,
enabled,
ref,
children: ($$renderer7) => {
popper?.($$renderer7, {
props: mergeProps(restProps, floatingProps, dismissibleProps, focusScopeProps, { style: { pointerEvents: contentPointerEvents } }),
wrapperProps
});
$$renderer7.push(`<!---->`);
}
});
};
Dismissible_layer($$renderer5, {
id,
onInteractOutside,
onFocusOutside,
interactOutsideBehavior,
isValidEvent: isValidEvent2,
enabled,
ref,
children
});
}
}
});
};
Focus_scope($$renderer3, {
onOpenAutoFocus,
onCloseAutoFocus,
loop,
enabled,
trapFocus,
forceMount: restProps.forceMount,
ref,
focusScope
});
}
$$renderer3.push(`<!---->`);
};
Popper_content($$renderer2, {
isStatic,
id,
side,
sideOffset,
align,
alignOffset,
arrowPadding,
avoidCollisions,
collisionBoundary,
collisionPadding,
sticky,
hideWhenDetached,
updatePositionStrategy,
strategy,
dir,
wrapperId,
style,
onPlaced,
customAnchor,
enabled,
tooltip,
content,
$$slots: { content: true }
});
}
});
}
function Popper_layer($$renderer, $$props) {
let {
popper,
open,
onEscapeKeydown,
escapeKeydownBehavior,
preventOverflowTextSelection,
id,
onPointerDown,
onPointerUp,
side,
sideOffset,
align,
alignOffset,
arrowPadding,
avoidCollisions,
collisionBoundary,
collisionPadding,
sticky,
hideWhenDetached,
updatePositionStrategy,
strategy,
dir,
preventScroll,
wrapperId,
style,
onPlaced,
onInteractOutside,
onCloseAutoFocus,
onOpenAutoFocus,
onFocusOutside,
interactOutsideBehavior = "close",
loop,
trapFocus = true,
isValidEvent: isValidEvent2 = () => false,
customAnchor = null,
isStatic = false,
ref,
shouldRender,
$$slots,
$$events,
...restProps
} = $$props;
if (shouldRender) {
$$renderer.push("<!--[-->");
Popper_layer_inner($$renderer, spread_props([
{
popper,
onEscapeKeydown,
escapeKeydownBehavior,
preventOverflowTextSelection,
id,
onPointerDown,
onPointerUp,
side,
sideOffset,
align,
alignOffset,
arrowPadding,
avoidCollisions,
collisionBoundary,
collisionPadding,
sticky,
hideWhenDetached,
updatePositionStrategy,
strategy,
dir,
preventScroll,
wrapperId,
style,
onPlaced,
customAnchor,
isStatic,
enabled: open,
onInteractOutside,
onCloseAutoFocus,
onOpenAutoFocus,
interactOutsideBehavior,
loop,
trapFocus,
isValidEvent: isValidEvent2,
onFocusOutside,
forceMount: false,
ref
},
restProps
]));
} else {
$$renderer.push("<!--[!-->");
}
$$renderer.push(`<!--]-->`);
}
function Popper_layer_force_mount($$renderer, $$props) {
let {
popper,
onEscapeKeydown,
escapeKeydownBehavior,
preventOverflowTextSelection,
id,
onPointerDown,
onPointerUp,
side,
sideOffset,
align,
alignOffset,
arrowPadding,
avoidCollisions,
collisionBoundary,
collisionPadding,
sticky,
hideWhenDetached,
updatePositionStrategy,
strategy,
dir,
preventScroll,
wrapperId,
style,
onPlaced,
onInteractOutside,
onCloseAutoFocus,
onOpenAutoFocus,
onFocusOutside,
interactOutsideBehavior = "close",
loop,
trapFocus = true,
isValidEvent: isValidEvent2 = () => false,
customAnchor = null,
isStatic = false,
enabled,
$$slots,
$$events,
...restProps
} = $$props;
Popper_layer_inner($$renderer, spread_props([
{
popper,
onEscapeKeydown,
escapeKeydownBehavior,
preventOverflowTextSelection,
id,
onPointerDown,
onPointerUp,
side,
sideOffset,
align,
alignOffset,
arrowPadding,
avoidCollisions,
collisionBoundary,
collisionPadding,
sticky,
hideWhenDetached,
updatePositionStrategy,
strategy,
dir,
preventScroll,
wrapperId,
style,
onPlaced,
customAnchor,
isStatic,
enabled,
onInteractOutside,
onCloseAutoFocus,
onOpenAutoFocus,
interactOutsideBehavior,
loop,
trapFocus,
isValidEvent: isValidEvent2,
onFocusOutside
},
restProps,
{ forceMount: true }
]));
}
function Menu_separator($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
const uid = props_id($$renderer2);
let {
ref = null,
id = createId(uid),
child,
children,
$$slots,
$$events,
...restProps
} = $$props;
const separatorState = MenuSeparatorState.create({
id: boxWith(() => id),
ref: boxWith(() => ref, (v) => ref = v)
});
const mergedProps = mergeProps(restProps, separatorState.props);
if (child) {
$$renderer2.push("<!--[-->");
child($$renderer2, { props: mergedProps });
$$renderer2.push(`<!---->`);
} else {
$$renderer2.push("<!--[!-->");
$$renderer2.push(`<div${attributes({ ...mergedProps })}>`);
children?.($$renderer2);
$$renderer2.push(`<!----></div>`);
}
$$renderer2.push(`<!--]-->`);
bind_props($$props, { ref });
});
}
function Menu($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let {
open = false,
dir = "ltr",
onOpenChange = noop,
onOpenChangeComplete = noop,
_internal_variant: variant = "dropdown-menu",
children
} = $$props;
const root = MenuRootState.create({
variant: boxWith(() => variant),
dir: boxWith(() => dir),
onClose: () => {
open = false;
onOpenChange(false);
}
});
MenuMenuState.create(
{
open: boxWith(() => open, (v) => {
open = v;
onOpenChange(v);
}),
onOpenChangeComplete: boxWith(() => onOpenChangeComplete)
},
root
);
Floating_layer($$renderer2, {
children: ($$renderer3) => {
children?.($$renderer3);
$$renderer3.push(`<!---->`);
}
});
bind_props($$props, { open });
});
}
function Dropdown_menu_content$1($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
const uid = props_id($$renderer2);
let {
id = createId(uid),
child,
children,
ref = null,
loop = true,
onInteractOutside = noop,
onEscapeKeydown = noop,
onCloseAutoFocus = noop,
forceMount = false,
trapFocus = false,
style,
$$slots,
$$events,
...restProps
} = $$props;
const contentState = MenuContentState.create({
id: boxWith(() => id),
loop: boxWith(() => loop),
ref: boxWith(() => ref, (v) => ref = v),
onCloseAutoFocus: boxWith(() => onCloseAutoFocus)
});
const mergedProps = mergeProps(restProps, contentState.props);
function handleInteractOutside(e) {
contentState.handleInteractOutside(e);
if (e.defaultPrevented) return;
onInteractOutside(e);
if (e.defaultPrevented) return;
if (e.target && e.target instanceof Element) {
const subContentSelector = `[${contentState.parentMenu.root.getBitsAttr("sub-content")}]`;
if (e.target.closest(subContentSelector)) return;
}
contentState.parentMenu.onClose();
}
function handleEscapeKeydown(e) {
onEscapeKeydown(e);
if (e.defaultPrevented) return;
contentState.parentMenu.onClose();
}
if (forceMount) {
$$renderer2.push("<!--[-->");
{
let popper = function($$renderer3, { props, wrapperProps }) {
const finalProps = mergeProps(props, { style: getFloatingContentCSSVars("dropdown-menu") }, { style });
if (child) {
$$renderer3.push("<!--[-->");
child($$renderer3, {
props: finalProps,
wrapperProps,
...contentState.snippetProps
});
$$renderer3.push(`<!---->`);
} else {
$$renderer3.push("<!--[!-->");
$$renderer3.push(`<div${attributes({ ...wrapperProps })}><div${attributes({ ...finalProps })}>`);
children?.($$renderer3);
$$renderer3.push(`<!----></div></div>`);
}
$$renderer3.push(`<!--]-->`);
};
Popper_layer_force_mount($$renderer2, spread_props([
mergedProps,
contentState.popperProps,
{
ref: contentState.opts.ref,
enabled: contentState.parentMenu.opts.open.current,
onInteractOutside: handleInteractOutside,
onEscapeKeydown: handleEscapeKeydown,
trapFocus,
loop,
forceMount: true,
id,
shouldRender: contentState.shouldRender,
popper,
$$slots: { popper: true }
}
]));
}
} else if (!forceMount) {
$$renderer2.push("<!--[1-->");
{
let popper = function($$renderer3, { props, wrapperProps }) {
const finalProps = mergeProps(props, { style: getFloatingContentCSSVars("dropdown-menu") }, { style });
if (child) {
$$renderer3.push("<!--[-->");
child($$renderer3, {
props: finalProps,
wrapperProps,
...contentState.snippetProps
});
$$renderer3.push(`<!---->`);
} else {
$$renderer3.push("<!--[!-->");
$$renderer3.push(`<div${attributes({ ...wrapperProps })}><div${attributes({ ...finalProps })}>`);
children?.($$renderer3);
$$renderer3.push(`<!----></div></div>`);
}
$$renderer3.push(`<!--]-->`);
};
Popper_layer($$renderer2, spread_props([
mergedProps,
contentState.popperProps,
{
ref: contentState.opts.ref,
open: contentState.parentMenu.opts.open.current,
onInteractOutside: handleInteractOutside,
onEscapeKeydown: handleEscapeKeydown,
trapFocus,
loop,
forceMount: false,
id,
shouldRender: contentState.shouldRender,
popper,
$$slots: { popper: true }
}
]));
}
} else {
$$renderer2.push("<!--[!-->");
}
$$renderer2.push(`<!--]-->`);
bind_props($$props, { ref });
});
}
function Menu_trigger($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
const uid = props_id($$renderer2);
let {
id = createId(uid),
ref = null,
child,
children,
disabled = false,
type = "button",
$$slots,
$$events,
...restProps
} = $$props;
const triggerState = DropdownMenuTriggerState.create({
id: boxWith(() => id),
disabled: boxWith(() => disabled ?? false),
ref: boxWith(() => ref, (v) => ref = v)
});
const mergedProps = mergeProps(restProps, triggerState.props, { type });
Floating_layer_anchor($$renderer2, {
id,
ref: triggerState.opts.ref,
children: ($$renderer3) => {
if (child) {
$$renderer3.push("<!--[-->");
child($$renderer3, { props: mergedProps });
$$renderer3.push(`<!---->`);
} else {
$$renderer3.push("<!--[!-->");
$$renderer3.push(`<button${attributes({ ...mergedProps })}>`);
children?.($$renderer3);
$$renderer3.push(`<!----></button>`);
}
$$renderer3.push(`<!--]-->`);
}
});
bind_props($$props, { ref });
});
}
const switchAttrs = createBitsAttrs({ component: "switch", parts: ["root", "thumb"] });
const SwitchRootContext = new Context("Switch.Root");
class SwitchRootState {
static create(opts) {
return SwitchRootContext.set(new SwitchRootState(opts));
}
opts;
attachment;
constructor(opts) {
this.opts = opts;
this.attachment = attachRef(opts.ref);
this.onkeydown = this.onkeydown.bind(this);
this.onclick = this.onclick.bind(this);
}
#toggle() {
this.opts.checked.current = !this.opts.checked.current;
}
onkeydown(e) {
if (!(e.key === ENTER || e.key === SPACE) || this.opts.disabled.current) return;
e.preventDefault();
this.#toggle();
}
onclick(_) {
if (this.opts.disabled.current) return;
this.#toggle();
}
#sharedProps = derived(() => ({
"data-disabled": boolToEmptyStrOrUndef(this.opts.disabled.current),
"data-state": getDataChecked(this.opts.checked.current),
"data-required": boolToEmptyStrOrUndef(this.opts.required.current)
}));
get sharedProps() {
return this.#sharedProps();
}
set sharedProps($$value) {
return this.#sharedProps($$value);
}
#snippetProps = derived(() => ({ checked: this.opts.checked.current }));
get snippetProps() {
return this.#snippetProps();
}
set snippetProps($$value) {
return this.#snippetProps($$value);
}
#props = derived(() => ({
...this.sharedProps,
id: this.opts.id.current,
role: "switch",
disabled: boolToTrueOrUndef(this.opts.disabled.current),
"aria-checked": getAriaChecked(this.opts.checked.current),
"aria-required": boolToStr(this.opts.required.current),
[switchAttrs.root]: "",
onclick: this.onclick,
onkeydown: this.onkeydown,
...this.attachment
}));
get props() {
return this.#props();
}
set props($$value) {
return this.#props($$value);
}
}
class SwitchInputState {
static create() {
return new SwitchInputState(SwitchRootContext.get());
}
root;
#shouldRender = derived(() => this.root.opts.name.current !== void 0);
get shouldRender() {
return this.#shouldRender();
}
set shouldRender($$value) {
return this.#shouldRender($$value);
}
constructor(root) {
this.root = root;
}
#props = derived(() => ({
type: "checkbox",
name: this.root.opts.name.current,
value: this.root.opts.value.current,
checked: this.root.opts.checked.current,
disabled: this.root.opts.disabled.current,
required: this.root.opts.required.current
}));
get props() {
return this.#props();
}
set props($$value) {
return this.#props($$value);
}
}
class SwitchThumbState {
static create(opts) {
return new SwitchThumbState(opts, SwitchRootContext.get());
}
opts;
root;
attachment;
constructor(opts, root) {
this.opts = opts;
this.root = root;
this.attachment = attachRef(opts.ref);
}
#snippetProps = derived(() => ({ checked: this.root.opts.checked.current }));
get snippetProps() {
return this.#snippetProps();
}
set snippetProps($$value) {
return this.#snippetProps($$value);
}
#props = derived(() => ({
...this.root.sharedProps,
id: this.opts.id.current,
[switchAttrs.thumb]: "",
...this.attachment
}));
get props() {
return this.#props();
}
set props($$value) {
return this.#props($$value);
}
}
function Switch_input($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
const inputState = SwitchInputState.create();
if (inputState.shouldRender) {
$$renderer2.push("<!--[-->");
Hidden_input($$renderer2, spread_props([inputState.props]));
} else {
$$renderer2.push("<!--[!-->");
}
$$renderer2.push(`<!--]-->`);
});
}
function Switch$1($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
const uid = props_id($$renderer2);
let {
child,
children,
ref = null,
id = createId(uid),
disabled = false,
required = false,
checked = false,
value = "on",
name = void 0,
type = "button",
onCheckedChange = noop,
$$slots,
$$events,
...restProps
} = $$props;
const rootState = SwitchRootState.create({
checked: boxWith(() => checked, (v) => {
checked = v;
onCheckedChange?.(v);
}),
disabled: boxWith(() => disabled ?? false),
required: boxWith(() => required),
value: boxWith(() => value),
name: boxWith(() => name),
id: boxWith(() => id),
ref: boxWith(() => ref, (v) => ref = v)
});
const mergedProps = mergeProps(restProps, rootState.props, { type });
if (child) {
$$renderer2.push("<!--[-->");
child($$renderer2, { props: mergedProps, ...rootState.snippetProps });
$$renderer2.push(`<!---->`);
} else {
$$renderer2.push("<!--[!-->");
$$renderer2.push(`<button${attributes({ ...mergedProps })}>`);
children?.($$renderer2, rootState.snippetProps);
$$renderer2.push(`<!----></button>`);
}
$$renderer2.push(`<!--]--> `);
Switch_input($$renderer2);
$$renderer2.push(`<!---->`);
bind_props($$props, { ref, checked });
});
}
function Switch_thumb($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
const uid = props_id($$renderer2);
let {
child,
children,
ref = null,
id = createId(uid),
$$slots,
$$events,
...restProps
} = $$props;
const thumbState = SwitchThumbState.create({
id: boxWith(() => id),
ref: boxWith(() => ref, (v) => ref = v)
});
const mergedProps = mergeProps(restProps, thumbState.props);
if (child) {
$$renderer2.push("<!--[-->");
child($$renderer2, { props: mergedProps, ...thumbState.snippetProps });
$$renderer2.push(`<!---->`);
} else {
$$renderer2.push("<!--[!-->");
$$renderer2.push(`<span${attributes({ ...mergedProps })}>`);
children?.($$renderer2, thumbState.snippetProps);
$$renderer2.push(`<!----></span>`);
}
$$renderer2.push(`<!--]-->`);
bind_props($$props, { ref });
});
}
function Avatar($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let {
ref = null,
loadingStatus = "loading",
class: className,
$$slots,
$$events,
...restProps
} = $$props;
let $$settled = true;
let $$inner_renderer;
function $$render_inner($$renderer3) {
$$renderer3.push("<!---->");
Avatar$1?.($$renderer3, spread_props([
{
"data-slot": "avatar",
class: cn("relative flex size-8 shrink-0 overflow-hidden rounded-full", className)
},
restProps,
{
get ref() {
return ref;
},
set ref($$value) {
ref = $$value;
$$settled = false;
},
get loadingStatus() {
return loadingStatus;
},
set loadingStatus($$value) {
loadingStatus = $$value;
$$settled = false;
}
}
]));
$$renderer3.push(`<!---->`);
}
do {
$$settled = true;
$$inner_renderer = $$renderer2.copy();
$$render_inner($$inner_renderer);
} while (!$$settled);
$$renderer2.subsume($$inner_renderer);
bind_props($$props, { ref, loadingStatus });
});
}
function Avatar_fallback($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let {
ref = null,
class: className,
$$slots,
$$events,
...restProps
} = $$props;
let $$settled = true;
let $$inner_renderer;
function $$render_inner($$renderer3) {
$$renderer3.push("<!---->");
Avatar_fallback$1?.($$renderer3, spread_props([
{
"data-slot": "avatar-fallback",
class: cn("bg-muted flex size-full items-center justify-center rounded-full", className)
},
restProps,
{
get ref() {
return ref;
},
set ref($$value) {
ref = $$value;
$$settled = false;
}
}
]));
$$renderer3.push(`<!---->`);
}
do {
$$settled = true;
$$inner_renderer = $$renderer2.copy();
$$render_inner($$inner_renderer);
} while (!$$settled);
$$renderer2.subsume($$inner_renderer);
bind_props($$props, { ref });
});
}
function Dropdown_menu($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let { open = false, $$slots, $$events, ...restProps } = $$props;
let $$settled = true;
let $$inner_renderer;
function $$render_inner($$renderer3) {
$$renderer3.push("<!---->");
Menu?.($$renderer3, spread_props([
restProps,
{
get open() {
return open;
},
set open($$value) {
open = $$value;
$$settled = false;
}
}
]));
$$renderer3.push(`<!---->`);
}
do {
$$settled = true;
$$inner_renderer = $$renderer2.copy();
$$render_inner($$inner_renderer);
} while (!$$settled);
$$renderer2.subsume($$inner_renderer);
bind_props($$props, { open });
});
}
function Dropdown_menu_portal($$renderer, $$props) {
let { $$slots, $$events, ...restProps } = $$props;
$$renderer.push("<!---->");
Portal?.($$renderer, spread_props([restProps]));
$$renderer.push(`<!---->`);
}
function Dropdown_menu_content($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let {
ref = null,
sideOffset = 4,
portalProps,
class: className,
$$slots,
$$events,
...restProps
} = $$props;
let $$settled = true;
let $$inner_renderer;
function $$render_inner($$renderer3) {
Dropdown_menu_portal($$renderer3, spread_props([
portalProps,
{
children: ($$renderer4) => {
$$renderer4.push("<!---->");
Dropdown_menu_content$1?.($$renderer4, spread_props([
{
"data-slot": "dropdown-menu-content",
sideOffset,
class: cn("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-end-2 data-[side=right]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--bits-dropdown-menu-content-available-height) min-w-[8rem] origin-(--bits-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md outline-none", className)
},
restProps,
{
get ref() {
return ref;
},
set ref($$value) {
ref = $$value;
$$settled = false;
}
}
]));
$$renderer4.push(`<!---->`);
},
$$slots: { default: true }
}
]));
}
do {
$$settled = true;
$$inner_renderer = $$renderer2.copy();
$$render_inner($$inner_renderer);
} while (!$$settled);
$$renderer2.subsume($$inner_renderer);
bind_props($$props, { ref });
});
}
function Dropdown_menu_separator($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let {
ref = null,
class: className,
$$slots,
$$events,
...restProps
} = $$props;
let $$settled = true;
let $$inner_renderer;
function $$render_inner($$renderer3) {
$$renderer3.push("<!---->");
Menu_separator?.($$renderer3, spread_props([
{
"data-slot": "dropdown-menu-separator",
class: cn("bg-border -mx-1 my-1 h-px", className)
},
restProps,
{
get ref() {
return ref;
},
set ref($$value) {
ref = $$value;
$$settled = false;
}
}
]));
$$renderer3.push(`<!---->`);
}
do {
$$settled = true;
$$inner_renderer = $$renderer2.copy();
$$render_inner($$inner_renderer);
} while (!$$settled);
$$renderer2.subsume($$inner_renderer);
bind_props($$props, { ref });
});
}
function Dropdown_menu_trigger($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let { ref = null, $$slots, $$events, ...restProps } = $$props;
let $$settled = true;
let $$inner_renderer;
function $$render_inner($$renderer3) {
$$renderer3.push("<!---->");
Menu_trigger?.($$renderer3, spread_props([
{ "data-slot": "dropdown-menu-trigger" },
restProps,
{
get ref() {
return ref;
},
set ref($$value) {
ref = $$value;
$$settled = false;
}
}
]));
$$renderer3.push(`<!---->`);
}
do {
$$settled = true;
$$inner_renderer = $$renderer2.copy();
$$render_inner($$inner_renderer);
} while (!$$settled);
$$renderer2.subsume($$inner_renderer);
bind_props($$props, { ref });
});
}
function Switch($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let {
ref = null,
class: className,
checked = false,
$$slots,
$$events,
...restProps
} = $$props;
let $$settled = true;
let $$inner_renderer;
function $$render_inner($$renderer3) {
$$renderer3.push("<!---->");
Switch$1?.($$renderer3, spread_props([
{
"data-slot": "switch",
class: cn("data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 peer inline-flex h-[1.15rem] w-8 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50", className)
},
restProps,
{
get ref() {
return ref;
},
set ref($$value) {
ref = $$value;
$$settled = false;
},
get checked() {
return checked;
},
set checked($$value) {
checked = $$value;
$$settled = false;
},
children: ($$renderer4) => {
$$renderer4.push("<!---->");
Switch_thumb?.($$renderer4, {
"data-slot": "switch-thumb",
class: cn("bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block size-4 rounded-full ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0")
});
$$renderer4.push(`<!---->`);
},
$$slots: { default: true }
}
]));
$$renderer3.push(`<!---->`);
}
do {
$$settled = true;
$$inner_renderer = $$renderer2.copy();
$$render_inner($$inner_renderer);
} while (!$$settled);
$$renderer2.subsume($$inner_renderer);
bind_props($$props, { ref, checked });
});
}
function _layout($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let { data, children } = $$props;
let darkmode = false;
let onDarkmodeChange = () => {
};
$$renderer2.push(`<div class="app-shell">`);
if (data.user) {
$$renderer2.push("<!--[-->");
$$renderer2.push(`<header class="flex items-center justify-between w-full"><h1 class="text-lg font-semibold">Base</h1> `);
$$renderer2.push("<!---->");
Dropdown_menu?.($$renderer2, {
children: ($$renderer3) => {
$$renderer3.push("<!---->");
Dropdown_menu_trigger?.($$renderer3, {
class: "rounded-full border border-input bg-background hover:bg-accent",
onclick: (e) => e.preventDefault(),
children: ($$renderer4) => {
$$renderer4.push("<!---->");
Avatar?.($$renderer4, {
class: "h-8 w-8",
children: ($$renderer5) => {
$$renderer5.push("<!---->");
Avatar_fallback?.($$renderer5, {
class: "text-xs",
children: ($$renderer6) => {
$$renderer6.push(`<!---->${escape_html(data.user.name ? String(data.user.name).slice(0, 2).toUpperCase() : data.user.email ? String(data.user.email).slice(0, 2).toUpperCase() : "?")}`);
},
$$slots: { default: true }
});
$$renderer5.push(`<!---->`);
},
$$slots: { default: true }
});
$$renderer4.push(`<!---->`);
},
$$slots: { default: true }
});
$$renderer3.push(`<!----> `);
$$renderer3.push("<!---->");
Dropdown_menu_content?.($$renderer3, {
align: "end",
class: "w-48",
children: ($$renderer4) => {
$$renderer4.push(`<div class="relative flex cursor-default items-center gap-2 rounded-sm py-1.5 px-2 text-sm outline-none select-none" role="button" tabindex="0">`);
Label($$renderer4, {
for: "darkmode-switch",
class: "flex-1 cursor-pointer",
children: ($$renderer5) => {
$$renderer5.push(`<!---->Dark mode`);
},
$$slots: { default: true }
});
$$renderer4.push(`<!----> `);
Switch($$renderer4, {
id: "darkmode-switch",
checked: darkmode,
onCheckedChange: (v) => v !== void 0 && onDarkmodeChange()
});
$$renderer4.push(`<!----></div> `);
$$renderer4.push("<!---->");
Dropdown_menu_separator?.($$renderer4, {});
$$renderer4.push(`<!----> <form method="POST" action="/logout" class="contents"><button type="submit" class="relative flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50">Log out</button></form>`);
},
$$slots: { default: true }
});
$$renderer3.push(`<!---->`);
},
$$slots: { default: true }
});
$$renderer2.push(`<!----></header>`);
} else {
$$renderer2.push("<!--[!-->");
}
$$renderer2.push(`<!--]--> <main class="flex-1 flex flex-col gap-4 min-h-0">`);
children?.($$renderer2);
$$renderer2.push(`<!----></main></div>`);
});
}
export {
_layout as default
};