UNPKG

@anoki/fse-ui

Version:

FSE UI components library

529 lines (528 loc) • 14.4 kB
import { evaluate as L, getSideAxis as T, getSide as j, clamp as X, getOppositePlacement as ee, getExpandedPlacements as te, getOppositeAxisPlacements as ne, getAlignmentSides as ie, getAlignment as z, min as $, max as W, getPaddingObject as J, rectToClientRect as _, getOppositeAxis as K, getAlignmentAxis as N, sides as se, getAxisLength as Q } from "./index.es666.js"; function I(t, e, d) { let { reference: a, floating: r } = t; const n = T(e), o = N(e), m = Q(o), u = j(e), h = n === "y", c = a.x + a.width / 2 - r.width / 2, s = a.y + a.height / 2 - r.height / 2, f = a[m] / 2 - r[m] / 2; let i; switch (u) { case "top": i = { x: c, y: a.y - r.height }; break; case "bottom": i = { x: c, y: a.y + a.height }; break; case "right": i = { x: a.x + a.width, y: s }; break; case "left": i = { x: a.x - r.width, y: s }; break; default: i = { x: a.x, y: a.y }; } switch (z(e)) { case "start": i[o] -= f * (d && h ? -1 : 1); break; case "end": i[o] += f * (d && h ? -1 : 1); break; } return i; } const ce = async (t, e, d) => { const { placement: a = "bottom", strategy: r = "absolute", middleware: n = [], platform: o } = d, m = n.filter(Boolean), u = await (o.isRTL == null ? void 0 : o.isRTL(e)); let h = await o.getElementRects({ reference: t, floating: e, strategy: r }), { x: c, y: s } = I(h, a, u), f = a, i = {}, l = 0; for (let g = 0; g < m.length; g++) { const { name: x, fn: y } = m[g], { x: A, y: p, data: v, reset: w } = await y({ x: c, y: s, initialPlacement: a, placement: f, strategy: r, middlewareData: i, rects: h, platform: o, elements: { reference: t, floating: e } }); c = A ?? c, s = p ?? s, i = { ...i, [x]: { ...i[x], ...v } }, w && l <= 50 && (l++, typeof w == "object" && (w.placement && (f = w.placement), w.rects && (h = w.rects === !0 ? await o.getElementRects({ reference: t, floating: e, strategy: r }) : w.rects), { x: c, y: s } = I(h, f, u)), g = -1); } return { x: c, y: s, placement: f, strategy: r, middlewareData: i }; }; async function Y(t, e) { var d; e === void 0 && (e = {}); const { x: a, y: r, platform: n, rects: o, elements: m, strategy: u } = t, { boundary: h = "clippingAncestors", rootBoundary: c = "viewport", elementContext: s = "floating", altBoundary: f = !1, padding: i = 0 } = L(e, t), l = J(i), x = m[f ? s === "floating" ? "reference" : "floating" : s], y = _(await n.getClippingRect({ element: (d = await (n.isElement == null ? void 0 : n.isElement(x))) == null || d ? x : x.contextElement || await (n.getDocumentElement == null ? void 0 : n.getDocumentElement(m.floating)), boundary: h, rootBoundary: c, strategy: u })), A = s === "floating" ? { x: a, y: r, width: o.floating.width, height: o.floating.height } : o.reference, p = await (n.getOffsetParent == null ? void 0 : n.getOffsetParent(m.floating)), v = await (n.isElement == null ? void 0 : n.isElement(p)) ? await (n.getScale == null ? void 0 : n.getScale(p)) || { x: 1, y: 1 } : { x: 1, y: 1 }, w = _(n.convertOffsetParentRelativeRectToViewportRelativeRect ? await n.convertOffsetParentRelativeRectToViewportRelativeRect({ elements: m, rect: A, offsetParent: p, strategy: u }) : A); return { top: (y.top - w.top + l.top) / v.y, bottom: (w.bottom - y.bottom + l.bottom) / v.y, left: (y.left - w.left + l.left) / v.x, right: (w.right - y.right + l.right) / v.x }; } const le = (t) => ({ name: "arrow", options: t, async fn(e) { const { x: d, y: a, placement: r, rects: n, platform: o, elements: m, middlewareData: u } = e, { element: h, padding: c = 0 } = L(t, e) || {}; if (h == null) return {}; const s = J(c), f = { x: d, y: a }, i = N(r), l = Q(i), g = await o.getDimensions(h), x = i === "y", y = x ? "top" : "left", A = x ? "bottom" : "right", p = x ? "clientHeight" : "clientWidth", v = n.reference[l] + n.reference[i] - f[i] - n.floating[l], w = f[i] - n.reference[i], P = await (o.getOffsetParent == null ? void 0 : o.getOffsetParent(h)); let C = P ? P[p] : 0; (!C || !await (o.isElement == null ? void 0 : o.isElement(P))) && (C = m.floating[p] || n.floating[l]); const M = v / 2 - w / 2, k = C / 2 - g[l] / 2 - 1, O = $(s[y], k), H = $(s[A], k), D = O, F = C - g[l] - H, b = C / 2 - g[l] / 2 + M, B = X(D, b, F), E = !u.arrow && z(r) != null && b !== B && n.reference[l] / 2 - (b < D ? O : H) - g[l] / 2 < 0, S = E ? b < D ? b - D : b - F : 0; return { [i]: f[i] + S, data: { [i]: B, centerOffset: b - B - S, ...E && { alignmentOffset: S } }, reset: E }; } }), re = function(t) { return t === void 0 && (t = {}), { name: "flip", options: t, async fn(e) { var d, a; const { placement: r, middlewareData: n, rects: o, initialPlacement: m, platform: u, elements: h } = e, { mainAxis: c = !0, crossAxis: s = !0, fallbackPlacements: f, fallbackStrategy: i = "bestFit", fallbackAxisSideDirection: l = "none", flipAlignment: g = !0, ...x } = L(t, e); if ((d = n.arrow) != null && d.alignmentOffset) return {}; const y = j(r), A = T(m), p = j(m) === m, v = await (u.isRTL == null ? void 0 : u.isRTL(h.floating)), w = f || (p || !g ? [ee(m)] : te(m)), P = l !== "none"; !f && P && w.push(...ne(m, g, l, v)); const C = [m, ...w], M = await Y(e, x), k = []; let O = ((a = n.flip) == null ? void 0 : a.overflows) || []; if (c && k.push(M[y]), s) { const b = ie(r, o, v); k.push(M[b[0]], M[b[1]]); } if (O = [...O, { placement: r, overflows: k }], !k.every((b) => b <= 0)) { var H, D; const b = (((H = n.flip) == null ? void 0 : H.index) || 0) + 1, B = C[b]; if (B && (!(s === "alignment" ? A !== T(B) : !1) || // We leave the current main axis only if every placement on that axis // overflows the main axis. O.every((R) => T(R.placement) === A ? R.overflows[0] > 0 : !0))) return { data: { index: b, overflows: O }, reset: { placement: B } }; let E = (D = O.filter((S) => S.overflows[0] <= 0).sort((S, R) => S.overflows[1] - R.overflows[1])[0]) == null ? void 0 : D.placement; if (!E) switch (i) { case "bestFit": { var F; const S = (F = O.filter((R) => { if (P) { const V = T(R.placement); return V === A || // Create a bias to the `y` side axis due to horizontal // reading directions favoring greater width. V === "y"; } return !0; }).map((R) => [R.placement, R.overflows.filter((V) => V > 0).reduce((V, Z) => V + Z, 0)]).sort((R, V) => R[1] - V[1])[0]) == null ? void 0 : F[0]; S && (E = S); break; } case "initialPlacement": E = m; break; } if (r !== E) return { reset: { placement: E } }; } return {}; } }; }; function q(t, e) { return { top: t.top - e.height, right: t.right - e.width, bottom: t.bottom - e.height, left: t.left - e.width }; } function G(t) { return se.some((e) => t[e] >= 0); } const fe = function(t) { return t === void 0 && (t = {}), { name: "hide", options: t, async fn(e) { const { rects: d } = e, { strategy: a = "referenceHidden", ...r } = L(t, e); switch (a) { case "referenceHidden": { const n = await Y(e, { ...r, elementContext: "reference" }), o = q(n, d.reference); return { data: { referenceHiddenOffsets: o, referenceHidden: G(o) } }; } case "escaped": { const n = await Y(e, { ...r, altBoundary: !0 }), o = q(n, d.floating); return { data: { escapedOffsets: o, escaped: G(o) } }; } default: return {}; } } }; }, U = /* @__PURE__ */ new Set(["left", "top"]); async function oe(t, e) { const { placement: d, platform: a, elements: r } = t, n = await (a.isRTL == null ? void 0 : a.isRTL(r.floating)), o = j(d), m = z(d), u = T(d) === "y", h = U.has(o) ? -1 : 1, c = n && u ? -1 : 1, s = L(e, t); let { mainAxis: f, crossAxis: i, alignmentAxis: l } = typeof s == "number" ? { mainAxis: s, crossAxis: 0, alignmentAxis: null } : { mainAxis: s.mainAxis || 0, crossAxis: s.crossAxis || 0, alignmentAxis: s.alignmentAxis }; return m && typeof l == "number" && (i = m === "end" ? l * -1 : l), u ? { x: i * c, y: f * h } : { x: f * h, y: i * c }; } const me = function(t) { return t === void 0 && (t = 0), { name: "offset", options: t, async fn(e) { var d, a; const { x: r, y: n, placement: o, middlewareData: m } = e, u = await oe(e, t); return o === ((d = m.offset) == null ? void 0 : d.placement) && (a = m.arrow) != null && a.alignmentOffset ? {} : { x: r + u.x, y: n + u.y, data: { ...u, placement: o } }; } }; }, de = function(t) { return t === void 0 && (t = {}), { name: "shift", options: t, async fn(e) { const { x: d, y: a, placement: r } = e, { mainAxis: n = !0, crossAxis: o = !1, limiter: m = { fn: (x) => { let { x: y, y: A } = x; return { x: y, y: A }; } }, ...u } = L(t, e), h = { x: d, y: a }, c = await Y(e, u), s = T(j(r)), f = K(s); let i = h[f], l = h[s]; if (n) { const x = f === "y" ? "top" : "left", y = f === "y" ? "bottom" : "right", A = i + c[x], p = i - c[y]; i = X(A, i, p); } if (o) { const x = s === "y" ? "top" : "left", y = s === "y" ? "bottom" : "right", A = l + c[x], p = l - c[y]; l = X(A, l, p); } const g = m.fn({ ...e, [f]: i, [s]: l }); return { ...g, data: { x: g.x - d, y: g.y - a, enabled: { [f]: n, [s]: o } } }; } }; }, xe = function(t) { return t === void 0 && (t = {}), { options: t, fn(e) { const { x: d, y: a, placement: r, rects: n, middlewareData: o } = e, { offset: m = 0, mainAxis: u = !0, crossAxis: h = !0 } = L(t, e), c = { x: d, y: a }, s = T(r), f = K(s); let i = c[f], l = c[s]; const g = L(m, e), x = typeof g == "number" ? { mainAxis: g, crossAxis: 0 } : { mainAxis: 0, crossAxis: 0, ...g }; if (u) { const p = f === "y" ? "height" : "width", v = n.reference[f] - n.floating[p] + x.mainAxis, w = n.reference[f] + n.reference[p] - x.mainAxis; i < v ? i = v : i > w && (i = w); } if (h) { var y, A; const p = f === "y" ? "width" : "height", v = U.has(j(r)), w = n.reference[s] - n.floating[p] + (v && ((y = o.offset) == null ? void 0 : y[s]) || 0) + (v ? 0 : x.crossAxis), P = n.reference[s] + n.reference[p] + (v ? 0 : ((A = o.offset) == null ? void 0 : A[s]) || 0) - (v ? x.crossAxis : 0); l < w ? l = w : l > P && (l = P); } return { [f]: i, [s]: l }; } }; }, ge = function(t) { return t === void 0 && (t = {}), { name: "size", options: t, async fn(e) { var d, a; const { placement: r, rects: n, platform: o, elements: m } = e, { apply: u = () => { }, ...h } = L(t, e), c = await Y(e, h), s = j(r), f = z(r), i = T(r) === "y", { width: l, height: g } = n.floating; let x, y; s === "top" || s === "bottom" ? (x = s, y = f === (await (o.isRTL == null ? void 0 : o.isRTL(m.floating)) ? "start" : "end") ? "left" : "right") : (y = s, x = f === "end" ? "top" : "bottom"); const A = g - c.top - c.bottom, p = l - c.left - c.right, v = $(g - c[x], A), w = $(l - c[y], p), P = !e.middlewareData.shift; let C = v, M = w; if ((d = e.middlewareData.shift) != null && d.enabled.x && (M = p), (a = e.middlewareData.shift) != null && a.enabled.y && (C = A), P && !f) { const O = W(c.left, 0), H = W(c.right, 0), D = W(c.top, 0), F = W(c.bottom, 0); i ? M = l - 2 * (O !== 0 || H !== 0 ? O + H : W(c.left, c.right)) : C = g - 2 * (D !== 0 || F !== 0 ? D + F : W(c.top, c.bottom)); } await u({ ...e, availableWidth: M, availableHeight: C }); const k = await o.getDimensions(m.floating); return l !== k.width || g !== k.height ? { reset: { rects: !0 } } : {}; } }; }; export { le as arrow, ce as computePosition, Y as detectOverflow, re as flip, fe as hide, xe as limitShift, me as offset, _ as rectToClientRect, de as shift, ge as size }; //# sourceMappingURL=index.es665.js.map