nanopop.min.mjs.map 10 KB

1
  1. {"version":3,"file":"nanopop.min.mjs","sources":["../src/NanoPop.ts"],"sourcesContent":["type Direction = 'top' | 'left' | 'bottom' | 'right';\ntype Alignment = 'start' | 'middle' | 'end';\n\nexport type VariantFlipOrder = {\n start: string;\n middle: string;\n end: string;\n};\n\nexport type PositionFlipOrder = {\n top: string;\n right: string;\n bottom: string;\n left: string;\n};\n\nexport type NanoPopPosition = `${Direction}-${Alignment}` | Direction;\n\nexport type NanoPopOptions = {\n container: DOMRect;\n position: NanoPopPosition;\n variantFlipOrder: VariantFlipOrder;\n positionFlipOrder: PositionFlipOrder;\n margin: number;\n reference?: HTMLElement;\n popper?: HTMLElement;\n padding?: number;\n};\n\ntype AvailablePositions = {\n t: number;\n b: number;\n l: number;\n r: number;\n};\n\ntype AvailableVariants = {\n vs: number;\n vm: number;\n ve: number;\n hs: number;\n hm: number;\n he: number;\n};\n\ntype PositionPairs = [Direction, Direction];\n\nexport type PositionMatch = 'ts' | 'tm' | 'te' | 'bs' | 'bm' | 'be' | 'ls' | 'lm' | 'le' | 'rs' | 'rm' | 're';\n\nexport interface NanoPop {\n update(updatedOptions?: Partial<NanoPopOptions>): PositionMatch | null;\n}\n\nexport interface NanoPopConstructor {\n\n /**\n * @param reference Reference element\n * @param popper Actual popper element\n * @param options Optional options\n */\n (reference: HTMLElement, popper: HTMLElement, options?: Partial<NanoPopOptions>): NanoPop;\n\n /**\n * @param options Partial options which get merged with the current one\n */\n (options?: Partial<NanoPopOptions>): NanoPop;\n}\n\n// Export current version\nexport const version = VERSION;\n\n// Export default\nexport const defaults = {\n variantFlipOrder: {start: 'sme', middle: 'mse', end: 'ems'},\n positionFlipOrder: {top: 'tbrl', right: 'rltb', bottom: 'btrl', left: 'lrbt'},\n position: 'bottom',\n margin: 8,\n padding: 0\n};\n\n/**\n * Repositions an element once using the provided options and elements.\n * @param reference Reference element\n * @param popper Popper element\n * @param opt Optional, additional options\n */\nexport const reposition = (\n reference: HTMLElement,\n popper: HTMLElement,\n opt?: Partial<NanoPopOptions>\n): PositionMatch | null => {\n const {\n container,\n margin,\n padding,\n position,\n variantFlipOrder,\n positionFlipOrder\n } = {\n container: document.documentElement.getBoundingClientRect(),\n ...defaults,\n ...opt\n };\n\n /**\n * Reset position to resolve viewport\n * See https://developer.mozilla.org/en-US/docs/Web/CSS/position#fixed\n */\n const {left: originalLeft, top: originalTop} = popper.style;\n popper.style.left = '0';\n popper.style.top = '0';\n\n const refBox = reference.getBoundingClientRect();\n const popBox = popper.getBoundingClientRect();\n\n /**\n * Holds coordinates of top, left, bottom and right alignment\n */\n const positionStore: AvailablePositions = {\n t: refBox.top - popBox.height - margin,\n b: refBox.bottom + margin,\n r: refBox.right + margin,\n l: refBox.left - popBox.width - margin\n };\n\n /**\n * Holds corresponding variants (start, middle, end).\n * The values depend on horizontal / vertical orientation\n */\n const variantStore: AvailableVariants = {\n vs: refBox.left,\n vm: refBox.left + refBox.width / 2 + -popBox.width / 2,\n ve: refBox.left + refBox.width - popBox.width,\n hs: refBox.top,\n hm: refBox.bottom - refBox.height / 2 - popBox.height / 2,\n he: refBox.bottom - popBox.height\n };\n\n // Extract position and variant\n // Top-start -> top is \"position\" and \"start\" is the variant\n const [posKey, varKey = 'middle'] = position.split('-');\n const positions = positionFlipOrder[posKey as keyof PositionFlipOrder];\n const variants = variantFlipOrder[varKey as keyof VariantFlipOrder];\n\n // Try out all possible combinations, starting with the preferred one.\n const {top, left, bottom, right} = container;\n\n for (const p of positions) {\n const vertical = (p === 't' || p === 'b');\n\n // The position-value\n const positionVal = positionStore[p as keyof AvailablePositions];\n\n // Which property has to be changes.\n const [positionKey, variantKey] = (vertical ? ['top', 'left'] : ['left', 'top']) as PositionPairs;\n\n /**\n * box refers to the size of the popper element. Depending on the orientation this is width or height.\n * The limit is the corresponding, maximum value for this position.\n */\n const [positionSize, variantSize] = vertical ? [popBox.height, popBox.width] : [popBox.width, popBox.height];\n\n const [positionMaximum, variantMaximum] = vertical ? [bottom, right] : [right, bottom];\n const [positionMinimum, variantMinimum] = vertical ? [top, left] : [left, top];\n\n // Skip pre-clipped values\n if (positionVal < positionMinimum || (positionVal + positionSize + padding) > positionMaximum) {\n continue;\n }\n\n for (const v of variants) {\n\n // The position-value, the related size value of the popper and the limit\n const variantVal = variantStore[((vertical ? 'v' : 'h') + v) as keyof AvailableVariants];\n\n if (variantVal < variantMinimum || (variantVal + variantSize + padding) > variantMaximum) {\n continue;\n }\n\n // Apply styles and normalize viewport\n popper.style[variantKey] = `${variantVal - popBox[variantKey]}px`;\n popper.style[positionKey] = `${positionVal - popBox[positionKey]}px`;\n return (p + v) as PositionMatch;\n }\n }\n\n // Revert style values (won't work with styled-elements or similar systems)\n // \"Fix\" for https://github.com/Simonwep/nanopop/issues/7\n popper.style.left = originalLeft;\n popper.style.top = originalTop;\n\n return null;\n};\n\n/**\n * Creates a stateful popper.\n * You can either...\n * ... pass an options object: createPopper(<options>)\n * ... pass both the reference and popper: create(<ref>, <el>, <?options>)\n * ... pass nothing, in this case you'll have to set at least both a reference and a popper in update.\n *\n * @param reference | options Reference element or options\n * @param popper Popper element\n * @param options Optional additional options\n */\nexport const createPopper: NanoPopConstructor = (\n reference?: HTMLElement | Partial<NanoPopOptions>,\n popper?: HTMLElement,\n options?: Partial<NanoPopOptions>\n): NanoPop => {\n\n // Resolve options\n const baseOptions: Partial<NanoPopOptions> = typeof reference === 'object' && !(reference instanceof HTMLElement) ?\n reference : {reference, popper, ...options};\n\n return {\n\n /**\n * Repositions the current popper.\n * @param options Optional options which get merged with the current ones.\n */\n update(options: Partial<NanoPopOptions> = baseOptions): PositionMatch | null {\n const {reference, popper} = Object.assign(baseOptions, options);\n\n if (!popper || !reference) {\n throw new Error('Popper- or reference-element missing.');\n }\n\n return reposition(reference, popper, baseOptions);\n }\n };\n};\n"],"names":["version","defaults","variantFlipOrder","start","middle","end","positionFlipOrder","top","right","bottom","left","position","margin","padding","reposition","reference","popper","opt","container","document","documentElement","getBoundingClientRect","originalLeft","originalTop","style","refBox","popBox","positionStore","t","height","b","r","l","width","variantStore","vs","vm","ve","hs","hm","he","posKey","varKey","split","positions","variants","p","vertical","positionVal","positionKey","variantKey","positionSize","variantSize","positionMaximum","variantMaximum","positionMinimum","variantMinimum","v","variantVal","createPopper","options","baseOptions","HTMLElement","update","Object","assign","Error"],"mappings":";AA2DO,MAAMA,EAAU,QAEVC,EAAW,CACpBC,iBAAkB,CAAEC,MAAO,MAAOC,OAAQ,MAAOC,IAAK,OACtDC,kBAAmB,CAAEC,IAAK,OAAQC,MAAO,OAAQC,OAAQ,OAAQC,KAAM,QACvEC,SAAU,SACVC,OAAQ,EACRC,QAAS,GAQAC,EAAa,CAACC,EAAwBC,EAAqBC,KACpE,MAAMC,UAAEA,EAASN,OAAEA,EAAMC,QAAEA,EAAOF,SAAEA,EAAQT,iBAAEA,EAAgBI,kBAAEA,GAAsB,CAClFY,UAAWC,SAASC,gBAAgBC,2BACjCpB,KACAgB,IAMCP,KAAMY,EAAcf,IAAKgB,GAAgBP,EAAOQ,MACxDR,EAAOQ,MAAMd,KAAO,IACpBM,EAAOQ,MAAMjB,IAAM,IACnB,MAAMkB,EAASV,EAAUM,wBACnBK,EAASV,EAAOK,wBAIhBM,EAAoC,CACtCC,EAAGH,EAAOlB,IAAMmB,EAAOG,OAASjB,EAChCkB,EAAGL,EAAOhB,OAASG,EACnBmB,EAAGN,EAAOjB,MAAQI,EAClBoB,EAAGP,EAAOf,KAAOgB,EAAOO,MAAQrB,GAM9BsB,EAAkC,CACpCC,GAAIV,EAAOf,KACX0B,GAAIX,EAAOf,KAAOe,EAAOQ,MAAQ,GAAKP,EAAOO,MAAQ,EACrDI,GAAIZ,EAAOf,KAAOe,EAAOQ,MAAQP,EAAOO,MACxCK,GAAIb,EAAOlB,IACXgC,GAAId,EAAOhB,OAASgB,EAAOI,OAAS,EAAIH,EAAOG,OAAS,EACxDW,GAAIf,EAAOhB,OAASiB,EAAOG,SAIxBY,EAAQC,EAAS,UAAY/B,EAASgC,MAAM,KAC7CC,EAAYtC,EAAkBmC,GAC9BI,EAAW3C,EAAiBwC,IAE5BnC,IAAEA,EAAGG,KAAEA,EAAID,OAAEA,EAAMD,MAAEA,GAAUU,EACrC,IAAK,MAAM4B,KAAKF,EAAW,CACvB,MAAMG,EAAkB,MAAND,GAAmB,MAANA,EAEzBE,EAAcrB,EAAcmB,IAE3BG,EAAaC,GAAeH,EAAW,CAAC,MAAO,QAAU,CAAC,OAAQ,QAKlEI,EAAcC,GAAeL,EAAW,CAACrB,EAAOG,OAAQH,EAAOO,OAAS,CAACP,EAAOO,MAAOP,EAAOG,SAC9FwB,EAAiBC,GAAkBP,EAAW,CAACtC,EAAQD,GAAS,CAACA,EAAOC,IACxE8C,EAAiBC,GAAkBT,EAAW,CAACxC,EAAKG,GAAQ,CAACA,EAAMH,GAE1E,KAAIyC,EAAcO,GAAoBP,EAAcG,EAAetC,EAAWwC,GAG9E,IAAK,MAAMI,KAAKZ,EAAU,CAEtB,MAAMa,EAAaxB,GAAea,EAAW,IAAM,KAAOU,GAC1D,KAAIC,EAAaF,GAAmBE,EAAaN,EAAcvC,EAAWyC,GAM1E,OAFAtC,EAAOQ,MAAM0B,GAAiBQ,EAAahC,EAAOwB,GAAvB,KAC3BlC,EAAOQ,MAAMyB,GAAkBD,EAActB,EAAOuB,GAAxB,KACpBH,EAAIW,CACf,CACJ,CAKD,OAFAzC,EAAOQ,MAAMd,KAAOY,EACpBN,EAAOQ,MAAMjB,IAAMgB,EACZ,IAAI,EAaFoC,EAAmC,CAAC5C,EAAmDC,EAAsB4C,KAEtH,MAAMC,EAA4D,iBAAd9C,GAA4BA,aAAqB+C,YACrF,CAAE/C,YAAWC,YAAW4C,GAApC7C,EACJ,MAAO,CAKHgD,OAAOH,EAAmCC,GACtC,MAAM9C,UAAEA,EAASC,OAAEA,GAAWgD,OAAOC,OAAOJ,EAAaD,GACzD,IAAK5C,IAAWD,EACZ,MAAM,IAAImD,MAAM,yCAEpB,OAAOpD,EAAWC,EAAWC,EAAQ6C,EACxC,EACJ"}