@ansh-ui/vue 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/chunk-2VSROZ2N.js +1281 -0
- package/dist/chunk-2VSROZ2N.js.map +1 -0
- package/dist/chunk-5BQEZYG6.cjs +1294 -0
- package/dist/chunk-5BQEZYG6.cjs.map +1 -0
- package/dist/chunk-6732H4BQ.cjs +28 -0
- package/dist/chunk-6732H4BQ.cjs.map +1 -0
- package/dist/chunk-6ABPGOJP.js +722 -0
- package/dist/chunk-6ABPGOJP.js.map +1 -0
- package/dist/chunk-6XJOB6LE.js +62 -0
- package/dist/chunk-6XJOB6LE.js.map +1 -0
- package/dist/chunk-774WBLDR.cjs +24 -0
- package/dist/chunk-774WBLDR.cjs.map +1 -0
- package/dist/chunk-B6OXKW5Q.js +567 -0
- package/dist/chunk-B6OXKW5Q.js.map +1 -0
- package/dist/chunk-DMPNT3MY.cjs +64 -0
- package/dist/chunk-DMPNT3MY.cjs.map +1 -0
- package/dist/chunk-EISHOEB6.cjs +158 -0
- package/dist/chunk-EISHOEB6.cjs.map +1 -0
- package/dist/chunk-EVO23GUS.js +223 -0
- package/dist/chunk-EVO23GUS.js.map +1 -0
- package/dist/chunk-FVKLCGA4.js +1035 -0
- package/dist/chunk-FVKLCGA4.js.map +1 -0
- package/dist/chunk-IOXGBPOV.cjs +3681 -0
- package/dist/chunk-IOXGBPOV.cjs.map +1 -0
- package/dist/chunk-J2LA4GRP.cjs +1051 -0
- package/dist/chunk-J2LA4GRP.cjs.map +1 -0
- package/dist/chunk-JQ4YLXXM.cjs +580 -0
- package/dist/chunk-JQ4YLXXM.cjs.map +1 -0
- package/dist/chunk-KCA7RNJ4.cjs +781 -0
- package/dist/chunk-KCA7RNJ4.cjs.map +1 -0
- package/dist/chunk-NJDDNO4C.js +23 -0
- package/dist/chunk-NJDDNO4C.js.map +1 -0
- package/dist/chunk-OAQ7MDYX.js +22 -0
- package/dist/chunk-OAQ7MDYX.js.map +1 -0
- package/dist/chunk-PP6OYURM.cjs +238 -0
- package/dist/chunk-PP6OYURM.cjs.map +1 -0
- package/dist/chunk-SHX2JGID.cjs +269 -0
- package/dist/chunk-SHX2JGID.cjs.map +1 -0
- package/dist/chunk-SOYRICHU.js +3645 -0
- package/dist/chunk-SOYRICHU.js.map +1 -0
- package/dist/chunk-T425FIC7.js +773 -0
- package/dist/chunk-T425FIC7.js.map +1 -0
- package/dist/chunk-TMG3M6TK.js +152 -0
- package/dist/chunk-TMG3M6TK.js.map +1 -0
- package/dist/chunk-XLLSS464.cjs +286 -0
- package/dist/chunk-XLLSS464.cjs.map +1 -0
- package/dist/chunk-XZ5ZFLZM.js +280 -0
- package/dist/chunk-XZ5ZFLZM.js.map +1 -0
- package/dist/chunk-Z7XOFKM4.cjs +733 -0
- package/dist/chunk-Z7XOFKM4.cjs.map +1 -0
- package/dist/chunk-ZGMXOMCB.js +266 -0
- package/dist/chunk-ZGMXOMCB.js.map +1 -0
- package/dist/data.cjs +70 -0
- package/dist/data.cjs.map +1 -0
- package/dist/data.d.cts +963 -0
- package/dist/data.d.ts +963 -0
- package/dist/data.js +5 -0
- package/dist/data.js.map +1 -0
- package/dist/form.cjs +151 -0
- package/dist/form.cjs.map +1 -0
- package/dist/form.d.cts +2639 -0
- package/dist/form.d.ts +2639 -0
- package/dist/form.js +6 -0
- package/dist/form.js.map +1 -0
- package/dist/index.cjs +1158 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +439 -0
- package/dist/index.d.ts +439 -0
- package/dist/index.js +547 -0
- package/dist/index.js.map +1 -0
- package/dist/layout.cjs +67 -0
- package/dist/layout.cjs.map +1 -0
- package/dist/layout.d.cts +729 -0
- package/dist/layout.d.ts +729 -0
- package/dist/layout.js +6 -0
- package/dist/layout.js.map +1 -0
- package/dist/motion.cjs +50 -0
- package/dist/motion.cjs.map +1 -0
- package/dist/motion.d.cts +681 -0
- package/dist/motion.d.ts +681 -0
- package/dist/motion.js +5 -0
- package/dist/motion.js.map +1 -0
- package/dist/navigation.cjs +48 -0
- package/dist/navigation.cjs.map +1 -0
- package/dist/navigation.d.cts +515 -0
- package/dist/navigation.d.ts +515 -0
- package/dist/navigation.js +7 -0
- package/dist/navigation.js.map +1 -0
- package/dist/overlay.cjs +61 -0
- package/dist/overlay.cjs.map +1 -0
- package/dist/overlay.d.cts +772 -0
- package/dist/overlay.d.ts +772 -0
- package/dist/overlay.js +8 -0
- package/dist/overlay.js.map +1 -0
- package/dist/position-Cn7qP1pn.d.cts +50 -0
- package/dist/position-Cn7qP1pn.d.ts +50 -0
- package/dist/primitives.cjs +129 -0
- package/dist/primitives.cjs.map +1 -0
- package/dist/primitives.d.cts +300 -0
- package/dist/primitives.d.ts +300 -0
- package/dist/primitives.js +8 -0
- package/dist/primitives.js.map +1 -0
- package/dist/sidebar-CQqEmpid.d.cts +124 -0
- package/dist/sidebar-CTZ-Ckko.d.ts +124 -0
- package/dist/styles.css +5593 -0
- package/dist/utils-IKPG3zcC.d.cts +46 -0
- package/dist/utils-IKPG3zcC.d.ts +46 -0
- package/package.json +91 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/primitives/use-dismiss.ts","../src/primitives/position.ts","../src/primitives/use-anchored-position.ts"],"names":["useId","watch","getCurrentScope","onScopeDispose","shallowRef","computed"],"mappings":"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","file":"chunk-XLLSS464.cjs","sourcesContent":["import { type Ref, getCurrentScope, onScopeDispose, watch } from 'vue'\nimport { type ReadonlyRef, useId } from './utils'\n\n/**\n * Dismissing layered surfaces — the Vue counterpart of `@ansh-ui/react`'s `useDismiss`.\n *\n * The hard part isn't detecting an outside click, it's nesting: a dropdown inside a dialog, with a\n * tooltip inside that. Pressing Escape must close **one** layer, the innermost. A module-level stack\n * shared across every instance (React or Vue — the runtimes don't share memory, but each framework's\n * own instances do) fixes it: surfaces push on open and pop on close, and only the top of the stack\n * responds to Escape.\n */\n\nconst layers: string[] = []\n\n/** Ids of the currently open dismissable layers, outermost first. Exposed for tests. */\nexport function getLayerStack(): readonly string[] {\n return layers\n}\n\nexport interface DismissOptions {\n /** Close on pointer press outside the surface. Default `true`. */\n outsidePress?: boolean\n /** Close on Escape. Only the topmost layer responds. Default `true`. */\n escapeKey?: boolean\n /**\n * Extra elements that count as \"inside\" — normally the trigger.\n *\n * Without this the trigger's own click closes the surface via the outside handler and then\n * immediately reopens it via its own click handler, so the surface appears not to close at all.\n */\n ignore?: Array<Ref<HTMLElement | null | undefined>>\n}\n\nexport function useDismiss(\n target: Ref<HTMLElement | null | undefined>,\n open: ReadonlyRef<boolean>,\n onDismiss: () => void,\n options: DismissOptions = {},\n): void {\n const { outsidePress = true, escapeKey = true, ignore = [] } = options\n const id = useId('layer')\n\n let detach: (() => void) | null = null\n\n const attach = (): void => {\n if (detach) return\n layers.push(id)\n\n const onKeyDown = (event: KeyboardEvent): void => {\n if (!escapeKey || event.key !== 'Escape') return\n // Innermost only.\n if (layers[layers.length - 1] !== id) return\n event.stopPropagation()\n onDismiss()\n }\n\n const onPointerDown = (event: PointerEvent | MouseEvent): void => {\n if (!outsidePress) return\n const target2 = event.target as Node | null\n if (!target2 || !target2.isConnected) return\n if (target.value?.contains(target2)) return\n for (const other of ignore) {\n if (other.value?.contains(target2)) return\n }\n onDismiss()\n }\n\n // `pointerdown` rather than `click`: a click fires after mouseup, so dragging a text selection\n // out of a popover and releasing outside would close it mid-selection.\n document.addEventListener('pointerdown', onPointerDown, true)\n document.addEventListener('keydown', onKeyDown, true)\n\n detach = () => {\n const index = layers.indexOf(id)\n if (index >= 0) layers.splice(index, 1)\n document.removeEventListener('pointerdown', onPointerDown, true)\n document.removeEventListener('keydown', onKeyDown, true)\n detach = null\n }\n }\n\n watch(open, (isOpen) => (isOpen ? attach() : detach?.()), { immediate: true })\n\n if (getCurrentScope()) onScopeDispose(() => detach?.())\n}\n\n/**\n * Lock body scroll while a modal surface is open.\n *\n * Reference-counted, so two stacked modals don't fight over the original value — the inner one\n * closing must not restore scrolling while the outer one is still open.\n *\n * The scrollbar's width is replaced with padding. Without that, hiding the scrollbar reflows the\n * whole page a few pixels wider the instant a dialog opens, which reads as a flash.\n */\nlet scrollLocks = 0\nlet restoreStyles: { overflow: string; paddingRight: string } | null = null\n\nexport function useScrollLock(active: ReadonlyRef<boolean>): void {\n let locked = false\n\n const lock = (): void => {\n if (locked || typeof document === 'undefined') return\n locked = true\n scrollLocks += 1\n if (scrollLocks === 1) {\n const { body } = document\n restoreStyles = { overflow: body.style.overflow, paddingRight: body.style.paddingRight }\n\n const gutter = window.innerWidth - document.documentElement.clientWidth\n body.style.overflow = 'hidden'\n if (gutter > 0) {\n const current = Number.parseFloat(window.getComputedStyle(body).paddingRight) || 0\n body.style.paddingRight = `${current + gutter}px`\n }\n }\n }\n\n const unlock = (): void => {\n if (!locked) return\n locked = false\n scrollLocks -= 1\n if (scrollLocks === 0 && restoreStyles) {\n document.body.style.overflow = restoreStyles.overflow\n document.body.style.paddingRight = restoreStyles.paddingRight\n restoreStyles = null\n }\n }\n\n watch(active, (isActive) => (isActive ? lock() : unlock()), { immediate: true })\n\n if (getCurrentScope()) onScopeDispose(unlock)\n}\n","/**\n * Anchored positioning.\n *\n * Popovers, tooltips, menus and comboboxes all need the same thing: place a floating box next to an\n * anchor, keep it on screen, and report where it actually ended up so the arrow can point the right\n * way. This is that calculation, as a **pure function** of rectangles — verbatim from\n * `@ansh-ui/react`'s `primitives/position.ts`.\n *\n * It is duplicated rather than imported across the workspace boundary on purpose: the function has\n * zero framework dependency, so copying costs nothing in drift (a bug fix here is a five-line diff\n * to mirror) and avoids making `@ansh-ui/vue` depend on `@ansh-ui/react` for one pure function.\n */\n\nexport type Side = 'top' | 'right' | 'bottom' | 'left'\nexport type Align = 'start' | 'center' | 'end'\nexport type Placement = Side | `${Side}-${Align}`\n\nexport interface Rect {\n x: number\n y: number\n width: number\n height: number\n}\n\nexport interface PositionOptions {\n /** Preferred placement. Default `'bottom'`. */\n placement?: Placement\n /** Gap between anchor and floating element, in px. Default `8`. */\n offset?: number\n /** Minimum distance to keep from the viewport edge, in px. Default `8`. */\n padding?: number\n /** Flip to the opposite side when there isn't room. Default `true`. */\n flip?: boolean\n /** Slide along the cross axis to stay on screen. Default `true`. */\n shift?: boolean\n /** Size of the arrow, in px, if one is being positioned. Default `0` (no arrow). */\n arrowSize?: number\n}\n\nexport interface PositionResult {\n x: number\n y: number\n placement: Placement\n side: Side\n align: Align\n arrow: { x: number; y: number } | null\n hidden: boolean\n}\n\nfunction parse(placement: Placement): { side: Side; align: Align } {\n const [side, align = 'center'] = placement.split('-') as [Side, Align?]\n return { side, align }\n}\n\nconst OPPOSITE: Record<Side, Side> = { top: 'bottom', bottom: 'top', left: 'right', right: 'left' }\n\nfunction space(anchor: Rect, viewport: Rect, padding: number) {\n return {\n top: anchor.y - viewport.y - padding,\n bottom: viewport.y + viewport.height - (anchor.y + anchor.height) - padding,\n left: anchor.x - viewport.x - padding,\n right: viewport.x + viewport.width - (anchor.x + anchor.width) - padding,\n }\n}\n\nfunction place(anchor: Rect, floating: Rect, side: Side, align: Align, offset: number) {\n let x = 0\n let y = 0\n\n switch (side) {\n case 'top':\n y = anchor.y - floating.height - offset\n break\n case 'bottom':\n y = anchor.y + anchor.height + offset\n break\n case 'left':\n x = anchor.x - floating.width - offset\n break\n case 'right':\n x = anchor.x + anchor.width + offset\n break\n }\n\n const vertical = side === 'top' || side === 'bottom'\n if (vertical) {\n if (align === 'start') x = anchor.x\n else if (align === 'end') x = anchor.x + anchor.width - floating.width\n else x = anchor.x + anchor.width / 2 - floating.width / 2\n } else {\n if (align === 'start') y = anchor.y\n else if (align === 'end') y = anchor.y + anchor.height - floating.height\n else y = anchor.y + anchor.height / 2 - floating.height / 2\n }\n\n return { x, y }\n}\n\nexport function computePosition(\n anchor: Rect,\n floating: Rect,\n viewport: Rect,\n options: PositionOptions = {},\n): PositionResult {\n const {\n placement = 'bottom',\n offset = 8,\n padding = 8,\n flip = true,\n shift = true,\n arrowSize = 0,\n } = options\n\n const requested = parse(placement)\n let side = requested.side\n const align = requested.align\n\n if (flip) {\n const available = space(anchor, viewport, padding)\n const needed = side === 'top' || side === 'bottom' ? floating.height : floating.width\n const opposite = OPPOSITE[side]\n if (available[side] < needed + offset && available[opposite] > available[side]) {\n side = opposite\n }\n }\n\n let { x, y } = place(anchor, floating, side, align, offset)\n\n const minX = viewport.x + padding\n const maxX = viewport.x + viewport.width - floating.width - padding\n const minY = viewport.y + padding\n const maxY = viewport.y + viewport.height - floating.height - padding\n\n if (shift) {\n if (side === 'top' || side === 'bottom') {\n x = maxX < minX ? minX : Math.min(Math.max(x, minX), maxX)\n } else {\n y = maxY < minY ? minY : Math.min(Math.max(y, minY), maxY)\n }\n }\n\n let arrow: { x: number; y: number } | null = null\n if (arrowSize > 0) {\n const half = arrowSize / 2\n const inset = arrowSize + 4\n if (side === 'top' || side === 'bottom') {\n const centre = anchor.x + anchor.width / 2 - x - half\n const limit = Math.max(inset, floating.width - inset - arrowSize)\n arrow = {\n x: Math.min(Math.max(centre, inset), limit),\n y: side === 'top' ? floating.height : -arrowSize,\n }\n } else {\n const centre = anchor.y + anchor.height / 2 - y - half\n const limit = Math.max(inset, floating.height - inset - arrowSize)\n arrow = {\n x: side === 'left' ? floating.width : -arrowSize,\n y: Math.min(Math.max(centre, inset), limit),\n }\n }\n }\n\n const hidden =\n anchor.y + anchor.height < viewport.y ||\n anchor.y > viewport.y + viewport.height ||\n anchor.x + anchor.width < viewport.x ||\n anchor.x > viewport.x + viewport.width\n\n return {\n x: Math.round(x),\n y: Math.round(y),\n placement: align === 'center' ? side : (`${side}-${align}` as Placement),\n side,\n align,\n arrow,\n hidden,\n }\n}\n","import {\n type ComputedRef,\n type Ref,\n computed,\n getCurrentScope,\n onScopeDispose,\n shallowRef,\n watch,\n} from 'vue'\nimport { type PositionOptions, type PositionResult, computePosition } from './position'\nimport { type ReadonlyRef } from './utils'\n\nexport interface AnchoredPositionOptions extends PositionOptions {\n /** Set the floating element's width to the anchor's — what a combobox listbox wants. */\n matchWidth?: boolean\n}\n\nexport interface AnchoredPosition {\n style: Record<string, string>\n arrowStyle: Record<string, string> | undefined\n placement: PositionResult['placement']\n side: PositionResult['side']\n}\n\nconst HIDDEN = {\n position: 'fixed',\n top: '0px',\n left: '0px',\n // Rendered off-screen rather than `display: none` for the first frame, so the element has real\n // dimensions to measure. Measuring a `display: none` element returns a zero rect, which would\n // place the surface at the anchor's corner for one frame — a visible jump on every open.\n transform: 'translate3d(0, -200vh, 0)',\n pointerEvents: 'none',\n} as const\n\n/**\n * Keep a floating element positioned against an anchor — the Vue counterpart of `@ansh-ui/react`'s\n * `useAnchoredPosition`.\n *\n * Recomputes on scroll (capture phase, so nested scroll containers are caught), on viewport resize,\n * and whenever either element changes size. It deliberately does **not** poll on every frame: that\n * costs a forced layout per frame for a value that changes only on discrete events.\n *\n * Bound to `open` rather than a separate `enabled` flag — every consumer in this package positions\n * only while its surface is open, so a second flag would be unused surface area.\n */\nexport function useAnchoredPosition(\n anchorRef: Ref<HTMLElement | null | undefined>,\n floatingRef: Ref<HTMLElement | null | undefined>,\n open: ReadonlyRef<boolean>,\n options: AnchoredPositionOptions = {},\n): { position: ComputedRef<AnchoredPosition>; update: () => void } {\n const {\n matchWidth = false,\n placement = 'bottom',\n offset = 8,\n padding = 8,\n flip = true,\n shift = true,\n arrowSize = 0,\n } = options\n\n const result = shallowRef<PositionResult | null>(null)\n const anchorWidth = shallowRef<number | null>(null)\n\n function update(): void {\n const anchor = anchorRef.value\n const floating = floatingRef.value\n if (!anchor || !floating) return\n\n const anchorRect = anchor.getBoundingClientRect()\n const floatingRect = floating.getBoundingClientRect()\n\n // jsdom reports every rect as zero. Positioning against a zero-size floating box would place it\n // at the anchor's corner, so bail and leave the off-screen style in place; tests assert on\n // `computePosition` directly, where the geometry is real.\n if (floatingRect.width === 0 && floatingRect.height === 0) return\n\n anchorWidth.value = matchWidth ? anchorRect.width : null\n result.value = computePosition(\n anchorRect,\n floatingRect,\n { x: 0, y: 0, width: window.innerWidth, height: window.innerHeight },\n { placement, offset, padding, flip, shift, arrowSize },\n )\n }\n\n let cleanup: (() => void) | null = null\n\n watch(\n open,\n (isOpen) => {\n cleanup?.()\n cleanup = null\n\n if (!isOpen) {\n result.value = null\n return\n }\n\n update()\n\n // Capture phase catches scrolling in any ancestor container, not just the document.\n const onScroll = (): void => update()\n window.addEventListener('scroll', onScroll, { capture: true, passive: true })\n window.addEventListener('resize', onScroll, { passive: true })\n\n let observer: ResizeObserver | undefined\n if (typeof ResizeObserver !== 'undefined') {\n observer = new ResizeObserver(() => update())\n if (anchorRef.value) observer.observe(anchorRef.value)\n if (floatingRef.value) observer.observe(floatingRef.value)\n }\n\n cleanup = () => {\n window.removeEventListener('scroll', onScroll, { capture: true })\n window.removeEventListener('resize', onScroll)\n observer?.disconnect()\n }\n },\n { immediate: true, flush: 'post' },\n )\n\n if (getCurrentScope()) onScopeDispose(() => cleanup?.())\n\n const position = computed<AnchoredPosition>(() => {\n const r = result.value\n if (!r) {\n return {\n style:\n matchWidth && anchorWidth.value !== null\n ? { ...HIDDEN, width: `${anchorWidth.value}px` }\n : { ...HIDDEN },\n arrowStyle: undefined,\n placement,\n side: placement.split('-')[0] as PositionResult['side'],\n }\n }\n\n return {\n style: {\n position: 'fixed',\n top: '0px',\n left: '0px',\n // `transform` rather than `top`/`left`: it is composited, so repositioning during scroll\n // does not invalidate layout for the rest of the page.\n transform: `translate3d(${r.x}px, ${r.y}px, 0)`,\n ...(r.hidden ? { visibility: 'hidden', pointerEvents: 'none' } : null),\n ...(anchorWidth.value !== null ? { width: `${anchorWidth.value}px` } : null),\n },\n arrowStyle: r.arrow\n ? { position: 'absolute', left: `${r.arrow.x}px`, top: `${r.arrow.y}px` }\n : undefined,\n placement: r.placement,\n side: r.side,\n }\n })\n\n return { position, update }\n}\n"]}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { useId } from './chunk-NJDDNO4C.js';
|
|
2
|
+
import { watch, getCurrentScope, onScopeDispose, shallowRef, computed } from 'vue';
|
|
3
|
+
|
|
4
|
+
var layers = [];
|
|
5
|
+
function getLayerStack() {
|
|
6
|
+
return layers;
|
|
7
|
+
}
|
|
8
|
+
function useDismiss(target, open, onDismiss, options = {}) {
|
|
9
|
+
const { outsidePress = true, escapeKey = true, ignore = [] } = options;
|
|
10
|
+
const id = useId("layer");
|
|
11
|
+
let detach = null;
|
|
12
|
+
const attach = () => {
|
|
13
|
+
if (detach) return;
|
|
14
|
+
layers.push(id);
|
|
15
|
+
const onKeyDown = (event) => {
|
|
16
|
+
if (!escapeKey || event.key !== "Escape") return;
|
|
17
|
+
if (layers[layers.length - 1] !== id) return;
|
|
18
|
+
event.stopPropagation();
|
|
19
|
+
onDismiss();
|
|
20
|
+
};
|
|
21
|
+
const onPointerDown = (event) => {
|
|
22
|
+
if (!outsidePress) return;
|
|
23
|
+
const target2 = event.target;
|
|
24
|
+
if (!target2 || !target2.isConnected) return;
|
|
25
|
+
if (target.value?.contains(target2)) return;
|
|
26
|
+
for (const other of ignore) {
|
|
27
|
+
if (other.value?.contains(target2)) return;
|
|
28
|
+
}
|
|
29
|
+
onDismiss();
|
|
30
|
+
};
|
|
31
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
32
|
+
document.addEventListener("keydown", onKeyDown, true);
|
|
33
|
+
detach = () => {
|
|
34
|
+
const index = layers.indexOf(id);
|
|
35
|
+
if (index >= 0) layers.splice(index, 1);
|
|
36
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
37
|
+
document.removeEventListener("keydown", onKeyDown, true);
|
|
38
|
+
detach = null;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
watch(open, (isOpen) => isOpen ? attach() : detach?.(), { immediate: true });
|
|
42
|
+
if (getCurrentScope()) onScopeDispose(() => detach?.());
|
|
43
|
+
}
|
|
44
|
+
var scrollLocks = 0;
|
|
45
|
+
var restoreStyles = null;
|
|
46
|
+
function useScrollLock(active) {
|
|
47
|
+
let locked = false;
|
|
48
|
+
const lock = () => {
|
|
49
|
+
if (locked || typeof document === "undefined") return;
|
|
50
|
+
locked = true;
|
|
51
|
+
scrollLocks += 1;
|
|
52
|
+
if (scrollLocks === 1) {
|
|
53
|
+
const { body } = document;
|
|
54
|
+
restoreStyles = { overflow: body.style.overflow, paddingRight: body.style.paddingRight };
|
|
55
|
+
const gutter = window.innerWidth - document.documentElement.clientWidth;
|
|
56
|
+
body.style.overflow = "hidden";
|
|
57
|
+
if (gutter > 0) {
|
|
58
|
+
const current = Number.parseFloat(window.getComputedStyle(body).paddingRight) || 0;
|
|
59
|
+
body.style.paddingRight = `${current + gutter}px`;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const unlock = () => {
|
|
64
|
+
if (!locked) return;
|
|
65
|
+
locked = false;
|
|
66
|
+
scrollLocks -= 1;
|
|
67
|
+
if (scrollLocks === 0 && restoreStyles) {
|
|
68
|
+
document.body.style.overflow = restoreStyles.overflow;
|
|
69
|
+
document.body.style.paddingRight = restoreStyles.paddingRight;
|
|
70
|
+
restoreStyles = null;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
watch(active, (isActive) => isActive ? lock() : unlock(), { immediate: true });
|
|
74
|
+
if (getCurrentScope()) onScopeDispose(unlock);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// src/primitives/position.ts
|
|
78
|
+
function parse(placement) {
|
|
79
|
+
const [side, align = "center"] = placement.split("-");
|
|
80
|
+
return { side, align };
|
|
81
|
+
}
|
|
82
|
+
var OPPOSITE = { top: "bottom", bottom: "top", left: "right", right: "left" };
|
|
83
|
+
function space(anchor, viewport, padding) {
|
|
84
|
+
return {
|
|
85
|
+
top: anchor.y - viewport.y - padding,
|
|
86
|
+
bottom: viewport.y + viewport.height - (anchor.y + anchor.height) - padding,
|
|
87
|
+
left: anchor.x - viewport.x - padding,
|
|
88
|
+
right: viewport.x + viewport.width - (anchor.x + anchor.width) - padding
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function place(anchor, floating, side, align, offset) {
|
|
92
|
+
let x = 0;
|
|
93
|
+
let y = 0;
|
|
94
|
+
switch (side) {
|
|
95
|
+
case "top":
|
|
96
|
+
y = anchor.y - floating.height - offset;
|
|
97
|
+
break;
|
|
98
|
+
case "bottom":
|
|
99
|
+
y = anchor.y + anchor.height + offset;
|
|
100
|
+
break;
|
|
101
|
+
case "left":
|
|
102
|
+
x = anchor.x - floating.width - offset;
|
|
103
|
+
break;
|
|
104
|
+
case "right":
|
|
105
|
+
x = anchor.x + anchor.width + offset;
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
const vertical = side === "top" || side === "bottom";
|
|
109
|
+
if (vertical) {
|
|
110
|
+
if (align === "start") x = anchor.x;
|
|
111
|
+
else if (align === "end") x = anchor.x + anchor.width - floating.width;
|
|
112
|
+
else x = anchor.x + anchor.width / 2 - floating.width / 2;
|
|
113
|
+
} else {
|
|
114
|
+
if (align === "start") y = anchor.y;
|
|
115
|
+
else if (align === "end") y = anchor.y + anchor.height - floating.height;
|
|
116
|
+
else y = anchor.y + anchor.height / 2 - floating.height / 2;
|
|
117
|
+
}
|
|
118
|
+
return { x, y };
|
|
119
|
+
}
|
|
120
|
+
function computePosition(anchor, floating, viewport, options = {}) {
|
|
121
|
+
const {
|
|
122
|
+
placement = "bottom",
|
|
123
|
+
offset = 8,
|
|
124
|
+
padding = 8,
|
|
125
|
+
flip = true,
|
|
126
|
+
shift = true,
|
|
127
|
+
arrowSize = 0
|
|
128
|
+
} = options;
|
|
129
|
+
const requested = parse(placement);
|
|
130
|
+
let side = requested.side;
|
|
131
|
+
const align = requested.align;
|
|
132
|
+
if (flip) {
|
|
133
|
+
const available = space(anchor, viewport, padding);
|
|
134
|
+
const needed = side === "top" || side === "bottom" ? floating.height : floating.width;
|
|
135
|
+
const opposite = OPPOSITE[side];
|
|
136
|
+
if (available[side] < needed + offset && available[opposite] > available[side]) {
|
|
137
|
+
side = opposite;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
let { x, y } = place(anchor, floating, side, align, offset);
|
|
141
|
+
const minX = viewport.x + padding;
|
|
142
|
+
const maxX = viewport.x + viewport.width - floating.width - padding;
|
|
143
|
+
const minY = viewport.y + padding;
|
|
144
|
+
const maxY = viewport.y + viewport.height - floating.height - padding;
|
|
145
|
+
if (shift) {
|
|
146
|
+
if (side === "top" || side === "bottom") {
|
|
147
|
+
x = maxX < minX ? minX : Math.min(Math.max(x, minX), maxX);
|
|
148
|
+
} else {
|
|
149
|
+
y = maxY < minY ? minY : Math.min(Math.max(y, minY), maxY);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
let arrow = null;
|
|
153
|
+
if (arrowSize > 0) {
|
|
154
|
+
const half = arrowSize / 2;
|
|
155
|
+
const inset = arrowSize + 4;
|
|
156
|
+
if (side === "top" || side === "bottom") {
|
|
157
|
+
const centre = anchor.x + anchor.width / 2 - x - half;
|
|
158
|
+
const limit = Math.max(inset, floating.width - inset - arrowSize);
|
|
159
|
+
arrow = {
|
|
160
|
+
x: Math.min(Math.max(centre, inset), limit),
|
|
161
|
+
y: side === "top" ? floating.height : -arrowSize
|
|
162
|
+
};
|
|
163
|
+
} else {
|
|
164
|
+
const centre = anchor.y + anchor.height / 2 - y - half;
|
|
165
|
+
const limit = Math.max(inset, floating.height - inset - arrowSize);
|
|
166
|
+
arrow = {
|
|
167
|
+
x: side === "left" ? floating.width : -arrowSize,
|
|
168
|
+
y: Math.min(Math.max(centre, inset), limit)
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const hidden = anchor.y + anchor.height < viewport.y || anchor.y > viewport.y + viewport.height || anchor.x + anchor.width < viewport.x || anchor.x > viewport.x + viewport.width;
|
|
173
|
+
return {
|
|
174
|
+
x: Math.round(x),
|
|
175
|
+
y: Math.round(y),
|
|
176
|
+
placement: align === "center" ? side : `${side}-${align}`,
|
|
177
|
+
side,
|
|
178
|
+
align,
|
|
179
|
+
arrow,
|
|
180
|
+
hidden
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
var HIDDEN = {
|
|
184
|
+
position: "fixed",
|
|
185
|
+
top: "0px",
|
|
186
|
+
left: "0px",
|
|
187
|
+
// Rendered off-screen rather than `display: none` for the first frame, so the element has real
|
|
188
|
+
// dimensions to measure. Measuring a `display: none` element returns a zero rect, which would
|
|
189
|
+
// place the surface at the anchor's corner for one frame — a visible jump on every open.
|
|
190
|
+
transform: "translate3d(0, -200vh, 0)",
|
|
191
|
+
pointerEvents: "none"
|
|
192
|
+
};
|
|
193
|
+
function useAnchoredPosition(anchorRef, floatingRef, open, options = {}) {
|
|
194
|
+
const {
|
|
195
|
+
matchWidth = false,
|
|
196
|
+
placement = "bottom",
|
|
197
|
+
offset = 8,
|
|
198
|
+
padding = 8,
|
|
199
|
+
flip = true,
|
|
200
|
+
shift = true,
|
|
201
|
+
arrowSize = 0
|
|
202
|
+
} = options;
|
|
203
|
+
const result = shallowRef(null);
|
|
204
|
+
const anchorWidth = shallowRef(null);
|
|
205
|
+
function update() {
|
|
206
|
+
const anchor = anchorRef.value;
|
|
207
|
+
const floating = floatingRef.value;
|
|
208
|
+
if (!anchor || !floating) return;
|
|
209
|
+
const anchorRect = anchor.getBoundingClientRect();
|
|
210
|
+
const floatingRect = floating.getBoundingClientRect();
|
|
211
|
+
if (floatingRect.width === 0 && floatingRect.height === 0) return;
|
|
212
|
+
anchorWidth.value = matchWidth ? anchorRect.width : null;
|
|
213
|
+
result.value = computePosition(
|
|
214
|
+
anchorRect,
|
|
215
|
+
floatingRect,
|
|
216
|
+
{ x: 0, y: 0, width: window.innerWidth, height: window.innerHeight },
|
|
217
|
+
{ placement, offset, padding, flip, shift, arrowSize }
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
let cleanup = null;
|
|
221
|
+
watch(
|
|
222
|
+
open,
|
|
223
|
+
(isOpen) => {
|
|
224
|
+
cleanup?.();
|
|
225
|
+
cleanup = null;
|
|
226
|
+
if (!isOpen) {
|
|
227
|
+
result.value = null;
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
update();
|
|
231
|
+
const onScroll = () => update();
|
|
232
|
+
window.addEventListener("scroll", onScroll, { capture: true, passive: true });
|
|
233
|
+
window.addEventListener("resize", onScroll, { passive: true });
|
|
234
|
+
let observer;
|
|
235
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
236
|
+
observer = new ResizeObserver(() => update());
|
|
237
|
+
if (anchorRef.value) observer.observe(anchorRef.value);
|
|
238
|
+
if (floatingRef.value) observer.observe(floatingRef.value);
|
|
239
|
+
}
|
|
240
|
+
cleanup = () => {
|
|
241
|
+
window.removeEventListener("scroll", onScroll, { capture: true });
|
|
242
|
+
window.removeEventListener("resize", onScroll);
|
|
243
|
+
observer?.disconnect();
|
|
244
|
+
};
|
|
245
|
+
},
|
|
246
|
+
{ immediate: true, flush: "post" }
|
|
247
|
+
);
|
|
248
|
+
if (getCurrentScope()) onScopeDispose(() => cleanup?.());
|
|
249
|
+
const position = computed(() => {
|
|
250
|
+
const r = result.value;
|
|
251
|
+
if (!r) {
|
|
252
|
+
return {
|
|
253
|
+
style: matchWidth && anchorWidth.value !== null ? { ...HIDDEN, width: `${anchorWidth.value}px` } : { ...HIDDEN },
|
|
254
|
+
arrowStyle: void 0,
|
|
255
|
+
placement,
|
|
256
|
+
side: placement.split("-")[0]
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
return {
|
|
260
|
+
style: {
|
|
261
|
+
position: "fixed",
|
|
262
|
+
top: "0px",
|
|
263
|
+
left: "0px",
|
|
264
|
+
// `transform` rather than `top`/`left`: it is composited, so repositioning during scroll
|
|
265
|
+
// does not invalidate layout for the rest of the page.
|
|
266
|
+
transform: `translate3d(${r.x}px, ${r.y}px, 0)`,
|
|
267
|
+
...r.hidden ? { visibility: "hidden", pointerEvents: "none" } : null,
|
|
268
|
+
...anchorWidth.value !== null ? { width: `${anchorWidth.value}px` } : null
|
|
269
|
+
},
|
|
270
|
+
arrowStyle: r.arrow ? { position: "absolute", left: `${r.arrow.x}px`, top: `${r.arrow.y}px` } : void 0,
|
|
271
|
+
placement: r.placement,
|
|
272
|
+
side: r.side
|
|
273
|
+
};
|
|
274
|
+
});
|
|
275
|
+
return { position, update };
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export { computePosition, getLayerStack, useAnchoredPosition, useDismiss, useScrollLock };
|
|
279
|
+
//# sourceMappingURL=chunk-XZ5ZFLZM.js.map
|
|
280
|
+
//# sourceMappingURL=chunk-XZ5ZFLZM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/primitives/use-dismiss.ts","../src/primitives/position.ts","../src/primitives/use-anchored-position.ts"],"names":["watch","getCurrentScope","onScopeDispose"],"mappings":"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","file":"chunk-XZ5ZFLZM.js","sourcesContent":["import { type Ref, getCurrentScope, onScopeDispose, watch } from 'vue'\nimport { type ReadonlyRef, useId } from './utils'\n\n/**\n * Dismissing layered surfaces — the Vue counterpart of `@ansh-ui/react`'s `useDismiss`.\n *\n * The hard part isn't detecting an outside click, it's nesting: a dropdown inside a dialog, with a\n * tooltip inside that. Pressing Escape must close **one** layer, the innermost. A module-level stack\n * shared across every instance (React or Vue — the runtimes don't share memory, but each framework's\n * own instances do) fixes it: surfaces push on open and pop on close, and only the top of the stack\n * responds to Escape.\n */\n\nconst layers: string[] = []\n\n/** Ids of the currently open dismissable layers, outermost first. Exposed for tests. */\nexport function getLayerStack(): readonly string[] {\n return layers\n}\n\nexport interface DismissOptions {\n /** Close on pointer press outside the surface. Default `true`. */\n outsidePress?: boolean\n /** Close on Escape. Only the topmost layer responds. Default `true`. */\n escapeKey?: boolean\n /**\n * Extra elements that count as \"inside\" — normally the trigger.\n *\n * Without this the trigger's own click closes the surface via the outside handler and then\n * immediately reopens it via its own click handler, so the surface appears not to close at all.\n */\n ignore?: Array<Ref<HTMLElement | null | undefined>>\n}\n\nexport function useDismiss(\n target: Ref<HTMLElement | null | undefined>,\n open: ReadonlyRef<boolean>,\n onDismiss: () => void,\n options: DismissOptions = {},\n): void {\n const { outsidePress = true, escapeKey = true, ignore = [] } = options\n const id = useId('layer')\n\n let detach: (() => void) | null = null\n\n const attach = (): void => {\n if (detach) return\n layers.push(id)\n\n const onKeyDown = (event: KeyboardEvent): void => {\n if (!escapeKey || event.key !== 'Escape') return\n // Innermost only.\n if (layers[layers.length - 1] !== id) return\n event.stopPropagation()\n onDismiss()\n }\n\n const onPointerDown = (event: PointerEvent | MouseEvent): void => {\n if (!outsidePress) return\n const target2 = event.target as Node | null\n if (!target2 || !target2.isConnected) return\n if (target.value?.contains(target2)) return\n for (const other of ignore) {\n if (other.value?.contains(target2)) return\n }\n onDismiss()\n }\n\n // `pointerdown` rather than `click`: a click fires after mouseup, so dragging a text selection\n // out of a popover and releasing outside would close it mid-selection.\n document.addEventListener('pointerdown', onPointerDown, true)\n document.addEventListener('keydown', onKeyDown, true)\n\n detach = () => {\n const index = layers.indexOf(id)\n if (index >= 0) layers.splice(index, 1)\n document.removeEventListener('pointerdown', onPointerDown, true)\n document.removeEventListener('keydown', onKeyDown, true)\n detach = null\n }\n }\n\n watch(open, (isOpen) => (isOpen ? attach() : detach?.()), { immediate: true })\n\n if (getCurrentScope()) onScopeDispose(() => detach?.())\n}\n\n/**\n * Lock body scroll while a modal surface is open.\n *\n * Reference-counted, so two stacked modals don't fight over the original value — the inner one\n * closing must not restore scrolling while the outer one is still open.\n *\n * The scrollbar's width is replaced with padding. Without that, hiding the scrollbar reflows the\n * whole page a few pixels wider the instant a dialog opens, which reads as a flash.\n */\nlet scrollLocks = 0\nlet restoreStyles: { overflow: string; paddingRight: string } | null = null\n\nexport function useScrollLock(active: ReadonlyRef<boolean>): void {\n let locked = false\n\n const lock = (): void => {\n if (locked || typeof document === 'undefined') return\n locked = true\n scrollLocks += 1\n if (scrollLocks === 1) {\n const { body } = document\n restoreStyles = { overflow: body.style.overflow, paddingRight: body.style.paddingRight }\n\n const gutter = window.innerWidth - document.documentElement.clientWidth\n body.style.overflow = 'hidden'\n if (gutter > 0) {\n const current = Number.parseFloat(window.getComputedStyle(body).paddingRight) || 0\n body.style.paddingRight = `${current + gutter}px`\n }\n }\n }\n\n const unlock = (): void => {\n if (!locked) return\n locked = false\n scrollLocks -= 1\n if (scrollLocks === 0 && restoreStyles) {\n document.body.style.overflow = restoreStyles.overflow\n document.body.style.paddingRight = restoreStyles.paddingRight\n restoreStyles = null\n }\n }\n\n watch(active, (isActive) => (isActive ? lock() : unlock()), { immediate: true })\n\n if (getCurrentScope()) onScopeDispose(unlock)\n}\n","/**\n * Anchored positioning.\n *\n * Popovers, tooltips, menus and comboboxes all need the same thing: place a floating box next to an\n * anchor, keep it on screen, and report where it actually ended up so the arrow can point the right\n * way. This is that calculation, as a **pure function** of rectangles — verbatim from\n * `@ansh-ui/react`'s `primitives/position.ts`.\n *\n * It is duplicated rather than imported across the workspace boundary on purpose: the function has\n * zero framework dependency, so copying costs nothing in drift (a bug fix here is a five-line diff\n * to mirror) and avoids making `@ansh-ui/vue` depend on `@ansh-ui/react` for one pure function.\n */\n\nexport type Side = 'top' | 'right' | 'bottom' | 'left'\nexport type Align = 'start' | 'center' | 'end'\nexport type Placement = Side | `${Side}-${Align}`\n\nexport interface Rect {\n x: number\n y: number\n width: number\n height: number\n}\n\nexport interface PositionOptions {\n /** Preferred placement. Default `'bottom'`. */\n placement?: Placement\n /** Gap between anchor and floating element, in px. Default `8`. */\n offset?: number\n /** Minimum distance to keep from the viewport edge, in px. Default `8`. */\n padding?: number\n /** Flip to the opposite side when there isn't room. Default `true`. */\n flip?: boolean\n /** Slide along the cross axis to stay on screen. Default `true`. */\n shift?: boolean\n /** Size of the arrow, in px, if one is being positioned. Default `0` (no arrow). */\n arrowSize?: number\n}\n\nexport interface PositionResult {\n x: number\n y: number\n placement: Placement\n side: Side\n align: Align\n arrow: { x: number; y: number } | null\n hidden: boolean\n}\n\nfunction parse(placement: Placement): { side: Side; align: Align } {\n const [side, align = 'center'] = placement.split('-') as [Side, Align?]\n return { side, align }\n}\n\nconst OPPOSITE: Record<Side, Side> = { top: 'bottom', bottom: 'top', left: 'right', right: 'left' }\n\nfunction space(anchor: Rect, viewport: Rect, padding: number) {\n return {\n top: anchor.y - viewport.y - padding,\n bottom: viewport.y + viewport.height - (anchor.y + anchor.height) - padding,\n left: anchor.x - viewport.x - padding,\n right: viewport.x + viewport.width - (anchor.x + anchor.width) - padding,\n }\n}\n\nfunction place(anchor: Rect, floating: Rect, side: Side, align: Align, offset: number) {\n let x = 0\n let y = 0\n\n switch (side) {\n case 'top':\n y = anchor.y - floating.height - offset\n break\n case 'bottom':\n y = anchor.y + anchor.height + offset\n break\n case 'left':\n x = anchor.x - floating.width - offset\n break\n case 'right':\n x = anchor.x + anchor.width + offset\n break\n }\n\n const vertical = side === 'top' || side === 'bottom'\n if (vertical) {\n if (align === 'start') x = anchor.x\n else if (align === 'end') x = anchor.x + anchor.width - floating.width\n else x = anchor.x + anchor.width / 2 - floating.width / 2\n } else {\n if (align === 'start') y = anchor.y\n else if (align === 'end') y = anchor.y + anchor.height - floating.height\n else y = anchor.y + anchor.height / 2 - floating.height / 2\n }\n\n return { x, y }\n}\n\nexport function computePosition(\n anchor: Rect,\n floating: Rect,\n viewport: Rect,\n options: PositionOptions = {},\n): PositionResult {\n const {\n placement = 'bottom',\n offset = 8,\n padding = 8,\n flip = true,\n shift = true,\n arrowSize = 0,\n } = options\n\n const requested = parse(placement)\n let side = requested.side\n const align = requested.align\n\n if (flip) {\n const available = space(anchor, viewport, padding)\n const needed = side === 'top' || side === 'bottom' ? floating.height : floating.width\n const opposite = OPPOSITE[side]\n if (available[side] < needed + offset && available[opposite] > available[side]) {\n side = opposite\n }\n }\n\n let { x, y } = place(anchor, floating, side, align, offset)\n\n const minX = viewport.x + padding\n const maxX = viewport.x + viewport.width - floating.width - padding\n const minY = viewport.y + padding\n const maxY = viewport.y + viewport.height - floating.height - padding\n\n if (shift) {\n if (side === 'top' || side === 'bottom') {\n x = maxX < minX ? minX : Math.min(Math.max(x, minX), maxX)\n } else {\n y = maxY < minY ? minY : Math.min(Math.max(y, minY), maxY)\n }\n }\n\n let arrow: { x: number; y: number } | null = null\n if (arrowSize > 0) {\n const half = arrowSize / 2\n const inset = arrowSize + 4\n if (side === 'top' || side === 'bottom') {\n const centre = anchor.x + anchor.width / 2 - x - half\n const limit = Math.max(inset, floating.width - inset - arrowSize)\n arrow = {\n x: Math.min(Math.max(centre, inset), limit),\n y: side === 'top' ? floating.height : -arrowSize,\n }\n } else {\n const centre = anchor.y + anchor.height / 2 - y - half\n const limit = Math.max(inset, floating.height - inset - arrowSize)\n arrow = {\n x: side === 'left' ? floating.width : -arrowSize,\n y: Math.min(Math.max(centre, inset), limit),\n }\n }\n }\n\n const hidden =\n anchor.y + anchor.height < viewport.y ||\n anchor.y > viewport.y + viewport.height ||\n anchor.x + anchor.width < viewport.x ||\n anchor.x > viewport.x + viewport.width\n\n return {\n x: Math.round(x),\n y: Math.round(y),\n placement: align === 'center' ? side : (`${side}-${align}` as Placement),\n side,\n align,\n arrow,\n hidden,\n }\n}\n","import {\n type ComputedRef,\n type Ref,\n computed,\n getCurrentScope,\n onScopeDispose,\n shallowRef,\n watch,\n} from 'vue'\nimport { type PositionOptions, type PositionResult, computePosition } from './position'\nimport { type ReadonlyRef } from './utils'\n\nexport interface AnchoredPositionOptions extends PositionOptions {\n /** Set the floating element's width to the anchor's — what a combobox listbox wants. */\n matchWidth?: boolean\n}\n\nexport interface AnchoredPosition {\n style: Record<string, string>\n arrowStyle: Record<string, string> | undefined\n placement: PositionResult['placement']\n side: PositionResult['side']\n}\n\nconst HIDDEN = {\n position: 'fixed',\n top: '0px',\n left: '0px',\n // Rendered off-screen rather than `display: none` for the first frame, so the element has real\n // dimensions to measure. Measuring a `display: none` element returns a zero rect, which would\n // place the surface at the anchor's corner for one frame — a visible jump on every open.\n transform: 'translate3d(0, -200vh, 0)',\n pointerEvents: 'none',\n} as const\n\n/**\n * Keep a floating element positioned against an anchor — the Vue counterpart of `@ansh-ui/react`'s\n * `useAnchoredPosition`.\n *\n * Recomputes on scroll (capture phase, so nested scroll containers are caught), on viewport resize,\n * and whenever either element changes size. It deliberately does **not** poll on every frame: that\n * costs a forced layout per frame for a value that changes only on discrete events.\n *\n * Bound to `open` rather than a separate `enabled` flag — every consumer in this package positions\n * only while its surface is open, so a second flag would be unused surface area.\n */\nexport function useAnchoredPosition(\n anchorRef: Ref<HTMLElement | null | undefined>,\n floatingRef: Ref<HTMLElement | null | undefined>,\n open: ReadonlyRef<boolean>,\n options: AnchoredPositionOptions = {},\n): { position: ComputedRef<AnchoredPosition>; update: () => void } {\n const {\n matchWidth = false,\n placement = 'bottom',\n offset = 8,\n padding = 8,\n flip = true,\n shift = true,\n arrowSize = 0,\n } = options\n\n const result = shallowRef<PositionResult | null>(null)\n const anchorWidth = shallowRef<number | null>(null)\n\n function update(): void {\n const anchor = anchorRef.value\n const floating = floatingRef.value\n if (!anchor || !floating) return\n\n const anchorRect = anchor.getBoundingClientRect()\n const floatingRect = floating.getBoundingClientRect()\n\n // jsdom reports every rect as zero. Positioning against a zero-size floating box would place it\n // at the anchor's corner, so bail and leave the off-screen style in place; tests assert on\n // `computePosition` directly, where the geometry is real.\n if (floatingRect.width === 0 && floatingRect.height === 0) return\n\n anchorWidth.value = matchWidth ? anchorRect.width : null\n result.value = computePosition(\n anchorRect,\n floatingRect,\n { x: 0, y: 0, width: window.innerWidth, height: window.innerHeight },\n { placement, offset, padding, flip, shift, arrowSize },\n )\n }\n\n let cleanup: (() => void) | null = null\n\n watch(\n open,\n (isOpen) => {\n cleanup?.()\n cleanup = null\n\n if (!isOpen) {\n result.value = null\n return\n }\n\n update()\n\n // Capture phase catches scrolling in any ancestor container, not just the document.\n const onScroll = (): void => update()\n window.addEventListener('scroll', onScroll, { capture: true, passive: true })\n window.addEventListener('resize', onScroll, { passive: true })\n\n let observer: ResizeObserver | undefined\n if (typeof ResizeObserver !== 'undefined') {\n observer = new ResizeObserver(() => update())\n if (anchorRef.value) observer.observe(anchorRef.value)\n if (floatingRef.value) observer.observe(floatingRef.value)\n }\n\n cleanup = () => {\n window.removeEventListener('scroll', onScroll, { capture: true })\n window.removeEventListener('resize', onScroll)\n observer?.disconnect()\n }\n },\n { immediate: true, flush: 'post' },\n )\n\n if (getCurrentScope()) onScopeDispose(() => cleanup?.())\n\n const position = computed<AnchoredPosition>(() => {\n const r = result.value\n if (!r) {\n return {\n style:\n matchWidth && anchorWidth.value !== null\n ? { ...HIDDEN, width: `${anchorWidth.value}px` }\n : { ...HIDDEN },\n arrowStyle: undefined,\n placement,\n side: placement.split('-')[0] as PositionResult['side'],\n }\n }\n\n return {\n style: {\n position: 'fixed',\n top: '0px',\n left: '0px',\n // `transform` rather than `top`/`left`: it is composited, so repositioning during scroll\n // does not invalidate layout for the rest of the page.\n transform: `translate3d(${r.x}px, ${r.y}px, 0)`,\n ...(r.hidden ? { visibility: 'hidden', pointerEvents: 'none' } : null),\n ...(anchorWidth.value !== null ? { width: `${anchorWidth.value}px` } : null),\n },\n arrowStyle: r.arrow\n ? { position: 'absolute', left: `${r.arrow.x}px`, top: `${r.arrow.y}px` }\n : undefined,\n placement: r.placement,\n side: r.side,\n }\n })\n\n return { position, update }\n}\n"]}
|