diff --git a/.gitignore b/.gitignore
index c788e7a..8494a71 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,7 +28,7 @@ erl_crash.dump
prima-*.tar
# Ignore assets that are produced by build tools.
-/priv/static/assets/
+# /priv/static/assets/
/demo/priv/static/assets/
# Ignore digested assets cache.
diff --git a/assets/js/hooks/modal.js b/assets/js/hooks/modal.js
index 878f798..fa4896e 100644
--- a/assets/js/hooks/modal.js
+++ b/assets/js/hooks/modal.js
@@ -40,6 +40,8 @@ export default {
},
setupElements() {
+ this.autoClose = Object.hasOwn(this.el.dataset, 'primaAutoClose')
+
if (!this.ref("modal-panel")) {
this.async = true
}
@@ -126,18 +128,23 @@ export default {
}
},
- handleModalClose() {
- this.restoreBodyScroll()
- this.maybeExecJS(this.ref("modal-overlay"), "js-hide");
- this.maybeExecJS(this.ref("modal-panel"), "js-hide");
- this.maybeExecJS(this.ref("modal-loader"), "js-hide");
- if (this.async) {
- this.ref("modal-panel").dataset.primaDirty = true
+ handleModalClose(e) {
+ if (this.autoClose || !e) {
+ this.restoreBodyScroll()
+ this.maybeExecJS(this.ref("modal-overlay"), "js-hide");
+ this.maybeExecJS(this.ref("modal-panel"), "js-hide");
+ this.maybeExecJS(this.ref("modal-loader"), "js-hide");
+ if (this.async) {
+ this.ref("modal-panel").dataset.primaDirty = true
+ }
+ } else {
+ this.maybeExecJS(this.el, "js-hide");
}
},
handleOverlayHideEnd() {
this.maybeExecJS(this.el, "js-hide");
+ this.js().hide(this.el)
this.el.setAttribute('aria-hidden', 'true')
this.restoreFocusedElement()
},
diff --git a/lib/prima/dropdown.ex b/lib/prima/dropdown.ex
index 4282e53..b3001e6 100644
--- a/lib/prima/dropdown.ex
+++ b/lib/prima/dropdown.ex
@@ -130,10 +130,7 @@ defmodule Prima.Dropdown do
attr :class, :string, default: ""
attr :disabled, :boolean, default: false
attr :as, :any, default: nil
-
- # Workaround - unfortunately there seems to be no way to pass through arbitrary assigns without emitting compile warnings
- # Since dropdown items are often rendered as links, we add the <.link> attributes here as well.
- attr :rest, :global, include: ~w(navigate patch href)
+ attr :args, :map, default: %{}
slot :inner_block, required: true
@doc """
@@ -149,6 +146,7 @@ defmodule Prima.Dropdown do
* `class` - CSS classes for styling the menu item
* `disabled` - Boolean to mark the item as disabled (default: false)
* `as` - Custom function component to render instead of the default div element
+ * `args` - A map of args passed directly to the `as` function
## Examples
diff --git a/lib/prima/modal.ex b/lib/prima/modal.ex
index cf80881..a179bc8 100644
--- a/lib/prima/modal.ex
+++ b/lib/prima/modal.ex
@@ -128,6 +128,7 @@ defmodule Prima.Modal do
attr :id, :string, required: true
attr :class, :string, default: ""
attr :on_close, JS, default: %JS{}
+ attr :auto_close, :boolean, default: true
attr :show, :boolean, default: false
attr :portal, :boolean, default: true
@@ -175,7 +176,8 @@ defmodule Prima.Modal do
JS.hide()}
+ js-hide={@on_close}
+ data-prima-auto-close={@auto_close}
data-prima-show={@show}
style="display: none;"
phx-hook="Modal"
diff --git a/priv/static/assets/prima.js b/priv/static/assets/prima.js
new file mode 100644
index 0000000..fa7ffaf
--- /dev/null
+++ b/priv/static/assets/prima.js
@@ -0,0 +1,2371 @@
+var __defProp = Object.defineProperty;
+var __defProps = Object.defineProperties;
+var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
+var __getOwnPropSymbols = Object.getOwnPropertySymbols;
+var __hasOwnProp = Object.prototype.hasOwnProperty;
+var __propIsEnum = Object.prototype.propertyIsEnumerable;
+var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
+var __spreadValues = (a, b) => {
+ for (var prop in b || (b = {}))
+ if (__hasOwnProp.call(b, prop))
+ __defNormalProp(a, prop, b[prop]);
+ if (__getOwnPropSymbols)
+ for (var prop of __getOwnPropSymbols(b)) {
+ if (__propIsEnum.call(b, prop))
+ __defNormalProp(a, prop, b[prop]);
+ }
+ return a;
+};
+var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
+var __objRest = (source, exclude) => {
+ var target = {};
+ for (var prop in source)
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
+ target[prop] = source[prop];
+ if (source != null && __getOwnPropSymbols)
+ for (var prop of __getOwnPropSymbols(source)) {
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
+ target[prop] = source[prop];
+ }
+ return target;
+};
+
+// node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs
+var min = Math.min;
+var max = Math.max;
+var round = Math.round;
+var floor = Math.floor;
+var createCoords = (v) => ({
+ x: v,
+ y: v
+});
+var oppositeSideMap = {
+ left: "right",
+ right: "left",
+ bottom: "top",
+ top: "bottom"
+};
+var oppositeAlignmentMap = {
+ start: "end",
+ end: "start"
+};
+function evaluate(value, param) {
+ return typeof value === "function" ? value(param) : value;
+}
+function getSide(placement) {
+ return placement.split("-")[0];
+}
+function getAlignment(placement) {
+ return placement.split("-")[1];
+}
+function getOppositeAxis(axis) {
+ return axis === "x" ? "y" : "x";
+}
+function getAxisLength(axis) {
+ return axis === "y" ? "height" : "width";
+}
+var yAxisSides = /* @__PURE__ */ new Set(["top", "bottom"]);
+function getSideAxis(placement) {
+ return yAxisSides.has(getSide(placement)) ? "y" : "x";
+}
+function getAlignmentAxis(placement) {
+ return getOppositeAxis(getSideAxis(placement));
+}
+function getAlignmentSides(placement, rects, rtl) {
+ if (rtl === void 0) {
+ rtl = false;
+ }
+ const alignment = getAlignment(placement);
+ const alignmentAxis = getAlignmentAxis(placement);
+ const length = getAxisLength(alignmentAxis);
+ let mainAlignmentSide = alignmentAxis === "x" ? alignment === (rtl ? "end" : "start") ? "right" : "left" : alignment === "start" ? "bottom" : "top";
+ if (rects.reference[length] > rects.floating[length]) {
+ mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
+ }
+ return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];
+}
+function getExpandedPlacements(placement) {
+ const oppositePlacement = getOppositePlacement(placement);
+ return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
+}
+function getOppositeAlignmentPlacement(placement) {
+ return placement.replace(/start|end/g, (alignment) => oppositeAlignmentMap[alignment]);
+}
+var lrPlacement = ["left", "right"];
+var rlPlacement = ["right", "left"];
+var tbPlacement = ["top", "bottom"];
+var btPlacement = ["bottom", "top"];
+function getSideList(side, isStart, rtl) {
+ switch (side) {
+ case "top":
+ case "bottom":
+ if (rtl)
+ return isStart ? rlPlacement : lrPlacement;
+ return isStart ? lrPlacement : rlPlacement;
+ case "left":
+ case "right":
+ return isStart ? tbPlacement : btPlacement;
+ default:
+ return [];
+ }
+}
+function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
+ const alignment = getAlignment(placement);
+ let list = getSideList(getSide(placement), direction === "start", rtl);
+ if (alignment) {
+ list = list.map((side) => side + "-" + alignment);
+ if (flipAlignment) {
+ list = list.concat(list.map(getOppositeAlignmentPlacement));
+ }
+ }
+ return list;
+}
+function getOppositePlacement(placement) {
+ return placement.replace(/left|right|bottom|top/g, (side) => oppositeSideMap[side]);
+}
+function expandPaddingObject(padding) {
+ return __spreadValues({
+ top: 0,
+ right: 0,
+ bottom: 0,
+ left: 0
+ }, padding);
+}
+function getPaddingObject(padding) {
+ return typeof padding !== "number" ? expandPaddingObject(padding) : {
+ top: padding,
+ right: padding,
+ bottom: padding,
+ left: padding
+ };
+}
+function rectToClientRect(rect) {
+ const {
+ x,
+ y,
+ width,
+ height
+ } = rect;
+ return {
+ width,
+ height,
+ top: y,
+ left: x,
+ right: x + width,
+ bottom: y + height,
+ x,
+ y
+ };
+}
+
+// node_modules/@floating-ui/core/dist/floating-ui.core.mjs
+function computeCoordsFromPlacement(_ref, placement, rtl) {
+ let {
+ reference,
+ floating
+ } = _ref;
+ const sideAxis = getSideAxis(placement);
+ const alignmentAxis = getAlignmentAxis(placement);
+ const alignLength = getAxisLength(alignmentAxis);
+ const side = getSide(placement);
+ const isVertical = sideAxis === "y";
+ const commonX = reference.x + reference.width / 2 - floating.width / 2;
+ const commonY = reference.y + reference.height / 2 - floating.height / 2;
+ const commonAlign = reference[alignLength] / 2 - floating[alignLength] / 2;
+ let coords;
+ switch (side) {
+ case "top":
+ coords = {
+ x: commonX,
+ y: reference.y - floating.height
+ };
+ break;
+ case "bottom":
+ coords = {
+ x: commonX,
+ y: reference.y + reference.height
+ };
+ break;
+ case "right":
+ coords = {
+ x: reference.x + reference.width,
+ y: commonY
+ };
+ break;
+ case "left":
+ coords = {
+ x: reference.x - floating.width,
+ y: commonY
+ };
+ break;
+ default:
+ coords = {
+ x: reference.x,
+ y: reference.y
+ };
+ }
+ switch (getAlignment(placement)) {
+ case "start":
+ coords[alignmentAxis] -= commonAlign * (rtl && isVertical ? -1 : 1);
+ break;
+ case "end":
+ coords[alignmentAxis] += commonAlign * (rtl && isVertical ? -1 : 1);
+ break;
+ }
+ return coords;
+}
+var computePosition = async (reference, floating, config) => {
+ const {
+ placement = "bottom",
+ strategy = "absolute",
+ middleware = [],
+ platform: platform2
+ } = config;
+ const validMiddleware = middleware.filter(Boolean);
+ const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(floating));
+ let rects = await platform2.getElementRects({
+ reference,
+ floating,
+ strategy
+ });
+ let {
+ x,
+ y
+ } = computeCoordsFromPlacement(rects, placement, rtl);
+ let statefulPlacement = placement;
+ let middlewareData = {};
+ let resetCount = 0;
+ for (let i = 0; i < validMiddleware.length; i++) {
+ const {
+ name,
+ fn
+ } = validMiddleware[i];
+ const {
+ x: nextX,
+ y: nextY,
+ data,
+ reset
+ } = await fn({
+ x,
+ y,
+ initialPlacement: placement,
+ placement: statefulPlacement,
+ strategy,
+ middlewareData,
+ rects,
+ platform: platform2,
+ elements: {
+ reference,
+ floating
+ }
+ });
+ x = nextX != null ? nextX : x;
+ y = nextY != null ? nextY : y;
+ middlewareData = __spreadProps(__spreadValues({}, middlewareData), {
+ [name]: __spreadValues(__spreadValues({}, middlewareData[name]), data)
+ });
+ if (reset && resetCount <= 50) {
+ resetCount++;
+ if (typeof reset === "object") {
+ if (reset.placement) {
+ statefulPlacement = reset.placement;
+ }
+ if (reset.rects) {
+ rects = reset.rects === true ? await platform2.getElementRects({
+ reference,
+ floating,
+ strategy
+ }) : reset.rects;
+ }
+ ({
+ x,
+ y
+ } = computeCoordsFromPlacement(rects, statefulPlacement, rtl));
+ }
+ i = -1;
+ }
+ }
+ return {
+ x,
+ y,
+ placement: statefulPlacement,
+ strategy,
+ middlewareData
+ };
+};
+async function detectOverflow(state, options) {
+ var _await$platform$isEle;
+ if (options === void 0) {
+ options = {};
+ }
+ const {
+ x,
+ y,
+ platform: platform2,
+ rects,
+ elements,
+ strategy
+ } = state;
+ const {
+ boundary = "clippingAncestors",
+ rootBoundary = "viewport",
+ elementContext = "floating",
+ altBoundary = false,
+ padding = 0
+ } = evaluate(options, state);
+ const paddingObject = getPaddingObject(padding);
+ const altContext = elementContext === "floating" ? "reference" : "floating";
+ const element = elements[altBoundary ? altContext : elementContext];
+ const clippingClientRect = rectToClientRect(await platform2.getClippingRect({
+ element: ((_await$platform$isEle = await (platform2.isElement == null ? void 0 : platform2.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || await (platform2.getDocumentElement == null ? void 0 : platform2.getDocumentElement(elements.floating)),
+ boundary,
+ rootBoundary,
+ strategy
+ }));
+ const rect = elementContext === "floating" ? {
+ x,
+ y,
+ width: rects.floating.width,
+ height: rects.floating.height
+ } : rects.reference;
+ const offsetParent = await (platform2.getOffsetParent == null ? void 0 : platform2.getOffsetParent(elements.floating));
+ const offsetScale = await (platform2.isElement == null ? void 0 : platform2.isElement(offsetParent)) ? await (platform2.getScale == null ? void 0 : platform2.getScale(offsetParent)) || {
+ x: 1,
+ y: 1
+ } : {
+ x: 1,
+ y: 1
+ };
+ const elementClientRect = rectToClientRect(platform2.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform2.convertOffsetParentRelativeRectToViewportRelativeRect({
+ elements,
+ rect,
+ offsetParent,
+ strategy
+ }) : rect);
+ return {
+ top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,
+ bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,
+ left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,
+ right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
+ };
+}
+var flip = function(options) {
+ if (options === void 0) {
+ options = {};
+ }
+ return {
+ name: "flip",
+ options,
+ async fn(state) {
+ var _middlewareData$arrow, _middlewareData$flip;
+ const {
+ placement,
+ middlewareData,
+ rects,
+ initialPlacement,
+ platform: platform2,
+ elements
+ } = state;
+ const _a = evaluate(options, state), {
+ mainAxis: checkMainAxis = true,
+ crossAxis: checkCrossAxis = true,
+ fallbackPlacements: specifiedFallbackPlacements,
+ fallbackStrategy = "bestFit",
+ fallbackAxisSideDirection = "none",
+ flipAlignment = true
+ } = _a, detectOverflowOptions = __objRest(_a, [
+ "mainAxis",
+ "crossAxis",
+ "fallbackPlacements",
+ "fallbackStrategy",
+ "fallbackAxisSideDirection",
+ "flipAlignment"
+ ]);
+ if ((_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
+ return {};
+ }
+ const side = getSide(placement);
+ const initialSideAxis = getSideAxis(initialPlacement);
+ const isBasePlacement = getSide(initialPlacement) === initialPlacement;
+ const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating));
+ const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement));
+ const hasFallbackAxisSideDirection = fallbackAxisSideDirection !== "none";
+ if (!specifiedFallbackPlacements && hasFallbackAxisSideDirection) {
+ fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl));
+ }
+ const placements2 = [initialPlacement, ...fallbackPlacements];
+ const overflow = await detectOverflow(state, detectOverflowOptions);
+ const overflows = [];
+ let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];
+ if (checkMainAxis) {
+ overflows.push(overflow[side]);
+ }
+ if (checkCrossAxis) {
+ const sides2 = getAlignmentSides(placement, rects, rtl);
+ overflows.push(overflow[sides2[0]], overflow[sides2[1]]);
+ }
+ overflowsData = [...overflowsData, {
+ placement,
+ overflows
+ }];
+ if (!overflows.every((side2) => side2 <= 0)) {
+ var _middlewareData$flip2, _overflowsData$filter;
+ const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1;
+ const nextPlacement = placements2[nextIndex];
+ if (nextPlacement) {
+ const ignoreCrossAxisOverflow = checkCrossAxis === "alignment" ? initialSideAxis !== getSideAxis(nextPlacement) : false;
+ if (!ignoreCrossAxisOverflow || // We leave the current main axis only if every placement on that axis
+ // overflows the main axis.
+ overflowsData.every((d) => getSideAxis(d.placement) === initialSideAxis ? d.overflows[0] > 0 : true)) {
+ return {
+ data: {
+ index: nextIndex,
+ overflows: overflowsData
+ },
+ reset: {
+ placement: nextPlacement
+ }
+ };
+ }
+ }
+ let resetPlacement = (_overflowsData$filter = overflowsData.filter((d) => d.overflows[0] <= 0).sort((a, b) => a.overflows[1] - b.overflows[1])[0]) == null ? void 0 : _overflowsData$filter.placement;
+ if (!resetPlacement) {
+ switch (fallbackStrategy) {
+ case "bestFit": {
+ var _overflowsData$filter2;
+ const placement2 = (_overflowsData$filter2 = overflowsData.filter((d) => {
+ if (hasFallbackAxisSideDirection) {
+ const currentSideAxis = getSideAxis(d.placement);
+ return currentSideAxis === initialSideAxis || // Create a bias to the `y` side axis due to horizontal
+ // reading directions favoring greater width.
+ currentSideAxis === "y";
+ }
+ return true;
+ }).map((d) => [d.placement, d.overflows.filter((overflow2) => overflow2 > 0).reduce((acc, overflow2) => acc + overflow2, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$filter2[0];
+ if (placement2) {
+ resetPlacement = placement2;
+ }
+ break;
+ }
+ case "initialPlacement":
+ resetPlacement = initialPlacement;
+ break;
+ }
+ }
+ if (placement !== resetPlacement) {
+ return {
+ reset: {
+ placement: resetPlacement
+ }
+ };
+ }
+ }
+ return {};
+ }
+ };
+};
+var originSides = /* @__PURE__ */ new Set(["left", "top"]);
+async function convertValueToCoords(state, options) {
+ const {
+ placement,
+ platform: platform2,
+ elements
+ } = state;
+ const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating));
+ const side = getSide(placement);
+ const alignment = getAlignment(placement);
+ const isVertical = getSideAxis(placement) === "y";
+ const mainAxisMulti = originSides.has(side) ? -1 : 1;
+ const crossAxisMulti = rtl && isVertical ? -1 : 1;
+ const rawValue = evaluate(options, state);
+ let {
+ mainAxis,
+ crossAxis,
+ alignmentAxis
+ } = typeof rawValue === "number" ? {
+ mainAxis: rawValue,
+ crossAxis: 0,
+ alignmentAxis: null
+ } : {
+ mainAxis: rawValue.mainAxis || 0,
+ crossAxis: rawValue.crossAxis || 0,
+ alignmentAxis: rawValue.alignmentAxis
+ };
+ if (alignment && typeof alignmentAxis === "number") {
+ crossAxis = alignment === "end" ? alignmentAxis * -1 : alignmentAxis;
+ }
+ return isVertical ? {
+ x: crossAxis * crossAxisMulti,
+ y: mainAxis * mainAxisMulti
+ } : {
+ x: mainAxis * mainAxisMulti,
+ y: crossAxis * crossAxisMulti
+ };
+}
+var offset = function(options) {
+ if (options === void 0) {
+ options = 0;
+ }
+ return {
+ name: "offset",
+ options,
+ async fn(state) {
+ var _middlewareData$offse, _middlewareData$arrow;
+ const {
+ x,
+ y,
+ placement,
+ middlewareData
+ } = state;
+ const diffCoords = await convertValueToCoords(state, options);
+ if (placement === ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse.placement) && (_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
+ return {};
+ }
+ return {
+ x: x + diffCoords.x,
+ y: y + diffCoords.y,
+ data: __spreadProps(__spreadValues({}, diffCoords), {
+ placement
+ })
+ };
+ }
+ };
+};
+
+// node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs
+function hasWindow() {
+ return typeof window !== "undefined";
+}
+function getNodeName(node) {
+ if (isNode(node)) {
+ return (node.nodeName || "").toLowerCase();
+ }
+ return "#document";
+}
+function getWindow(node) {
+ var _node$ownerDocument;
+ return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
+}
+function getDocumentElement(node) {
+ var _ref;
+ return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
+}
+function isNode(value) {
+ if (!hasWindow()) {
+ return false;
+ }
+ return value instanceof Node || value instanceof getWindow(value).Node;
+}
+function isElement(value) {
+ if (!hasWindow()) {
+ return false;
+ }
+ return value instanceof Element || value instanceof getWindow(value).Element;
+}
+function isHTMLElement(value) {
+ if (!hasWindow()) {
+ return false;
+ }
+ return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
+}
+function isShadowRoot(value) {
+ if (!hasWindow() || typeof ShadowRoot === "undefined") {
+ return false;
+ }
+ return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
+}
+var invalidOverflowDisplayValues = /* @__PURE__ */ new Set(["inline", "contents"]);
+function isOverflowElement(element) {
+ const {
+ overflow,
+ overflowX,
+ overflowY,
+ display
+ } = getComputedStyle2(element);
+ return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !invalidOverflowDisplayValues.has(display);
+}
+var tableElements = /* @__PURE__ */ new Set(["table", "td", "th"]);
+function isTableElement(element) {
+ return tableElements.has(getNodeName(element));
+}
+var topLayerSelectors = [":popover-open", ":modal"];
+function isTopLayer(element) {
+ return topLayerSelectors.some((selector) => {
+ try {
+ return element.matches(selector);
+ } catch (_e) {
+ return false;
+ }
+ });
+}
+var transformProperties = ["transform", "translate", "scale", "rotate", "perspective"];
+var willChangeValues = ["transform", "translate", "scale", "rotate", "perspective", "filter"];
+var containValues = ["paint", "layout", "strict", "content"];
+function isContainingBlock(elementOrCss) {
+ const webkit = isWebKit();
+ const css = isElement(elementOrCss) ? getComputedStyle2(elementOrCss) : elementOrCss;
+ return transformProperties.some((value) => css[value] ? css[value] !== "none" : false) || (css.containerType ? css.containerType !== "normal" : false) || !webkit && (css.backdropFilter ? css.backdropFilter !== "none" : false) || !webkit && (css.filter ? css.filter !== "none" : false) || willChangeValues.some((value) => (css.willChange || "").includes(value)) || containValues.some((value) => (css.contain || "").includes(value));
+}
+function getContainingBlock(element) {
+ let currentNode = getParentNode(element);
+ while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
+ if (isContainingBlock(currentNode)) {
+ return currentNode;
+ } else if (isTopLayer(currentNode)) {
+ return null;
+ }
+ currentNode = getParentNode(currentNode);
+ }
+ return null;
+}
+function isWebKit() {
+ if (typeof CSS === "undefined" || !CSS.supports)
+ return false;
+ return CSS.supports("-webkit-backdrop-filter", "none");
+}
+var lastTraversableNodeNames = /* @__PURE__ */ new Set(["html", "body", "#document"]);
+function isLastTraversableNode(node) {
+ return lastTraversableNodeNames.has(getNodeName(node));
+}
+function getComputedStyle2(element) {
+ return getWindow(element).getComputedStyle(element);
+}
+function getNodeScroll(element) {
+ if (isElement(element)) {
+ return {
+ scrollLeft: element.scrollLeft,
+ scrollTop: element.scrollTop
+ };
+ }
+ return {
+ scrollLeft: element.scrollX,
+ scrollTop: element.scrollY
+ };
+}
+function getParentNode(node) {
+ if (getNodeName(node) === "html") {
+ return node;
+ }
+ const result = (
+ // Step into the shadow DOM of the parent of a slotted node.
+ node.assignedSlot || // DOM Element detected.
+ node.parentNode || // ShadowRoot detected.
+ isShadowRoot(node) && node.host || // Fallback.
+ getDocumentElement(node)
+ );
+ return isShadowRoot(result) ? result.host : result;
+}
+function getNearestOverflowAncestor(node) {
+ const parentNode = getParentNode(node);
+ if (isLastTraversableNode(parentNode)) {
+ return node.ownerDocument ? node.ownerDocument.body : node.body;
+ }
+ if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
+ return parentNode;
+ }
+ return getNearestOverflowAncestor(parentNode);
+}
+function getOverflowAncestors(node, list, traverseIframes) {
+ var _node$ownerDocument2;
+ if (list === void 0) {
+ list = [];
+ }
+ if (traverseIframes === void 0) {
+ traverseIframes = true;
+ }
+ const scrollableAncestor = getNearestOverflowAncestor(node);
+ const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
+ const win = getWindow(scrollableAncestor);
+ if (isBody) {
+ const frameElement = getFrameElement(win);
+ return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
+ }
+ return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
+}
+function getFrameElement(win) {
+ return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
+}
+
+// node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs
+function getCssDimensions(element) {
+ const css = getComputedStyle2(element);
+ let width = parseFloat(css.width) || 0;
+ let height = parseFloat(css.height) || 0;
+ const hasOffset = isHTMLElement(element);
+ const offsetWidth = hasOffset ? element.offsetWidth : width;
+ const offsetHeight = hasOffset ? element.offsetHeight : height;
+ const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;
+ if (shouldFallback) {
+ width = offsetWidth;
+ height = offsetHeight;
+ }
+ return {
+ width,
+ height,
+ $: shouldFallback
+ };
+}
+function unwrapElement(element) {
+ return !isElement(element) ? element.contextElement : element;
+}
+function getScale(element) {
+ const domElement = unwrapElement(element);
+ if (!isHTMLElement(domElement)) {
+ return createCoords(1);
+ }
+ const rect = domElement.getBoundingClientRect();
+ const {
+ width,
+ height,
+ $
+ } = getCssDimensions(domElement);
+ let x = ($ ? round(rect.width) : rect.width) / width;
+ let y = ($ ? round(rect.height) : rect.height) / height;
+ if (!x || !Number.isFinite(x)) {
+ x = 1;
+ }
+ if (!y || !Number.isFinite(y)) {
+ y = 1;
+ }
+ return {
+ x,
+ y
+ };
+}
+var noOffsets = /* @__PURE__ */ createCoords(0);
+function getVisualOffsets(element) {
+ const win = getWindow(element);
+ if (!isWebKit() || !win.visualViewport) {
+ return noOffsets;
+ }
+ return {
+ x: win.visualViewport.offsetLeft,
+ y: win.visualViewport.offsetTop
+ };
+}
+function shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) {
+ if (isFixed === void 0) {
+ isFixed = false;
+ }
+ if (!floatingOffsetParent || isFixed && floatingOffsetParent !== getWindow(element)) {
+ return false;
+ }
+ return isFixed;
+}
+function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
+ if (includeScale === void 0) {
+ includeScale = false;
+ }
+ if (isFixedStrategy === void 0) {
+ isFixedStrategy = false;
+ }
+ const clientRect = element.getBoundingClientRect();
+ const domElement = unwrapElement(element);
+ let scale = createCoords(1);
+ if (includeScale) {
+ if (offsetParent) {
+ if (isElement(offsetParent)) {
+ scale = getScale(offsetParent);
+ }
+ } else {
+ scale = getScale(element);
+ }
+ }
+ const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0);
+ let x = (clientRect.left + visualOffsets.x) / scale.x;
+ let y = (clientRect.top + visualOffsets.y) / scale.y;
+ let width = clientRect.width / scale.x;
+ let height = clientRect.height / scale.y;
+ if (domElement) {
+ const win = getWindow(domElement);
+ const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
+ let currentWin = win;
+ let currentIFrame = getFrameElement(currentWin);
+ while (currentIFrame && offsetParent && offsetWin !== currentWin) {
+ const iframeScale = getScale(currentIFrame);
+ const iframeRect = currentIFrame.getBoundingClientRect();
+ const css = getComputedStyle2(currentIFrame);
+ const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
+ const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
+ x *= iframeScale.x;
+ y *= iframeScale.y;
+ width *= iframeScale.x;
+ height *= iframeScale.y;
+ x += left;
+ y += top;
+ currentWin = getWindow(currentIFrame);
+ currentIFrame = getFrameElement(currentWin);
+ }
+ }
+ return rectToClientRect({
+ width,
+ height,
+ x,
+ y
+ });
+}
+function getWindowScrollBarX(element, rect) {
+ const leftScroll = getNodeScroll(element).scrollLeft;
+ if (!rect) {
+ return getBoundingClientRect(getDocumentElement(element)).left + leftScroll;
+ }
+ return rect.left + leftScroll;
+}
+function getHTMLOffset(documentElement, scroll) {
+ const htmlRect = documentElement.getBoundingClientRect();
+ const x = htmlRect.left + scroll.scrollLeft - getWindowScrollBarX(documentElement, htmlRect);
+ const y = htmlRect.top + scroll.scrollTop;
+ return {
+ x,
+ y
+ };
+}
+function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
+ let {
+ elements,
+ rect,
+ offsetParent,
+ strategy
+ } = _ref;
+ const isFixed = strategy === "fixed";
+ const documentElement = getDocumentElement(offsetParent);
+ const topLayer = elements ? isTopLayer(elements.floating) : false;
+ if (offsetParent === documentElement || topLayer && isFixed) {
+ return rect;
+ }
+ let scroll = {
+ scrollLeft: 0,
+ scrollTop: 0
+ };
+ let scale = createCoords(1);
+ const offsets = createCoords(0);
+ const isOffsetParentAnElement = isHTMLElement(offsetParent);
+ if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
+ if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) {
+ scroll = getNodeScroll(offsetParent);
+ }
+ if (isHTMLElement(offsetParent)) {
+ const offsetRect = getBoundingClientRect(offsetParent);
+ scale = getScale(offsetParent);
+ offsets.x = offsetRect.x + offsetParent.clientLeft;
+ offsets.y = offsetRect.y + offsetParent.clientTop;
+ }
+ }
+ const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
+ return {
+ width: rect.width * scale.x,
+ height: rect.height * scale.y,
+ x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x,
+ y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y
+ };
+}
+function getClientRects(element) {
+ return Array.from(element.getClientRects());
+}
+function getDocumentRect(element) {
+ const html = getDocumentElement(element);
+ const scroll = getNodeScroll(element);
+ const body = element.ownerDocument.body;
+ const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
+ const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
+ let x = -scroll.scrollLeft + getWindowScrollBarX(element);
+ const y = -scroll.scrollTop;
+ if (getComputedStyle2(body).direction === "rtl") {
+ x += max(html.clientWidth, body.clientWidth) - width;
+ }
+ return {
+ width,
+ height,
+ x,
+ y
+ };
+}
+var SCROLLBAR_MAX = 25;
+function getViewportRect(element, strategy) {
+ const win = getWindow(element);
+ const html = getDocumentElement(element);
+ const visualViewport = win.visualViewport;
+ let width = html.clientWidth;
+ let height = html.clientHeight;
+ let x = 0;
+ let y = 0;
+ if (visualViewport) {
+ width = visualViewport.width;
+ height = visualViewport.height;
+ const visualViewportBased = isWebKit();
+ if (!visualViewportBased || visualViewportBased && strategy === "fixed") {
+ x = visualViewport.offsetLeft;
+ y = visualViewport.offsetTop;
+ }
+ }
+ const windowScrollbarX = getWindowScrollBarX(html);
+ if (windowScrollbarX <= 0) {
+ const doc = html.ownerDocument;
+ const body = doc.body;
+ const bodyStyles = getComputedStyle(body);
+ const bodyMarginInline = doc.compatMode === "CSS1Compat" ? parseFloat(bodyStyles.marginLeft) + parseFloat(bodyStyles.marginRight) || 0 : 0;
+ const clippingStableScrollbarWidth = Math.abs(html.clientWidth - body.clientWidth - bodyMarginInline);
+ if (clippingStableScrollbarWidth <= SCROLLBAR_MAX) {
+ width -= clippingStableScrollbarWidth;
+ }
+ } else if (windowScrollbarX <= SCROLLBAR_MAX) {
+ width += windowScrollbarX;
+ }
+ return {
+ width,
+ height,
+ x,
+ y
+ };
+}
+var absoluteOrFixed = /* @__PURE__ */ new Set(["absolute", "fixed"]);
+function getInnerBoundingClientRect(element, strategy) {
+ const clientRect = getBoundingClientRect(element, true, strategy === "fixed");
+ const top = clientRect.top + element.clientTop;
+ const left = clientRect.left + element.clientLeft;
+ const scale = isHTMLElement(element) ? getScale(element) : createCoords(1);
+ const width = element.clientWidth * scale.x;
+ const height = element.clientHeight * scale.y;
+ const x = left * scale.x;
+ const y = top * scale.y;
+ return {
+ width,
+ height,
+ x,
+ y
+ };
+}
+function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
+ let rect;
+ if (clippingAncestor === "viewport") {
+ rect = getViewportRect(element, strategy);
+ } else if (clippingAncestor === "document") {
+ rect = getDocumentRect(getDocumentElement(element));
+ } else if (isElement(clippingAncestor)) {
+ rect = getInnerBoundingClientRect(clippingAncestor, strategy);
+ } else {
+ const visualOffsets = getVisualOffsets(element);
+ rect = {
+ x: clippingAncestor.x - visualOffsets.x,
+ y: clippingAncestor.y - visualOffsets.y,
+ width: clippingAncestor.width,
+ height: clippingAncestor.height
+ };
+ }
+ return rectToClientRect(rect);
+}
+function hasFixedPositionAncestor(element, stopNode) {
+ const parentNode = getParentNode(element);
+ if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) {
+ return false;
+ }
+ return getComputedStyle2(parentNode).position === "fixed" || hasFixedPositionAncestor(parentNode, stopNode);
+}
+function getClippingElementAncestors(element, cache) {
+ const cachedResult = cache.get(element);
+ if (cachedResult) {
+ return cachedResult;
+ }
+ let result = getOverflowAncestors(element, [], false).filter((el) => isElement(el) && getNodeName(el) !== "body");
+ let currentContainingBlockComputedStyle = null;
+ const elementIsFixed = getComputedStyle2(element).position === "fixed";
+ let currentNode = elementIsFixed ? getParentNode(element) : element;
+ while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
+ const computedStyle = getComputedStyle2(currentNode);
+ const currentNodeIsContaining = isContainingBlock(currentNode);
+ if (!currentNodeIsContaining && computedStyle.position === "fixed") {
+ currentContainingBlockComputedStyle = null;
+ }
+ const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === "static" && !!currentContainingBlockComputedStyle && absoluteOrFixed.has(currentContainingBlockComputedStyle.position) || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);
+ if (shouldDropCurrentNode) {
+ result = result.filter((ancestor) => ancestor !== currentNode);
+ } else {
+ currentContainingBlockComputedStyle = computedStyle;
+ }
+ currentNode = getParentNode(currentNode);
+ }
+ cache.set(element, result);
+ return result;
+}
+function getClippingRect(_ref) {
+ let {
+ element,
+ boundary,
+ rootBoundary,
+ strategy
+ } = _ref;
+ const elementClippingAncestors = boundary === "clippingAncestors" ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary);
+ const clippingAncestors = [...elementClippingAncestors, rootBoundary];
+ const firstClippingAncestor = clippingAncestors[0];
+ const clippingRect = clippingAncestors.reduce((accRect, clippingAncestor) => {
+ const rect = getClientRectFromClippingAncestor(element, clippingAncestor, strategy);
+ accRect.top = max(rect.top, accRect.top);
+ accRect.right = min(rect.right, accRect.right);
+ accRect.bottom = min(rect.bottom, accRect.bottom);
+ accRect.left = max(rect.left, accRect.left);
+ return accRect;
+ }, getClientRectFromClippingAncestor(element, firstClippingAncestor, strategy));
+ return {
+ width: clippingRect.right - clippingRect.left,
+ height: clippingRect.bottom - clippingRect.top,
+ x: clippingRect.left,
+ y: clippingRect.top
+ };
+}
+function getDimensions(element) {
+ const {
+ width,
+ height
+ } = getCssDimensions(element);
+ return {
+ width,
+ height
+ };
+}
+function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
+ const isOffsetParentAnElement = isHTMLElement(offsetParent);
+ const documentElement = getDocumentElement(offsetParent);
+ const isFixed = strategy === "fixed";
+ const rect = getBoundingClientRect(element, true, isFixed, offsetParent);
+ let scroll = {
+ scrollLeft: 0,
+ scrollTop: 0
+ };
+ const offsets = createCoords(0);
+ function setLeftRTLScrollbarOffset() {
+ offsets.x = getWindowScrollBarX(documentElement);
+ }
+ if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
+ if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) {
+ scroll = getNodeScroll(offsetParent);
+ }
+ if (isOffsetParentAnElement) {
+ const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent);
+ offsets.x = offsetRect.x + offsetParent.clientLeft;
+ offsets.y = offsetRect.y + offsetParent.clientTop;
+ } else if (documentElement) {
+ setLeftRTLScrollbarOffset();
+ }
+ }
+ if (isFixed && !isOffsetParentAnElement && documentElement) {
+ setLeftRTLScrollbarOffset();
+ }
+ const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
+ const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x;
+ const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y;
+ return {
+ x,
+ y,
+ width: rect.width,
+ height: rect.height
+ };
+}
+function isStaticPositioned(element) {
+ return getComputedStyle2(element).position === "static";
+}
+function getTrueOffsetParent(element, polyfill) {
+ if (!isHTMLElement(element) || getComputedStyle2(element).position === "fixed") {
+ return null;
+ }
+ if (polyfill) {
+ return polyfill(element);
+ }
+ let rawOffsetParent = element.offsetParent;
+ if (getDocumentElement(element) === rawOffsetParent) {
+ rawOffsetParent = rawOffsetParent.ownerDocument.body;
+ }
+ return rawOffsetParent;
+}
+function getOffsetParent(element, polyfill) {
+ const win = getWindow(element);
+ if (isTopLayer(element)) {
+ return win;
+ }
+ if (!isHTMLElement(element)) {
+ let svgOffsetParent = getParentNode(element);
+ while (svgOffsetParent && !isLastTraversableNode(svgOffsetParent)) {
+ if (isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) {
+ return svgOffsetParent;
+ }
+ svgOffsetParent = getParentNode(svgOffsetParent);
+ }
+ return win;
+ }
+ let offsetParent = getTrueOffsetParent(element, polyfill);
+ while (offsetParent && isTableElement(offsetParent) && isStaticPositioned(offsetParent)) {
+ offsetParent = getTrueOffsetParent(offsetParent, polyfill);
+ }
+ if (offsetParent && isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !isContainingBlock(offsetParent)) {
+ return win;
+ }
+ return offsetParent || getContainingBlock(element) || win;
+}
+var getElementRects = async function(data) {
+ const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
+ const getDimensionsFn = this.getDimensions;
+ const floatingDimensions = await getDimensionsFn(data.floating);
+ return {
+ reference: getRectRelativeToOffsetParent(data.reference, await getOffsetParentFn(data.floating), data.strategy),
+ floating: {
+ x: 0,
+ y: 0,
+ width: floatingDimensions.width,
+ height: floatingDimensions.height
+ }
+ };
+};
+function isRTL(element) {
+ return getComputedStyle2(element).direction === "rtl";
+}
+var platform = {
+ convertOffsetParentRelativeRectToViewportRelativeRect,
+ getDocumentElement,
+ getClippingRect,
+ getOffsetParent,
+ getElementRects,
+ getClientRects,
+ getDimensions,
+ getScale,
+ isElement,
+ isRTL
+};
+function rectsAreEqual(a, b) {
+ return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
+}
+function observeMove(element, onMove) {
+ let io = null;
+ let timeoutId;
+ const root = getDocumentElement(element);
+ function cleanup() {
+ var _io;
+ clearTimeout(timeoutId);
+ (_io = io) == null || _io.disconnect();
+ io = null;
+ }
+ function refresh(skip, threshold) {
+ if (skip === void 0) {
+ skip = false;
+ }
+ if (threshold === void 0) {
+ threshold = 1;
+ }
+ cleanup();
+ const elementRectForRootMargin = element.getBoundingClientRect();
+ const {
+ left,
+ top,
+ width,
+ height
+ } = elementRectForRootMargin;
+ if (!skip) {
+ onMove();
+ }
+ if (!width || !height) {
+ return;
+ }
+ const insetTop = floor(top);
+ const insetRight = floor(root.clientWidth - (left + width));
+ const insetBottom = floor(root.clientHeight - (top + height));
+ const insetLeft = floor(left);
+ const rootMargin = -insetTop + "px " + -insetRight + "px " + -insetBottom + "px " + -insetLeft + "px";
+ const options = {
+ rootMargin,
+ threshold: max(0, min(1, threshold)) || 1
+ };
+ let isFirstUpdate = true;
+ function handleObserve(entries) {
+ const ratio = entries[0].intersectionRatio;
+ if (ratio !== threshold) {
+ if (!isFirstUpdate) {
+ return refresh();
+ }
+ if (!ratio) {
+ timeoutId = setTimeout(() => {
+ refresh(false, 1e-7);
+ }, 1e3);
+ } else {
+ refresh(false, ratio);
+ }
+ }
+ if (ratio === 1 && !rectsAreEqual(elementRectForRootMargin, element.getBoundingClientRect())) {
+ refresh();
+ }
+ isFirstUpdate = false;
+ }
+ try {
+ io = new IntersectionObserver(handleObserve, __spreadProps(__spreadValues({}, options), {
+ // Handle