@vielzeug/orbit 1.0.5 → 1.1.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/dist/auto-update.cjs +1 -1
- package/dist/auto-update.cjs.map +1 -1
- package/dist/auto-update.d.ts.map +1 -1
- package/dist/auto-update.js +1 -1
- package/dist/auto-update.js.map +1 -1
- package/dist/containing-block.cjs +2 -0
- package/dist/containing-block.cjs.map +1 -0
- package/dist/containing-block.d.ts +28 -0
- package/dist/containing-block.d.ts.map +1 -0
- package/dist/containing-block.js +2 -0
- package/dist/containing-block.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/orbit.cjs +1 -1
- package/dist/orbit.cjs.map +1 -1
- package/dist/orbit.iife.js +1 -1
- package/dist/orbit.iife.js.map +1 -1
- package/dist/orbit.js +1 -1
- package/dist/orbit.js.map +1 -1
- package/dist/overflow.cjs +1 -1
- package/dist/overflow.cjs.map +1 -1
- package/dist/overflow.d.ts +19 -0
- package/dist/overflow.d.ts.map +1 -1
- package/dist/overflow.js +1 -1
- package/dist/overflow.js.map +1 -1
- package/dist/utils.cjs +1 -1
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.js +1 -1
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
package/dist/utils.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.cjs","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import { clamp } from '@vielzeug/arsenal';\n\nimport type { Alignment, Middleware, Padding, Placement, Rect, Side, SideObject, TypedMiddleware } from './types';\n\nimport { OrbitConfigError } from './errors';\n\nexport { clamp };\n\nexport const OPPOSITE: Record<Side, Side> = { bottom: 'top', left: 'right', right: 'left', top: 'bottom' };\n\n/** Returns the primary side of a placement (`'top' | 'bottom' | 'left' | 'right'`). */\nexport function getSide(p: Placement): Side {\n return p.split('-')[0] as Side;\n}\n\n/** Returns the alignment of a placement (`'start' | 'end'`), or `null` for center placements. */\nexport function getAlignment(p: Placement): Alignment | null {\n return (p.split('-')[1] as Alignment) ?? null;\n}\n\n/** @internal */\nexport function withPlacement(side: Side, align: Alignment | null): Placement {\n return (align ? `${side}-${align}` : side) as Placement;\n}\n\n/** @internal */\nexport function toRect({ height, width, x, y }: DOMRect | Rect): Rect {\n return { height, width, x, y };\n}\n\n/** @internal */\nexport function toSideObject(padding: Padding = 0): SideObject {\n if (typeof padding === 'number') {\n return { bottom: padding, left: padding, right: padding, top: padding };\n }\n\n return {\n bottom: padding.bottom ?? 0,\n left: padding.left ?? 0,\n right: padding.right ?? 0,\n top: padding.top ?? 0,\n };\n}\n\n/** @internal */\nexport function isElement(value: unknown): value is Element {\n return typeof Element !== 'undefined' && value instanceof Element;\n}\n\n// ── Middleware helpers ────────────────────────────────────────────────────────\n\n/**\n * Ordering rules for dev-mode middleware validation.\n * Each tuple is `[mustFollow, mustPrecede]` — `mustFollow` must appear **after** `mustPrecede`\n * in the pipeline. Validation throws if `mustFollow` is found at a lower index than `mustPrecede`.\n * @internal\n */\nexport const MIDDLEWARE_ORDER_RULES: Array<[mustFollow: string, mustPrecede: string]> = [\n ['arrow', 'flip'],\n ['arrow', 'shift'],\n ['arrow', 'autoPlacement'],\n ['flip', 'inline'],\n ['shift', 'inline'],\n ['autoPlacement', 'inline'],\n ['size', 'flip'],\n ['size', 'autoPlacement'],\n];\n\n/**\n * Validates a list of middleware names for known-bad orderings.\n * Throws a descriptive error in dev mode if an invalid ordering is detected.\n * @internal\n */\nexport function validateMiddlewareNames(names: Array<string | null>): void {\n for (const [mustFollow, mustPrecede] of MIDDLEWARE_ORDER_RULES) {\n const followIdx = names.indexOf(mustFollow);\n const precedeIdx = names.indexOf(mustPrecede);\n\n if (followIdx !== -1 && precedeIdx !== -1 && followIdx < precedeIdx) {\n throw new OrbitConfigError(\n `\"${mustFollow}\" must come after \"${mustPrecede}\" in the middleware pipeline. ` +\n `Recommended order: inline → offset → flip/autoPlacement → shift → size → arrow.`,\n );\n }\n }\n\n if (names.includes('flip') && names.includes('autoPlacement')) {\n throw new OrbitConfigError('use either flip() or autoPlacement() in the middleware pipeline, not both.');\n }\n}\n\n/**\n * Unique symbol used to tag middleware with a name for dev-mode ordering validation.\n * Using a Symbol avoids collisions with any `__name` property set by transpilers or wrappers.\n * @internal\n */\nexport const MIDDLEWARE_NAME = Symbol.for('@vielzeug/orbit/name');\n\n/**\n * Tags a middleware function with a name for dev-mode ordering validation and brands it\n * as a `TypedMiddleware<K, D>` for compile-time `middlewareData` inference.\n * @internal\n */\nexport function tagMiddleware<K extends string, D, F extends Middleware>(fn: F, name: K): F & TypedMiddleware<K, D> {\n (fn as Record<symbol, unknown>)[MIDDLEWARE_NAME] = name;\n\n return fn as F & TypedMiddleware<K, D>;\n}\n\n// ── Geometry ──────────────────────────────────────────────────────────────────\n\nfunction alignedOffset(align: Alignment | null, refStart: number, refSize: number, floatSize: number): number {\n if (align === 'start') return refStart;\n\n if (align === 'end') return refStart + refSize - floatSize;\n\n return refStart + (refSize - floatSize) / 2;\n}\n\n/**\n * Computes the base (un-shifted) x/y coordinates for a floating element\n * given the placement and the reference/floating rects.\n * @internal\n */\nexport function baseCoords(placement: Placement, ref: Rect, float: Rect): { x: number; y: number } {\n const side = getSide(placement);\n const align = getAlignment(placement);\n\n switch (side) {\n case 'bottom':\n return { x: alignedOffset(align, ref.x, ref.width, float.width), y: ref.y + ref.height };\n case 'left':\n return { x: ref.x - float.width, y: alignedOffset(align, ref.y, ref.height, float.height) };\n case 'right':\n return { x: ref.x + ref.width, y: alignedOffset(align, ref.y, ref.height, float.height) };\n case 'top':\n return { x: alignedOffset(align, ref.x, ref.width, float.width), y: ref.y - float.height };\n }\n}\n"],"mappings":"6DAQA,IAAa,EAA+B,CAAE,OAAQ,MAAO,KAAM,QAAS,MAAO,OAAQ,IAAK,QAAS,EAGzG,SAAgB,EAAQ,EAAoB,CAC1C,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC,EACtB,CAGA,SAAgB,EAAa,EAAgC,CAC3D,OAAQ,EAAE,MAAM,GAAG,CAAC,CAAC,IAAoB,IAC3C,CAGA,SAAgB,EAAc,EAAY,EAAoC,CAC5E,OAAQ,EAAQ,GAAG,EAAK,GAAG,IAAU,CACvC,CAGA,SAAgB,EAAO,CAAE,SAAQ,QAAO,IAAG,KAA2B,CACpE,MAAO,CAAE,SAAQ,QAAO,IAAG,GAAE,CAC/B,CAGA,SAAgB,EAAa,EAAmB,EAAe,CAK7D,OAJI,OAAO,GAAY,SACd,CAAE,OAAQ,EAAS,KAAM,EAAS,MAAO,EAAS,IAAK,CAAQ,EAGjE,CACL,OAAQ,EAAQ,QAAU,EAC1B,KAAM,EAAQ,MAAQ,EACtB,MAAO,EAAQ,OAAS,EACxB,IAAK,EAAQ,KAAO,CACtB,CACF,CAGA,SAAgB,EAAU,EAAkC,CAC1D,OAAO,OAAO,QAAY,KAAe,aAAiB,OAC5D,CAUA,IAAa,EAA2E,CACtF,CAAC,QAAS,MAAM,EAChB,CAAC,QAAS,OAAO,EACjB,CAAC,QAAS,eAAe,EACzB,CAAC,OAAQ,QAAQ,EACjB,CAAC,QAAS,QAAQ,EAClB,CAAC,gBAAiB,QAAQ,EAC1B,CAAC,OAAQ,MAAM,EACf,CAAC,OAAQ,eAAe,CAC1B,EAOA,SAAgB,EAAwB,EAAmC,CACzE,IAAK,GAAM,CAAC,EAAY,KAAgB,EAAwB,CAC9D,IAAM,EAAY,EAAM,QAAQ,CAAU,EACpC,EAAa,EAAM,QAAQ,CAAW,EAE5C,GAAI,IAAc,IAAM,IAAe,IAAM,EAAY,EACvD,MAAM,IAAI,EAAA,iBACR,IAAI,EAAW,qBAAqB,EAAY,8GAElD,CAEJ,CAEA,GAAI,EAAM,SAAS,MAAM,GAAK,EAAM,SAAS,eAAe,EAC1D,MAAM,IAAI,EAAA,iBAAiB,4EAA4E,CAE3G,CAOA,IAAa,EAAkB,OAAO,IAAI,sBAAsB,EAOhE,SAAgB,EAAyD,EAAO,EAAoC,CAGlH,MAFA,GAAgC,GAAmB,EAE5C,CACT,CAIA,SAAS,EAAc,EAAyB,EAAkB,EAAiB,EAA2B,CAK5G,OAJI,IAAU,QAAgB,EAE1B,IAAU,MAAc,EAAW,EAAU,EAE1C,GAAY,EAAU,GAAa,CAC5C,CAOA,SAAgB,EAAW,EAAsB,EAAW,EAAuC,CACjG,IAAM,EAAO,EAAQ,CAAS,EACxB,EAAQ,EAAa,CAAS,EAEpC,OAAQ,EAAR,CACE,IAAK,SACH,MAAO,CAAE,EAAG,EAAc,EAAO,EAAI,EAAG,EAAI,MAAO,EAAM,KAAK,EAAG,EAAG,EAAI,EAAI,EAAI,MAAO,EACzF,IAAK,OACH,MAAO,CAAE,EAAG,EAAI,EAAI,EAAM,MAAO,EAAG,EAAc,EAAO,EAAI,EAAG,EAAI,OAAQ,EAAM,MAAM,CAAE,EAC5F,IAAK,QACH,MAAO,CAAE,EAAG,EAAI,EAAI,EAAI,MAAO,EAAG,EAAc,EAAO,EAAI,EAAG,EAAI,OAAQ,EAAM,MAAM,CAAE,EAC1F,IAAK,MACH,MAAO,CAAE,EAAG,EAAc,EAAO,EAAI,EAAG,EAAI,MAAO,EAAM,KAAK,EAAG,EAAG,EAAI,EAAI,EAAM,MAAO,CAC7F,CACF"}
|
|
1
|
+
{"version":3,"file":"utils.cjs","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import { clamp } from '@vielzeug/arsenal';\n\nimport type { Alignment, Middleware, Padding, Placement, Rect, Side, SideObject, TypedMiddleware } from './types';\n\nimport { OrbitConfigError } from './errors';\n\nexport { clamp };\n\nexport const OPPOSITE: Record<Side, Side> = { bottom: 'top', left: 'right', right: 'left', top: 'bottom' };\n\n/** Returns the primary side of a placement (`'top' | 'bottom' | 'left' | 'right'`). */\nexport function getSide(p: Placement): Side {\n return p.split('-')[0] as Side;\n}\n\n/** Returns the alignment of a placement (`'start' | 'end'`), or `null` for center placements. */\nexport function getAlignment(p: Placement): Alignment | null {\n return (p.split('-')[1] as Alignment) ?? null;\n}\n\n/** @internal */\nexport function withPlacement(side: Side, align: Alignment | null): Placement {\n return (align ? `${side}-${align}` : side) as Placement;\n}\n\n/** @internal */\nexport function toRect({ height, width, x, y }: DOMRect | Rect): Rect {\n return { height, width, x, y };\n}\n\n/** @internal */\nexport function toSideObject(padding: Padding = 0): SideObject {\n if (typeof padding === 'number') {\n return { bottom: padding, left: padding, right: padding, top: padding };\n }\n\n return {\n bottom: padding.bottom ?? 0,\n left: padding.left ?? 0,\n right: padding.right ?? 0,\n top: padding.top ?? 0,\n };\n}\n\n/** @internal */\nexport function isElement(value: unknown): value is Element {\n return typeof Element !== 'undefined' && value instanceof Element;\n}\n\n/**\n * Returns `node`'s parent in the flat (rendering) tree — the tree CSS layout, paint, and\n * containing-block rules actually walk, which is *not* the same as light-DOM `parentElement`:\n *\n * - If `node` is itself distributed into a `<slot>` (`node.assignedSlot` is set), its rendered\n * parent is that `<slot>`, which lives inside the shadow tree that projects it — not wherever\n * `node.parentElement` points in the light DOM. Skipping this check would walk straight past\n * the shadow host and out into *its* light-DOM ancestors, missing every ancestor between the\n * `<slot>` and the shadow root (a dialog's `.panel`, say) entirely.\n * - Otherwise, falls back to `parentElement`, or — once that's exhausted at a shadow root\n * boundary — the shadow root's host, so the walk continues past shadow boundaries instead of\n * stopping there.\n *\n * `null` once it reaches a true root.\n * @internal\n */\nexport function flatTreeParent(node: Element): Element | null {\n if (node.assignedSlot) return node.assignedSlot;\n\n return (\n node.parentElement ?? (node.getRootNode() instanceof ShadowRoot ? (node.getRootNode() as ShadowRoot).host : null)\n );\n}\n\n// ── Middleware helpers ────────────────────────────────────────────────────────\n\n/**\n * Ordering rules for dev-mode middleware validation.\n * Each tuple is `[mustFollow, mustPrecede]` — `mustFollow` must appear **after** `mustPrecede`\n * in the pipeline. Validation throws if `mustFollow` is found at a lower index than `mustPrecede`.\n * @internal\n */\nexport const MIDDLEWARE_ORDER_RULES: Array<[mustFollow: string, mustPrecede: string]> = [\n ['arrow', 'flip'],\n ['arrow', 'shift'],\n ['arrow', 'autoPlacement'],\n ['flip', 'inline'],\n ['shift', 'inline'],\n ['autoPlacement', 'inline'],\n ['size', 'flip'],\n ['size', 'autoPlacement'],\n];\n\n/**\n * Validates a list of middleware names for known-bad orderings.\n * Throws a descriptive error in dev mode if an invalid ordering is detected.\n * @internal\n */\nexport function validateMiddlewareNames(names: Array<string | null>): void {\n for (const [mustFollow, mustPrecede] of MIDDLEWARE_ORDER_RULES) {\n const followIdx = names.indexOf(mustFollow);\n const precedeIdx = names.indexOf(mustPrecede);\n\n if (followIdx !== -1 && precedeIdx !== -1 && followIdx < precedeIdx) {\n throw new OrbitConfigError(\n `\"${mustFollow}\" must come after \"${mustPrecede}\" in the middleware pipeline. ` +\n `Recommended order: inline → offset → flip/autoPlacement → shift → size → arrow.`,\n );\n }\n }\n\n if (names.includes('flip') && names.includes('autoPlacement')) {\n throw new OrbitConfigError('use either flip() or autoPlacement() in the middleware pipeline, not both.');\n }\n}\n\n/**\n * Unique symbol used to tag middleware with a name for dev-mode ordering validation.\n * Using a Symbol avoids collisions with any `__name` property set by transpilers or wrappers.\n * @internal\n */\nexport const MIDDLEWARE_NAME = Symbol.for('@vielzeug/orbit/name');\n\n/**\n * Tags a middleware function with a name for dev-mode ordering validation and brands it\n * as a `TypedMiddleware<K, D>` for compile-time `middlewareData` inference.\n * @internal\n */\nexport function tagMiddleware<K extends string, D, F extends Middleware>(fn: F, name: K): F & TypedMiddleware<K, D> {\n (fn as Record<symbol, unknown>)[MIDDLEWARE_NAME] = name;\n\n return fn as F & TypedMiddleware<K, D>;\n}\n\n// ── Geometry ──────────────────────────────────────────────────────────────────\n\nfunction alignedOffset(align: Alignment | null, refStart: number, refSize: number, floatSize: number): number {\n if (align === 'start') return refStart;\n\n if (align === 'end') return refStart + refSize - floatSize;\n\n return refStart + (refSize - floatSize) / 2;\n}\n\n/**\n * Computes the base (un-shifted) x/y coordinates for a floating element\n * given the placement and the reference/floating rects.\n * @internal\n */\nexport function baseCoords(placement: Placement, ref: Rect, float: Rect): { x: number; y: number } {\n const side = getSide(placement);\n const align = getAlignment(placement);\n\n switch (side) {\n case 'bottom':\n return { x: alignedOffset(align, ref.x, ref.width, float.width), y: ref.y + ref.height };\n case 'left':\n return { x: ref.x - float.width, y: alignedOffset(align, ref.y, ref.height, float.height) };\n case 'right':\n return { x: ref.x + ref.width, y: alignedOffset(align, ref.y, ref.height, float.height) };\n case 'top':\n return { x: alignedOffset(align, ref.x, ref.width, float.width), y: ref.y - float.height };\n }\n}\n"],"mappings":"6DAQA,IAAa,EAA+B,CAAE,OAAQ,MAAO,KAAM,QAAS,MAAO,OAAQ,IAAK,QAAS,EAGzG,SAAgB,EAAQ,EAAoB,CAC1C,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC,EACtB,CAGA,SAAgB,EAAa,EAAgC,CAC3D,OAAQ,EAAE,MAAM,GAAG,CAAC,CAAC,IAAoB,IAC3C,CAGA,SAAgB,EAAc,EAAY,EAAoC,CAC5E,OAAQ,EAAQ,GAAG,EAAK,GAAG,IAAU,CACvC,CAGA,SAAgB,EAAO,CAAE,SAAQ,QAAO,IAAG,KAA2B,CACpE,MAAO,CAAE,SAAQ,QAAO,IAAG,GAAE,CAC/B,CAGA,SAAgB,EAAa,EAAmB,EAAe,CAK7D,OAJI,OAAO,GAAY,SACd,CAAE,OAAQ,EAAS,KAAM,EAAS,MAAO,EAAS,IAAK,CAAQ,EAGjE,CACL,OAAQ,EAAQ,QAAU,EAC1B,KAAM,EAAQ,MAAQ,EACtB,MAAO,EAAQ,OAAS,EACxB,IAAK,EAAQ,KAAO,CACtB,CACF,CAGA,SAAgB,EAAU,EAAkC,CAC1D,OAAO,OAAO,QAAY,KAAe,aAAiB,OAC5D,CAkBA,SAAgB,EAAe,EAA+B,CAG5D,OAFI,EAAK,aAAqB,EAAK,aAGjC,EAAK,gBAAkB,EAAK,YAAY,YAAa,WAAc,EAAK,YAAY,CAAC,CAAgB,KAAO,KAEhH,CAUA,IAAa,EAA2E,CACtF,CAAC,QAAS,MAAM,EAChB,CAAC,QAAS,OAAO,EACjB,CAAC,QAAS,eAAe,EACzB,CAAC,OAAQ,QAAQ,EACjB,CAAC,QAAS,QAAQ,EAClB,CAAC,gBAAiB,QAAQ,EAC1B,CAAC,OAAQ,MAAM,EACf,CAAC,OAAQ,eAAe,CAC1B,EAOA,SAAgB,EAAwB,EAAmC,CACzE,IAAK,GAAM,CAAC,EAAY,KAAgB,EAAwB,CAC9D,IAAM,EAAY,EAAM,QAAQ,CAAU,EACpC,EAAa,EAAM,QAAQ,CAAW,EAE5C,GAAI,IAAc,IAAM,IAAe,IAAM,EAAY,EACvD,MAAM,IAAI,EAAA,iBACR,IAAI,EAAW,qBAAqB,EAAY,8GAElD,CAEJ,CAEA,GAAI,EAAM,SAAS,MAAM,GAAK,EAAM,SAAS,eAAe,EAC1D,MAAM,IAAI,EAAA,iBAAiB,4EAA4E,CAE3G,CAOA,IAAa,EAAkB,OAAO,IAAI,sBAAsB,EAOhE,SAAgB,EAAyD,EAAO,EAAoC,CAGlH,MAFA,GAAgC,GAAmB,EAE5C,CACT,CAIA,SAAS,EAAc,EAAyB,EAAkB,EAAiB,EAA2B,CAK5G,OAJI,IAAU,QAAgB,EAE1B,IAAU,MAAc,EAAW,EAAU,EAE1C,GAAY,EAAU,GAAa,CAC5C,CAOA,SAAgB,EAAW,EAAsB,EAAW,EAAuC,CACjG,IAAM,EAAO,EAAQ,CAAS,EACxB,EAAQ,EAAa,CAAS,EAEpC,OAAQ,EAAR,CACE,IAAK,SACH,MAAO,CAAE,EAAG,EAAc,EAAO,EAAI,EAAG,EAAI,MAAO,EAAM,KAAK,EAAG,EAAG,EAAI,EAAI,EAAI,MAAO,EACzF,IAAK,OACH,MAAO,CAAE,EAAG,EAAI,EAAI,EAAM,MAAO,EAAG,EAAc,EAAO,EAAI,EAAG,EAAI,OAAQ,EAAM,MAAM,CAAE,EAC5F,IAAK,QACH,MAAO,CAAE,EAAG,EAAI,EAAI,EAAI,MAAO,EAAG,EAAc,EAAO,EAAI,EAAG,EAAI,OAAQ,EAAM,MAAM,CAAE,EAC1F,IAAK,MACH,MAAO,CAAE,EAAG,EAAc,EAAO,EAAI,EAAG,EAAI,MAAO,EAAM,KAAK,EAAG,EAAG,EAAI,EAAI,EAAM,MAAO,CAC7F,CACF"}
|
package/dist/utils.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{OrbitConfigError as e}from"./errors.js";import{clamp as t}from"@vielzeug/arsenal";var n={bottom:`top`,left:`right`,right:`left`,top:`bottom`};function r(e){return e.split(`-`)[0]}function i(e){return e.split(`-`)[1]??null}function a(e,t){return t?`${e}-${t}`:e}function o({height:e,width:t,x:n,y:r}){return{height:e,width:t,x:n,y:r}}function s(e=0){return typeof e==`number`?{bottom:e,left:e,right:e,top:e}:{bottom:e.bottom??0,left:e.left??0,right:e.right??0,top:e.top??0}}function c(e){return typeof Element<`u`&&e instanceof Element}var
|
|
1
|
+
import{OrbitConfigError as e}from"./errors.js";import{clamp as t}from"@vielzeug/arsenal";var n={bottom:`top`,left:`right`,right:`left`,top:`bottom`};function r(e){return e.split(`-`)[0]}function i(e){return e.split(`-`)[1]??null}function a(e,t){return t?`${e}-${t}`:e}function o({height:e,width:t,x:n,y:r}){return{height:e,width:t,x:n,y:r}}function s(e=0){return typeof e==`number`?{bottom:e,left:e,right:e,top:e}:{bottom:e.bottom??0,left:e.left??0,right:e.right??0,top:e.top??0}}function c(e){return typeof Element<`u`&&e instanceof Element}function l(e){return e.assignedSlot?e.assignedSlot:e.parentElement??(e.getRootNode()instanceof ShadowRoot?e.getRootNode().host:null)}var u=[[`arrow`,`flip`],[`arrow`,`shift`],[`arrow`,`autoPlacement`],[`flip`,`inline`],[`shift`,`inline`],[`autoPlacement`,`inline`],[`size`,`flip`],[`size`,`autoPlacement`]];function d(t){for(let[n,r]of u){let i=t.indexOf(n),a=t.indexOf(r);if(i!==-1&&a!==-1&&i<a)throw new e(`"${n}" must come after "${r}" in the middleware pipeline. Recommended order: inline → offset → flip/autoPlacement → shift → size → arrow.`)}if(t.includes(`flip`)&&t.includes(`autoPlacement`))throw new e(`use either flip() or autoPlacement() in the middleware pipeline, not both.`)}var f=Symbol.for(`@vielzeug/orbit/name`);function p(e,t){return e[f]=t,e}function m(e,t,n,r){return e===`start`?t:e===`end`?t+n-r:t+(n-r)/2}function h(e,t,n){let a=r(e),o=i(e);switch(a){case`bottom`:return{x:m(o,t.x,t.width,n.width),y:t.y+t.height};case`left`:return{x:t.x-n.width,y:m(o,t.y,t.height,n.height)};case`right`:return{x:t.x+t.width,y:m(o,t.y,t.height,n.height)};case`top`:return{x:m(o,t.x,t.width,n.width),y:t.y-n.height}}}export{f as MIDDLEWARE_NAME,u as MIDDLEWARE_ORDER_RULES,n as OPPOSITE,h as baseCoords,t as clamp,l as flatTreeParent,i as getAlignment,r as getSide,c as isElement,p as tagMiddleware,o as toRect,s as toSideObject,d as validateMiddlewareNames,a as withPlacement};
|
|
2
2
|
//# sourceMappingURL=utils.js.map
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import { clamp } from '@vielzeug/arsenal';\n\nimport type { Alignment, Middleware, Padding, Placement, Rect, Side, SideObject, TypedMiddleware } from './types';\n\nimport { OrbitConfigError } from './errors';\n\nexport { clamp };\n\nexport const OPPOSITE: Record<Side, Side> = { bottom: 'top', left: 'right', right: 'left', top: 'bottom' };\n\n/** Returns the primary side of a placement (`'top' | 'bottom' | 'left' | 'right'`). */\nexport function getSide(p: Placement): Side {\n return p.split('-')[0] as Side;\n}\n\n/** Returns the alignment of a placement (`'start' | 'end'`), or `null` for center placements. */\nexport function getAlignment(p: Placement): Alignment | null {\n return (p.split('-')[1] as Alignment) ?? null;\n}\n\n/** @internal */\nexport function withPlacement(side: Side, align: Alignment | null): Placement {\n return (align ? `${side}-${align}` : side) as Placement;\n}\n\n/** @internal */\nexport function toRect({ height, width, x, y }: DOMRect | Rect): Rect {\n return { height, width, x, y };\n}\n\n/** @internal */\nexport function toSideObject(padding: Padding = 0): SideObject {\n if (typeof padding === 'number') {\n return { bottom: padding, left: padding, right: padding, top: padding };\n }\n\n return {\n bottom: padding.bottom ?? 0,\n left: padding.left ?? 0,\n right: padding.right ?? 0,\n top: padding.top ?? 0,\n };\n}\n\n/** @internal */\nexport function isElement(value: unknown): value is Element {\n return typeof Element !== 'undefined' && value instanceof Element;\n}\n\n// ── Middleware helpers ────────────────────────────────────────────────────────\n\n/**\n * Ordering rules for dev-mode middleware validation.\n * Each tuple is `[mustFollow, mustPrecede]` — `mustFollow` must appear **after** `mustPrecede`\n * in the pipeline. Validation throws if `mustFollow` is found at a lower index than `mustPrecede`.\n * @internal\n */\nexport const MIDDLEWARE_ORDER_RULES: Array<[mustFollow: string, mustPrecede: string]> = [\n ['arrow', 'flip'],\n ['arrow', 'shift'],\n ['arrow', 'autoPlacement'],\n ['flip', 'inline'],\n ['shift', 'inline'],\n ['autoPlacement', 'inline'],\n ['size', 'flip'],\n ['size', 'autoPlacement'],\n];\n\n/**\n * Validates a list of middleware names for known-bad orderings.\n * Throws a descriptive error in dev mode if an invalid ordering is detected.\n * @internal\n */\nexport function validateMiddlewareNames(names: Array<string | null>): void {\n for (const [mustFollow, mustPrecede] of MIDDLEWARE_ORDER_RULES) {\n const followIdx = names.indexOf(mustFollow);\n const precedeIdx = names.indexOf(mustPrecede);\n\n if (followIdx !== -1 && precedeIdx !== -1 && followIdx < precedeIdx) {\n throw new OrbitConfigError(\n `\"${mustFollow}\" must come after \"${mustPrecede}\" in the middleware pipeline. ` +\n `Recommended order: inline → offset → flip/autoPlacement → shift → size → arrow.`,\n );\n }\n }\n\n if (names.includes('flip') && names.includes('autoPlacement')) {\n throw new OrbitConfigError('use either flip() or autoPlacement() in the middleware pipeline, not both.');\n }\n}\n\n/**\n * Unique symbol used to tag middleware with a name for dev-mode ordering validation.\n * Using a Symbol avoids collisions with any `__name` property set by transpilers or wrappers.\n * @internal\n */\nexport const MIDDLEWARE_NAME = Symbol.for('@vielzeug/orbit/name');\n\n/**\n * Tags a middleware function with a name for dev-mode ordering validation and brands it\n * as a `TypedMiddleware<K, D>` for compile-time `middlewareData` inference.\n * @internal\n */\nexport function tagMiddleware<K extends string, D, F extends Middleware>(fn: F, name: K): F & TypedMiddleware<K, D> {\n (fn as Record<symbol, unknown>)[MIDDLEWARE_NAME] = name;\n\n return fn as F & TypedMiddleware<K, D>;\n}\n\n// ── Geometry ──────────────────────────────────────────────────────────────────\n\nfunction alignedOffset(align: Alignment | null, refStart: number, refSize: number, floatSize: number): number {\n if (align === 'start') return refStart;\n\n if (align === 'end') return refStart + refSize - floatSize;\n\n return refStart + (refSize - floatSize) / 2;\n}\n\n/**\n * Computes the base (un-shifted) x/y coordinates for a floating element\n * given the placement and the reference/floating rects.\n * @internal\n */\nexport function baseCoords(placement: Placement, ref: Rect, float: Rect): { x: number; y: number } {\n const side = getSide(placement);\n const align = getAlignment(placement);\n\n switch (side) {\n case 'bottom':\n return { x: alignedOffset(align, ref.x, ref.width, float.width), y: ref.y + ref.height };\n case 'left':\n return { x: ref.x - float.width, y: alignedOffset(align, ref.y, ref.height, float.height) };\n case 'right':\n return { x: ref.x + ref.width, y: alignedOffset(align, ref.y, ref.height, float.height) };\n case 'top':\n return { x: alignedOffset(align, ref.x, ref.width, float.width), y: ref.y - float.height };\n }\n}\n"],"mappings":"yFAQA,IAAa,EAA+B,CAAE,OAAQ,MAAO,KAAM,QAAS,MAAO,OAAQ,IAAK,QAAS,EAGzG,SAAgB,EAAQ,EAAoB,CAC1C,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC,EACtB,CAGA,SAAgB,EAAa,EAAgC,CAC3D,OAAQ,EAAE,MAAM,GAAG,CAAC,CAAC,IAAoB,IAC3C,CAGA,SAAgB,EAAc,EAAY,EAAoC,CAC5E,OAAQ,EAAQ,GAAG,EAAK,GAAG,IAAU,CACvC,CAGA,SAAgB,EAAO,CAAE,SAAQ,QAAO,IAAG,KAA2B,CACpE,MAAO,CAAE,SAAQ,QAAO,IAAG,GAAE,CAC/B,CAGA,SAAgB,EAAa,EAAmB,EAAe,CAK7D,OAJI,OAAO,GAAY,SACd,CAAE,OAAQ,EAAS,KAAM,EAAS,MAAO,EAAS,IAAK,CAAQ,EAGjE,CACL,OAAQ,EAAQ,QAAU,EAC1B,KAAM,EAAQ,MAAQ,EACtB,MAAO,EAAQ,OAAS,EACxB,IAAK,EAAQ,KAAO,CACtB,CACF,CAGA,SAAgB,EAAU,EAAkC,CAC1D,OAAO,OAAO,QAAY,KAAe,aAAiB,OAC5D,CAUA,IAAa,EAA2E,CACtF,CAAC,QAAS,MAAM,EAChB,CAAC,QAAS,OAAO,EACjB,CAAC,QAAS,eAAe,EACzB,CAAC,OAAQ,QAAQ,EACjB,CAAC,QAAS,QAAQ,EAClB,CAAC,gBAAiB,QAAQ,EAC1B,CAAC,OAAQ,MAAM,EACf,CAAC,OAAQ,eAAe,CAC1B,EAOA,SAAgB,EAAwB,EAAmC,CACzE,IAAK,GAAM,CAAC,EAAY,KAAgB,EAAwB,CAC9D,IAAM,EAAY,EAAM,QAAQ,CAAU,EACpC,EAAa,EAAM,QAAQ,CAAW,EAE5C,GAAI,IAAc,IAAM,IAAe,IAAM,EAAY,EACvD,MAAM,IAAI,EACR,IAAI,EAAW,qBAAqB,EAAY,8GAElD,CAEJ,CAEA,GAAI,EAAM,SAAS,MAAM,GAAK,EAAM,SAAS,eAAe,EAC1D,MAAM,IAAI,EAAiB,4EAA4E,CAE3G,CAOA,IAAa,EAAkB,OAAO,IAAI,sBAAsB,EAOhE,SAAgB,EAAyD,EAAO,EAAoC,CAGlH,MAFA,GAAgC,GAAmB,EAE5C,CACT,CAIA,SAAS,EAAc,EAAyB,EAAkB,EAAiB,EAA2B,CAK5G,OAJI,IAAU,QAAgB,EAE1B,IAAU,MAAc,EAAW,EAAU,EAE1C,GAAY,EAAU,GAAa,CAC5C,CAOA,SAAgB,EAAW,EAAsB,EAAW,EAAuC,CACjG,IAAM,EAAO,EAAQ,CAAS,EACxB,EAAQ,EAAa,CAAS,EAEpC,OAAQ,EAAR,CACE,IAAK,SACH,MAAO,CAAE,EAAG,EAAc,EAAO,EAAI,EAAG,EAAI,MAAO,EAAM,KAAK,EAAG,EAAG,EAAI,EAAI,EAAI,MAAO,EACzF,IAAK,OACH,MAAO,CAAE,EAAG,EAAI,EAAI,EAAM,MAAO,EAAG,EAAc,EAAO,EAAI,EAAG,EAAI,OAAQ,EAAM,MAAM,CAAE,EAC5F,IAAK,QACH,MAAO,CAAE,EAAG,EAAI,EAAI,EAAI,MAAO,EAAG,EAAc,EAAO,EAAI,EAAG,EAAI,OAAQ,EAAM,MAAM,CAAE,EAC1F,IAAK,MACH,MAAO,CAAE,EAAG,EAAc,EAAO,EAAI,EAAG,EAAI,MAAO,EAAM,KAAK,EAAG,EAAG,EAAI,EAAI,EAAM,MAAO,CAC7F,CACF"}
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import { clamp } from '@vielzeug/arsenal';\n\nimport type { Alignment, Middleware, Padding, Placement, Rect, Side, SideObject, TypedMiddleware } from './types';\n\nimport { OrbitConfigError } from './errors';\n\nexport { clamp };\n\nexport const OPPOSITE: Record<Side, Side> = { bottom: 'top', left: 'right', right: 'left', top: 'bottom' };\n\n/** Returns the primary side of a placement (`'top' | 'bottom' | 'left' | 'right'`). */\nexport function getSide(p: Placement): Side {\n return p.split('-')[0] as Side;\n}\n\n/** Returns the alignment of a placement (`'start' | 'end'`), or `null` for center placements. */\nexport function getAlignment(p: Placement): Alignment | null {\n return (p.split('-')[1] as Alignment) ?? null;\n}\n\n/** @internal */\nexport function withPlacement(side: Side, align: Alignment | null): Placement {\n return (align ? `${side}-${align}` : side) as Placement;\n}\n\n/** @internal */\nexport function toRect({ height, width, x, y }: DOMRect | Rect): Rect {\n return { height, width, x, y };\n}\n\n/** @internal */\nexport function toSideObject(padding: Padding = 0): SideObject {\n if (typeof padding === 'number') {\n return { bottom: padding, left: padding, right: padding, top: padding };\n }\n\n return {\n bottom: padding.bottom ?? 0,\n left: padding.left ?? 0,\n right: padding.right ?? 0,\n top: padding.top ?? 0,\n };\n}\n\n/** @internal */\nexport function isElement(value: unknown): value is Element {\n return typeof Element !== 'undefined' && value instanceof Element;\n}\n\n/**\n * Returns `node`'s parent in the flat (rendering) tree — the tree CSS layout, paint, and\n * containing-block rules actually walk, which is *not* the same as light-DOM `parentElement`:\n *\n * - If `node` is itself distributed into a `<slot>` (`node.assignedSlot` is set), its rendered\n * parent is that `<slot>`, which lives inside the shadow tree that projects it — not wherever\n * `node.parentElement` points in the light DOM. Skipping this check would walk straight past\n * the shadow host and out into *its* light-DOM ancestors, missing every ancestor between the\n * `<slot>` and the shadow root (a dialog's `.panel`, say) entirely.\n * - Otherwise, falls back to `parentElement`, or — once that's exhausted at a shadow root\n * boundary — the shadow root's host, so the walk continues past shadow boundaries instead of\n * stopping there.\n *\n * `null` once it reaches a true root.\n * @internal\n */\nexport function flatTreeParent(node: Element): Element | null {\n if (node.assignedSlot) return node.assignedSlot;\n\n return (\n node.parentElement ?? (node.getRootNode() instanceof ShadowRoot ? (node.getRootNode() as ShadowRoot).host : null)\n );\n}\n\n// ── Middleware helpers ────────────────────────────────────────────────────────\n\n/**\n * Ordering rules for dev-mode middleware validation.\n * Each tuple is `[mustFollow, mustPrecede]` — `mustFollow` must appear **after** `mustPrecede`\n * in the pipeline. Validation throws if `mustFollow` is found at a lower index than `mustPrecede`.\n * @internal\n */\nexport const MIDDLEWARE_ORDER_RULES: Array<[mustFollow: string, mustPrecede: string]> = [\n ['arrow', 'flip'],\n ['arrow', 'shift'],\n ['arrow', 'autoPlacement'],\n ['flip', 'inline'],\n ['shift', 'inline'],\n ['autoPlacement', 'inline'],\n ['size', 'flip'],\n ['size', 'autoPlacement'],\n];\n\n/**\n * Validates a list of middleware names for known-bad orderings.\n * Throws a descriptive error in dev mode if an invalid ordering is detected.\n * @internal\n */\nexport function validateMiddlewareNames(names: Array<string | null>): void {\n for (const [mustFollow, mustPrecede] of MIDDLEWARE_ORDER_RULES) {\n const followIdx = names.indexOf(mustFollow);\n const precedeIdx = names.indexOf(mustPrecede);\n\n if (followIdx !== -1 && precedeIdx !== -1 && followIdx < precedeIdx) {\n throw new OrbitConfigError(\n `\"${mustFollow}\" must come after \"${mustPrecede}\" in the middleware pipeline. ` +\n `Recommended order: inline → offset → flip/autoPlacement → shift → size → arrow.`,\n );\n }\n }\n\n if (names.includes('flip') && names.includes('autoPlacement')) {\n throw new OrbitConfigError('use either flip() or autoPlacement() in the middleware pipeline, not both.');\n }\n}\n\n/**\n * Unique symbol used to tag middleware with a name for dev-mode ordering validation.\n * Using a Symbol avoids collisions with any `__name` property set by transpilers or wrappers.\n * @internal\n */\nexport const MIDDLEWARE_NAME = Symbol.for('@vielzeug/orbit/name');\n\n/**\n * Tags a middleware function with a name for dev-mode ordering validation and brands it\n * as a `TypedMiddleware<K, D>` for compile-time `middlewareData` inference.\n * @internal\n */\nexport function tagMiddleware<K extends string, D, F extends Middleware>(fn: F, name: K): F & TypedMiddleware<K, D> {\n (fn as Record<symbol, unknown>)[MIDDLEWARE_NAME] = name;\n\n return fn as F & TypedMiddleware<K, D>;\n}\n\n// ── Geometry ──────────────────────────────────────────────────────────────────\n\nfunction alignedOffset(align: Alignment | null, refStart: number, refSize: number, floatSize: number): number {\n if (align === 'start') return refStart;\n\n if (align === 'end') return refStart + refSize - floatSize;\n\n return refStart + (refSize - floatSize) / 2;\n}\n\n/**\n * Computes the base (un-shifted) x/y coordinates for a floating element\n * given the placement and the reference/floating rects.\n * @internal\n */\nexport function baseCoords(placement: Placement, ref: Rect, float: Rect): { x: number; y: number } {\n const side = getSide(placement);\n const align = getAlignment(placement);\n\n switch (side) {\n case 'bottom':\n return { x: alignedOffset(align, ref.x, ref.width, float.width), y: ref.y + ref.height };\n case 'left':\n return { x: ref.x - float.width, y: alignedOffset(align, ref.y, ref.height, float.height) };\n case 'right':\n return { x: ref.x + ref.width, y: alignedOffset(align, ref.y, ref.height, float.height) };\n case 'top':\n return { x: alignedOffset(align, ref.x, ref.width, float.width), y: ref.y - float.height };\n }\n}\n"],"mappings":"yFAQA,IAAa,EAA+B,CAAE,OAAQ,MAAO,KAAM,QAAS,MAAO,OAAQ,IAAK,QAAS,EAGzG,SAAgB,EAAQ,EAAoB,CAC1C,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC,EACtB,CAGA,SAAgB,EAAa,EAAgC,CAC3D,OAAQ,EAAE,MAAM,GAAG,CAAC,CAAC,IAAoB,IAC3C,CAGA,SAAgB,EAAc,EAAY,EAAoC,CAC5E,OAAQ,EAAQ,GAAG,EAAK,GAAG,IAAU,CACvC,CAGA,SAAgB,EAAO,CAAE,SAAQ,QAAO,IAAG,KAA2B,CACpE,MAAO,CAAE,SAAQ,QAAO,IAAG,GAAE,CAC/B,CAGA,SAAgB,EAAa,EAAmB,EAAe,CAK7D,OAJI,OAAO,GAAY,SACd,CAAE,OAAQ,EAAS,KAAM,EAAS,MAAO,EAAS,IAAK,CAAQ,EAGjE,CACL,OAAQ,EAAQ,QAAU,EAC1B,KAAM,EAAQ,MAAQ,EACtB,MAAO,EAAQ,OAAS,EACxB,IAAK,EAAQ,KAAO,CACtB,CACF,CAGA,SAAgB,EAAU,EAAkC,CAC1D,OAAO,OAAO,QAAY,KAAe,aAAiB,OAC5D,CAkBA,SAAgB,EAAe,EAA+B,CAG5D,OAFI,EAAK,aAAqB,EAAK,aAGjC,EAAK,gBAAkB,EAAK,YAAY,YAAa,WAAc,EAAK,YAAY,CAAC,CAAgB,KAAO,KAEhH,CAUA,IAAa,EAA2E,CACtF,CAAC,QAAS,MAAM,EAChB,CAAC,QAAS,OAAO,EACjB,CAAC,QAAS,eAAe,EACzB,CAAC,OAAQ,QAAQ,EACjB,CAAC,QAAS,QAAQ,EAClB,CAAC,gBAAiB,QAAQ,EAC1B,CAAC,OAAQ,MAAM,EACf,CAAC,OAAQ,eAAe,CAC1B,EAOA,SAAgB,EAAwB,EAAmC,CACzE,IAAK,GAAM,CAAC,EAAY,KAAgB,EAAwB,CAC9D,IAAM,EAAY,EAAM,QAAQ,CAAU,EACpC,EAAa,EAAM,QAAQ,CAAW,EAE5C,GAAI,IAAc,IAAM,IAAe,IAAM,EAAY,EACvD,MAAM,IAAI,EACR,IAAI,EAAW,qBAAqB,EAAY,8GAElD,CAEJ,CAEA,GAAI,EAAM,SAAS,MAAM,GAAK,EAAM,SAAS,eAAe,EAC1D,MAAM,IAAI,EAAiB,4EAA4E,CAE3G,CAOA,IAAa,EAAkB,OAAO,IAAI,sBAAsB,EAOhE,SAAgB,EAAyD,EAAO,EAAoC,CAGlH,MAFA,GAAgC,GAAmB,EAE5C,CACT,CAIA,SAAS,EAAc,EAAyB,EAAkB,EAAiB,EAA2B,CAK5G,OAJI,IAAU,QAAgB,EAE1B,IAAU,MAAc,EAAW,EAAU,EAE1C,GAAY,EAAU,GAAa,CAC5C,CAOA,SAAgB,EAAW,EAAsB,EAAW,EAAuC,CACjG,IAAM,EAAO,EAAQ,CAAS,EACxB,EAAQ,EAAa,CAAS,EAEpC,OAAQ,EAAR,CACE,IAAK,SACH,MAAO,CAAE,EAAG,EAAc,EAAO,EAAI,EAAG,EAAI,MAAO,EAAM,KAAK,EAAG,EAAG,EAAI,EAAI,EAAI,MAAO,EACzF,IAAK,OACH,MAAO,CAAE,EAAG,EAAI,EAAI,EAAM,MAAO,EAAG,EAAc,EAAO,EAAI,EAAG,EAAI,OAAQ,EAAM,MAAM,CAAE,EAC5F,IAAK,QACH,MAAO,CAAE,EAAG,EAAI,EAAI,EAAI,MAAO,EAAG,EAAc,EAAO,EAAI,EAAG,EAAI,OAAQ,EAAM,MAAM,CAAE,EAC1F,IAAK,MACH,MAAO,CAAE,EAAG,EAAc,EAAO,EAAI,EAAG,EAAI,MAAO,EAAM,KAAK,EAAG,EAAG,EAAI,EAAI,EAAM,MAAO,CAC7F,CACF"}
|