Launch Week Day 5: Introducing Reachability for PHP.Learn More
Socket
Book a DemoSign in
Socket

scroll-into-view-if-needed

Package Overview
Dependencies
Maintainers
1
Versions
83
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

scroll-into-view-if-needed - npm Package Compare versions

Comparing version
3.0.10
to
3.1.0
+1
-1
dist/index.cjs

@@ -1,1 +0,1 @@

"use strict";var e=require("compute-scroll-into-view");const o=e=>!1===e?{block:"end",inline:"nearest"}:(e=>e===Object(e)&&0!==Object.keys(e).length)(e)?e:{block:"start",inline:"nearest"};module.exports=function(t,n){if(!t.isConnected||!(e=>{let o=e;for(;o&&o.parentNode;){if(o.parentNode===document)return!0;o=o.parentNode instanceof ShadowRoot?o.parentNode.host:o.parentNode}return!1})(t))return;if((e=>"object"==typeof e&&"function"==typeof e.behavior)(n))return n.behavior(e.compute(t,n));const r="boolean"==typeof n||null==n?void 0:n.behavior;for(const{el:i,top:c,left:l}of e.compute(t,o(n)))i.scroll({top:c,left:l,behavior:r})};//# sourceMappingURL=index.cjs.map
"use strict";var t=require("compute-scroll-into-view");const o=t=>!1===t?{block:"end",inline:"nearest"}:(t=>t===Object(t)&&0!==Object.keys(t).length)(t)?t:{block:"start",inline:"nearest"};module.exports=function(e,r){if(!e.isConnected||!(t=>{let o=t;for(;o&&o.parentNode;){if(o.parentNode===document)return!0;o=o.parentNode instanceof ShadowRoot?o.parentNode.host:o.parentNode}return!1})(e))return;const n=(t=>{const o=window.getComputedStyle(t);return{top:parseFloat(o.scrollMarginTop)||0,right:parseFloat(o.scrollMarginRight)||0,bottom:parseFloat(o.scrollMarginBottom)||0,left:parseFloat(o.scrollMarginLeft)||0}})(e);if((t=>"object"==typeof t&&"function"==typeof t.behavior)(r))return r.behavior(t.compute(e,r));const l="boolean"==typeof r||null==r?void 0:r.behavior;for(const{el:a,top:i,left:c}of t.compute(e,o(r))){const t=i-n.top+n.bottom,o=c-n.left+n.right;a.scroll({top:t,left:o,behavior:l})}};//# sourceMappingURL=index.cjs.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["import { compute } from 'compute-scroll-into-view'\nimport type {\n Options as BaseOptions,\n ScrollAction,\n} from 'compute-scroll-into-view'\n\n/** @public */\nexport type Options<T = unknown> =\n | StandardBehaviorOptions\n | CustomBehaviorOptions<T>\n\n/**\n * Only scrolls if the `node` is partially out of view:\n * ```ts\n * scrollIntoView(node, { scrollMode: 'if-needed' })\n * ```\n * Skips scrolling `overflow: hidden` elements:\n * ```ts\n * scrollIntoView(node, { skipOverflowHiddenElements: true })\n * ```\n * When scrolling is needed do the least and smoothest scrolling possible:\n * ```ts\n * scrollIntoView(node, {\n * behavior: 'smooth',\n * scrollMode: 'if-needed',\n * block: 'nearest',\n * inline: 'nearest',\n * })\n * ```\n * @public\n */\nexport interface StandardBehaviorOptions extends BaseOptions {\n /**\n * @defaultValue 'auto\n */\n behavior?: ScrollBehavior\n}\n\n/** @public */\nexport interface CustomBehaviorOptions<T = unknown> extends BaseOptions {\n behavior: CustomScrollBehaviorCallback<T>\n}\n\n/** @public */\nexport type CustomScrollBehaviorCallback<T = unknown> = (\n actions: ScrollAction[]\n) => T\n\nconst isStandardScrollBehavior = (\n options: any\n): options is StandardBehaviorOptions =>\n options === Object(options) && Object.keys(options).length !== 0\n\nconst isCustomScrollBehavior = <T = unknown>(\n options: any\n): options is CustomBehaviorOptions<T> =>\n typeof options === 'object' ? typeof options.behavior === 'function' : false\n\nconst getOptions = (options: any): StandardBehaviorOptions => {\n // Handle alignToTop for legacy reasons, to be compatible with the spec\n if (options === false) {\n return { block: 'end', inline: 'nearest' }\n }\n\n if (isStandardScrollBehavior(options)) {\n // compute.ts ensures the defaults are block: 'center' and inline: 'nearest', to conform to the spec\n return options\n }\n\n // if options = {}, options = true or options = null, based on w3c web platform test\n return { block: 'start', inline: 'nearest' }\n}\n\n// Determine if the element is part of the document (including shadow dom)\n// Derived from code of Andy Desmarais\n// https://terodox.tech/how-to-tell-if-an-element-is-in-the-dom-including-the-shadow-dom/\nconst isInDocument = (element: Node) => {\n let currentElement = element\n while (currentElement && currentElement.parentNode) {\n if (currentElement.parentNode === document) {\n return true\n } else if (currentElement.parentNode instanceof ShadowRoot) {\n currentElement = (currentElement.parentNode as ShadowRoot).host\n } else {\n currentElement = currentElement.parentNode\n }\n }\n return false\n}\n\n/**\n * Scrolls the given element into view, with options for when, and how.\n * Supports the same `options` as [`Element.prototype.scrollIntoView`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView) with additions such as `scrollMode`, `behavior: Function` and `skipOverflowHiddenElements`.\n * @public\n */\nfunction scrollIntoView(\n target: Element,\n options?: StandardBehaviorOptions | boolean\n): void\n/**\n * Scrolls the given element into view, with options for when, and how.\n * Supports the same `options` as [`Element.prototype.scrollIntoView`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView) with additions such as `scrollMode`, `behavior: Function` and `skipOverflowHiddenElements`.\n *\n * You can set the expected return type for `behavior: Function`:\n * ```ts\n * await scrollIntoView<Promise<boolean[]>>(node, {\n * behavior: async actions => {\n * return Promise.all(actions.map(\n * // animate() resolves to `true` if anything was animated, `false` if the element already were in the end state\n * ({ el, left, top }) => animate(el, {scroll: {left, top}})\n * ))\n * }\n * })\n * ```\n * @public\n */\nfunction scrollIntoView<T>(\n target: Element,\n options: CustomBehaviorOptions<T>\n): T\nfunction scrollIntoView<T = unknown>(\n target: Element,\n options?: StandardBehaviorOptions | CustomBehaviorOptions<T> | boolean\n): T | void {\n // Browsers treats targets that aren't in the dom as a no-op and so should we\n if (!target.isConnected || !isInDocument(target)) {\n return\n }\n\n if (isCustomScrollBehavior<T>(options)) {\n return options.behavior(compute(target, options))\n }\n\n const behavior = typeof options === 'boolean' ? undefined : options?.behavior\n\n for (const { el, top, left } of compute(target, getOptions(options))) {\n el.scroll({ top, left, behavior })\n }\n}\n\nexport default scrollIntoView\n"],"names":["getOptions","options","block","inline","Object","keys","length","isStandardScrollBehavior","module","exports","target","isConnected","element","currentElement","parentNode","document","ShadowRoot","host","isInDocument","behavior","isCustomScrollBehavior","compute","el","top","left","scroll"],"mappings":"uDAgDA,MAUMA,EAAcC,IAEF,IAAZA,EACK,CAAEC,MAAO,MAAOC,OAAQ,WAZjCF,IAEAA,IAAYG,OAAOH,IAA4C,IAAhCG,OAAOC,KAAKJ,GAASK,OAahDC,CAAyBN,GAEpBA,EAIF,CAAEC,MAAO,QAASC,OAAQ,WAoEnCK,OAAAC,QAlBA,SACEC,EACAT,GAGA,IAAKS,EAAOC,cAjDQC,KACpB,IAAIC,EAAiBD,EACd,KAAAC,GAAkBA,EAAeC,YAAY,CAC9C,GAAAD,EAAeC,aAAeC,SACzB,OAAA,EAEPF,EADSA,EAAeC,sBAAsBE,WAC5BH,EAAeC,WAA0BG,KAE1CJ,EAAeC,UAEpC,CACO,OAAA,CAAA,EAsCqBI,CAAaR,GACvC,OAGE,GA3EJT,IAEmB,iBAAZA,GAAmD,mBAArBA,EAAQkB,SAyEzCC,CAA0BnB,GAC5B,OAAOA,EAAQkB,SAASE,EAAAA,QAAQX,EAAQT,IAG1C,MAAMkB,EAA8B,kBAAZlB,GAA6C,MAATA,OAAZ,EAAqBA,EAAAkB,SAE1D,IAAA,MAAAG,GAAEA,EAAIC,IAAAA,EAAAC,KAAKA,KAAUH,UAAQX,EAAQV,EAAWC,IACzDqB,EAAGG,OAAO,CAAEF,MAAKC,OAAML,YAE3B"}
{"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["import { compute } from 'compute-scroll-into-view'\nimport type {\n Options as BaseOptions,\n ScrollAction,\n} from 'compute-scroll-into-view'\n\n/** @public */\nexport type Options<T = unknown> =\n | StandardBehaviorOptions\n | CustomBehaviorOptions<T>\n\n/**\n * Only scrolls if the `node` is partially out of view:\n * ```ts\n * scrollIntoView(node, { scrollMode: 'if-needed' })\n * ```\n * Skips scrolling `overflow: hidden` elements:\n * ```ts\n * scrollIntoView(node, { skipOverflowHiddenElements: true })\n * ```\n * When scrolling is needed do the least and smoothest scrolling possible:\n * ```ts\n * scrollIntoView(node, {\n * behavior: 'smooth',\n * scrollMode: 'if-needed',\n * block: 'nearest',\n * inline: 'nearest',\n * })\n * ```\n * @public\n */\nexport interface StandardBehaviorOptions extends BaseOptions {\n /**\n * @defaultValue 'auto\n */\n behavior?: ScrollBehavior\n}\n\n/** @public */\nexport interface CustomBehaviorOptions<T = unknown> extends BaseOptions {\n behavior: CustomScrollBehaviorCallback<T>\n}\n\n/** @public */\nexport type CustomScrollBehaviorCallback<T = unknown> = (\n actions: ScrollAction[]\n) => T\n\nconst isStandardScrollBehavior = (\n options: any\n): options is StandardBehaviorOptions =>\n options === Object(options) && Object.keys(options).length !== 0\n\nconst isCustomScrollBehavior = <T = unknown>(\n options: any\n): options is CustomBehaviorOptions<T> =>\n typeof options === 'object' ? typeof options.behavior === 'function' : false\n\nconst getOptions = (options: any): StandardBehaviorOptions => {\n // Handle alignToTop for legacy reasons, to be compatible with the spec\n if (options === false) {\n return { block: 'end', inline: 'nearest' }\n }\n\n if (isStandardScrollBehavior(options)) {\n // compute.ts ensures the defaults are block: 'center' and inline: 'nearest', to conform to the spec\n return options\n }\n\n // if options = {}, options = true or options = null, based on w3c web platform test\n return { block: 'start', inline: 'nearest' }\n}\n\nconst getScrollMargins = (target: Element) => {\n const computedStyle = window.getComputedStyle(target)\n return {\n top: parseFloat(computedStyle.scrollMarginTop) || 0,\n right: parseFloat(computedStyle.scrollMarginRight) || 0,\n bottom: parseFloat(computedStyle.scrollMarginBottom) || 0,\n left: parseFloat(computedStyle.scrollMarginLeft) || 0,\n }\n}\n\n// Determine if the element is part of the document (including shadow dom)\n// Derived from code of Andy Desmarais\n// https://terodox.tech/how-to-tell-if-an-element-is-in-the-dom-including-the-shadow-dom/\nconst isInDocument = (element: Node) => {\n let currentElement = element\n while (currentElement && currentElement.parentNode) {\n if (currentElement.parentNode === document) {\n return true\n } else if (currentElement.parentNode instanceof ShadowRoot) {\n currentElement = (currentElement.parentNode as ShadowRoot).host\n } else {\n currentElement = currentElement.parentNode\n }\n }\n return false\n}\n\n/**\n * Scrolls the given element into view, with options for when, and how.\n * Supports the same `options` as [`Element.prototype.scrollIntoView`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView) with additions such as `scrollMode`, `behavior: Function` and `skipOverflowHiddenElements`.\n * @public\n */\nfunction scrollIntoView(\n target: Element,\n options?: StandardBehaviorOptions | boolean\n): void\n/**\n * Scrolls the given element into view, with options for when, and how.\n * Supports the same `options` as [`Element.prototype.scrollIntoView`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView) with additions such as `scrollMode`, `behavior: Function` and `skipOverflowHiddenElements`.\n *\n * You can set the expected return type for `behavior: Function`:\n * ```ts\n * await scrollIntoView<Promise<boolean[]>>(node, {\n * behavior: async actions => {\n * return Promise.all(actions.map(\n * // animate() resolves to `true` if anything was animated, `false` if the element already were in the end state\n * ({ el, left, top }) => animate(el, {scroll: {left, top}})\n * ))\n * }\n * })\n * ```\n * @public\n */\nfunction scrollIntoView<T>(\n target: Element,\n options: CustomBehaviorOptions<T>\n): T\nfunction scrollIntoView<T = unknown>(\n target: Element,\n options?: StandardBehaviorOptions | CustomBehaviorOptions<T> | boolean\n): T | void {\n // Browsers treats targets that aren't in the dom as a no-op and so should we\n if (!target.isConnected || !isInDocument(target)) {\n return\n }\n\n const margins = getScrollMargins(target)\n\n if (isCustomScrollBehavior<T>(options)) {\n return options.behavior(compute(target, options))\n }\n\n const behavior = typeof options === 'boolean' ? undefined : options?.behavior\n\n for (const { el, top, left } of compute(target, getOptions(options))) {\n const adjustedTop = top - margins.top + margins.bottom\n const adjustedLeft = left - margins.left + margins.right\n el.scroll({ top: adjustedTop, left: adjustedLeft, behavior })\n }\n}\n\nexport default scrollIntoView\n"],"names":["getOptions","options","block","inline","Object","keys","length","isStandardScrollBehavior","module","exports","target","isConnected","element","currentElement","parentNode","document","ShadowRoot","host","isInDocument","margins","computedStyle","window","getComputedStyle","top","parseFloat","scrollMarginTop","right","scrollMarginRight","bottom","scrollMarginBottom","left","scrollMarginLeft","getScrollMargins","behavior","isCustomScrollBehavior","compute","el","adjustedTop","adjustedLeft","scroll"],"mappings":"uDAgDA,MAUMA,EAAcC,IAEF,IAAZA,EACK,CAAEC,MAAO,MAAOC,OAAQ,WAZjCF,IAEAA,IAAYG,OAAOH,IAA4C,IAAhCG,OAAOC,KAAKJ,GAASK,OAahDC,CAAyBN,GAEpBA,EAIF,CAAEC,MAAO,QAASC,OAAQ,WAkFnCK,OAAAC,QAtBA,SACEC,EACAT,GAGA,IAAKS,EAAOC,cAjDQC,KACpB,IAAIC,EAAiBD,EACd,KAAAC,GAAkBA,EAAeC,YAAY,CAC9C,GAAAD,EAAeC,aAAeC,SACzB,OAAA,EAEPF,EADSA,EAAeC,sBAAsBE,WAC5BH,EAAeC,WAA0BG,KAE1CJ,EAAeC,UAEpC,CACO,OAAA,CAAA,EAsCqBI,CAAaR,GACvC,OAGI,MAAAS,EAlEkBT,KAClB,MAAAU,EAAgBC,OAAOC,iBAAiBZ,GACvC,MAAA,CACLa,IAAKC,WAAWJ,EAAcK,kBAAoB,EAClDC,MAAOF,WAAWJ,EAAcO,oBAAsB,EACtDC,OAAQJ,WAAWJ,EAAcS,qBAAuB,EACxDC,KAAMN,WAAWJ,EAAcW,mBAAqB,EACtD,EA2DgBC,CAAiBtB,GAE7B,GAvFJT,IAEmB,iBAAZA,GAAmD,mBAArBA,EAAQgC,SAqFzCC,CAA0BjC,GAC5B,OAAOA,EAAQgC,SAASE,EAAAA,QAAQzB,EAAQT,IAG1C,MAAMgC,EAA8B,kBAAZhC,GAA6C,MAATA,OAAZ,EAAqBA,EAAAgC,SAE1D,IAAA,MAAAG,GAAEA,EAAIb,IAAAA,EAAAO,KAAKA,KAAUK,UAAQzB,EAAQV,EAAWC,IAAW,CACpE,MAAMoC,EAAcd,EAAMJ,EAAQI,IAAMJ,EAAQS,OAC1CU,EAAeR,EAAOX,EAAQW,KAAOX,EAAQO,MACnDU,EAAGG,OAAO,CAAEhB,IAAKc,EAAaP,KAAMQ,EAAcL,YACpD,CACF"}

@@ -1,1 +0,1 @@

import{compute as e}from"compute-scroll-into-view";const o=e=>!1===e?{block:"end",inline:"nearest"}:(e=>e===Object(e)&&0!==Object.keys(e).length)(e)?e:{block:"start",inline:"nearest"};function t(t,n){if(!t.isConnected||!(e=>{let o=e;for(;o&&o.parentNode;){if(o.parentNode===document)return!0;o=o.parentNode instanceof ShadowRoot?o.parentNode.host:o.parentNode}return!1})(t))return;if((e=>"object"==typeof e&&"function"==typeof e.behavior)(n))return n.behavior(e(t,n));const r="boolean"==typeof n||null==n?void 0:n.behavior;for(const{el:i,top:a,left:l}of e(t,o(n)))i.scroll({top:a,left:l,behavior:r})}export{t as default};//# sourceMappingURL=index.js.map
import{compute as t}from"compute-scroll-into-view";const o=t=>!1===t?{block:"end",inline:"nearest"}:(t=>t===Object(t)&&0!==Object.keys(t).length)(t)?t:{block:"start",inline:"nearest"};function e(e,r){if(!e.isConnected||!(t=>{let o=t;for(;o&&o.parentNode;){if(o.parentNode===document)return!0;o=o.parentNode instanceof ShadowRoot?o.parentNode.host:o.parentNode}return!1})(e))return;const n=(t=>{const o=window.getComputedStyle(t);return{top:parseFloat(o.scrollMarginTop)||0,right:parseFloat(o.scrollMarginRight)||0,bottom:parseFloat(o.scrollMarginBottom)||0,left:parseFloat(o.scrollMarginLeft)||0}})(e);if((t=>"object"==typeof t&&"function"==typeof t.behavior)(r))return r.behavior(t(e,r));const l="boolean"==typeof r||null==r?void 0:r.behavior;for(const{el:a,top:i,left:s}of t(e,o(r))){const t=i-n.top+n.bottom,o=s-n.left+n.right;a.scroll({top:t,left:o,behavior:l})}}export{e as default};//# sourceMappingURL=index.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { compute } from 'compute-scroll-into-view'\nimport type {\n Options as BaseOptions,\n ScrollAction,\n} from 'compute-scroll-into-view'\n\n/** @public */\nexport type Options<T = unknown> =\n | StandardBehaviorOptions\n | CustomBehaviorOptions<T>\n\n/**\n * Only scrolls if the `node` is partially out of view:\n * ```ts\n * scrollIntoView(node, { scrollMode: 'if-needed' })\n * ```\n * Skips scrolling `overflow: hidden` elements:\n * ```ts\n * scrollIntoView(node, { skipOverflowHiddenElements: true })\n * ```\n * When scrolling is needed do the least and smoothest scrolling possible:\n * ```ts\n * scrollIntoView(node, {\n * behavior: 'smooth',\n * scrollMode: 'if-needed',\n * block: 'nearest',\n * inline: 'nearest',\n * })\n * ```\n * @public\n */\nexport interface StandardBehaviorOptions extends BaseOptions {\n /**\n * @defaultValue 'auto\n */\n behavior?: ScrollBehavior\n}\n\n/** @public */\nexport interface CustomBehaviorOptions<T = unknown> extends BaseOptions {\n behavior: CustomScrollBehaviorCallback<T>\n}\n\n/** @public */\nexport type CustomScrollBehaviorCallback<T = unknown> = (\n actions: ScrollAction[]\n) => T\n\nconst isStandardScrollBehavior = (\n options: any\n): options is StandardBehaviorOptions =>\n options === Object(options) && Object.keys(options).length !== 0\n\nconst isCustomScrollBehavior = <T = unknown>(\n options: any\n): options is CustomBehaviorOptions<T> =>\n typeof options === 'object' ? typeof options.behavior === 'function' : false\n\nconst getOptions = (options: any): StandardBehaviorOptions => {\n // Handle alignToTop for legacy reasons, to be compatible with the spec\n if (options === false) {\n return { block: 'end', inline: 'nearest' }\n }\n\n if (isStandardScrollBehavior(options)) {\n // compute.ts ensures the defaults are block: 'center' and inline: 'nearest', to conform to the spec\n return options\n }\n\n // if options = {}, options = true or options = null, based on w3c web platform test\n return { block: 'start', inline: 'nearest' }\n}\n\n// Determine if the element is part of the document (including shadow dom)\n// Derived from code of Andy Desmarais\n// https://terodox.tech/how-to-tell-if-an-element-is-in-the-dom-including-the-shadow-dom/\nconst isInDocument = (element: Node) => {\n let currentElement = element\n while (currentElement && currentElement.parentNode) {\n if (currentElement.parentNode === document) {\n return true\n } else if (currentElement.parentNode instanceof ShadowRoot) {\n currentElement = (currentElement.parentNode as ShadowRoot).host\n } else {\n currentElement = currentElement.parentNode\n }\n }\n return false\n}\n\n/**\n * Scrolls the given element into view, with options for when, and how.\n * Supports the same `options` as [`Element.prototype.scrollIntoView`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView) with additions such as `scrollMode`, `behavior: Function` and `skipOverflowHiddenElements`.\n * @public\n */\nfunction scrollIntoView(\n target: Element,\n options?: StandardBehaviorOptions | boolean\n): void\n/**\n * Scrolls the given element into view, with options for when, and how.\n * Supports the same `options` as [`Element.prototype.scrollIntoView`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView) with additions such as `scrollMode`, `behavior: Function` and `skipOverflowHiddenElements`.\n *\n * You can set the expected return type for `behavior: Function`:\n * ```ts\n * await scrollIntoView<Promise<boolean[]>>(node, {\n * behavior: async actions => {\n * return Promise.all(actions.map(\n * // animate() resolves to `true` if anything was animated, `false` if the element already were in the end state\n * ({ el, left, top }) => animate(el, {scroll: {left, top}})\n * ))\n * }\n * })\n * ```\n * @public\n */\nfunction scrollIntoView<T>(\n target: Element,\n options: CustomBehaviorOptions<T>\n): T\nfunction scrollIntoView<T = unknown>(\n target: Element,\n options?: StandardBehaviorOptions | CustomBehaviorOptions<T> | boolean\n): T | void {\n // Browsers treats targets that aren't in the dom as a no-op and so should we\n if (!target.isConnected || !isInDocument(target)) {\n return\n }\n\n if (isCustomScrollBehavior<T>(options)) {\n return options.behavior(compute(target, options))\n }\n\n const behavior = typeof options === 'boolean' ? undefined : options?.behavior\n\n for (const { el, top, left } of compute(target, getOptions(options))) {\n el.scroll({ top, left, behavior })\n }\n}\n\nexport default scrollIntoView\n"],"names":["getOptions","options","block","inline","Object","keys","length","isStandardScrollBehavior","scrollIntoView","target","isConnected","element","currentElement","parentNode","document","ShadowRoot","host","isInDocument","behavior","isCustomScrollBehavior","compute","el","top","left","scroll"],"mappings":"mDAgDA,MAUMA,EAAcC,IAEF,IAAZA,EACK,CAAEC,MAAO,MAAOC,OAAQ,WAZjCF,IAEAA,IAAYG,OAAOH,IAA4C,IAAhCG,OAAOC,KAAKJ,GAASK,OAahDC,CAAyBN,GAEpBA,EAIF,CAAEC,MAAO,QAASC,OAAQ,WAkDnC,SAASK,EACPC,EACAR,GAGA,IAAKQ,EAAOC,cAjDQC,KACpB,IAAIC,EAAiBD,EACd,KAAAC,GAAkBA,EAAeC,YAAY,CAC9C,GAAAD,EAAeC,aAAeC,SACzB,OAAA,EAEPF,EADSA,EAAeC,sBAAsBE,WAC5BH,EAAeC,WAA0BG,KAE1CJ,EAAeC,UAEpC,CACO,OAAA,CAAA,EAsCqBI,CAAaR,GACvC,OAGE,GA3EJR,IAEmB,iBAAZA,GAAmD,mBAArBA,EAAQiB,SAyEzCC,CAA0BlB,GAC5B,OAAOA,EAAQiB,SAASE,EAAQX,EAAQR,IAG1C,MAAMiB,EAA8B,kBAAZjB,GAA6C,MAATA,OAAZ,EAAqBA,EAAAiB,SAE1D,IAAA,MAAAG,GAAEA,EAAIC,IAAAA,EAAAC,KAAKA,KAAUH,EAAQX,EAAQT,EAAWC,IACzDoB,EAAGG,OAAO,CAAEF,MAAKC,OAAML,YAE3B,QAAAV"}
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { compute } from 'compute-scroll-into-view'\nimport type {\n Options as BaseOptions,\n ScrollAction,\n} from 'compute-scroll-into-view'\n\n/** @public */\nexport type Options<T = unknown> =\n | StandardBehaviorOptions\n | CustomBehaviorOptions<T>\n\n/**\n * Only scrolls if the `node` is partially out of view:\n * ```ts\n * scrollIntoView(node, { scrollMode: 'if-needed' })\n * ```\n * Skips scrolling `overflow: hidden` elements:\n * ```ts\n * scrollIntoView(node, { skipOverflowHiddenElements: true })\n * ```\n * When scrolling is needed do the least and smoothest scrolling possible:\n * ```ts\n * scrollIntoView(node, {\n * behavior: 'smooth',\n * scrollMode: 'if-needed',\n * block: 'nearest',\n * inline: 'nearest',\n * })\n * ```\n * @public\n */\nexport interface StandardBehaviorOptions extends BaseOptions {\n /**\n * @defaultValue 'auto\n */\n behavior?: ScrollBehavior\n}\n\n/** @public */\nexport interface CustomBehaviorOptions<T = unknown> extends BaseOptions {\n behavior: CustomScrollBehaviorCallback<T>\n}\n\n/** @public */\nexport type CustomScrollBehaviorCallback<T = unknown> = (\n actions: ScrollAction[]\n) => T\n\nconst isStandardScrollBehavior = (\n options: any\n): options is StandardBehaviorOptions =>\n options === Object(options) && Object.keys(options).length !== 0\n\nconst isCustomScrollBehavior = <T = unknown>(\n options: any\n): options is CustomBehaviorOptions<T> =>\n typeof options === 'object' ? typeof options.behavior === 'function' : false\n\nconst getOptions = (options: any): StandardBehaviorOptions => {\n // Handle alignToTop for legacy reasons, to be compatible with the spec\n if (options === false) {\n return { block: 'end', inline: 'nearest' }\n }\n\n if (isStandardScrollBehavior(options)) {\n // compute.ts ensures the defaults are block: 'center' and inline: 'nearest', to conform to the spec\n return options\n }\n\n // if options = {}, options = true or options = null, based on w3c web platform test\n return { block: 'start', inline: 'nearest' }\n}\n\nconst getScrollMargins = (target: Element) => {\n const computedStyle = window.getComputedStyle(target)\n return {\n top: parseFloat(computedStyle.scrollMarginTop) || 0,\n right: parseFloat(computedStyle.scrollMarginRight) || 0,\n bottom: parseFloat(computedStyle.scrollMarginBottom) || 0,\n left: parseFloat(computedStyle.scrollMarginLeft) || 0,\n }\n}\n\n// Determine if the element is part of the document (including shadow dom)\n// Derived from code of Andy Desmarais\n// https://terodox.tech/how-to-tell-if-an-element-is-in-the-dom-including-the-shadow-dom/\nconst isInDocument = (element: Node) => {\n let currentElement = element\n while (currentElement && currentElement.parentNode) {\n if (currentElement.parentNode === document) {\n return true\n } else if (currentElement.parentNode instanceof ShadowRoot) {\n currentElement = (currentElement.parentNode as ShadowRoot).host\n } else {\n currentElement = currentElement.parentNode\n }\n }\n return false\n}\n\n/**\n * Scrolls the given element into view, with options for when, and how.\n * Supports the same `options` as [`Element.prototype.scrollIntoView`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView) with additions such as `scrollMode`, `behavior: Function` and `skipOverflowHiddenElements`.\n * @public\n */\nfunction scrollIntoView(\n target: Element,\n options?: StandardBehaviorOptions | boolean\n): void\n/**\n * Scrolls the given element into view, with options for when, and how.\n * Supports the same `options` as [`Element.prototype.scrollIntoView`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView) with additions such as `scrollMode`, `behavior: Function` and `skipOverflowHiddenElements`.\n *\n * You can set the expected return type for `behavior: Function`:\n * ```ts\n * await scrollIntoView<Promise<boolean[]>>(node, {\n * behavior: async actions => {\n * return Promise.all(actions.map(\n * // animate() resolves to `true` if anything was animated, `false` if the element already were in the end state\n * ({ el, left, top }) => animate(el, {scroll: {left, top}})\n * ))\n * }\n * })\n * ```\n * @public\n */\nfunction scrollIntoView<T>(\n target: Element,\n options: CustomBehaviorOptions<T>\n): T\nfunction scrollIntoView<T = unknown>(\n target: Element,\n options?: StandardBehaviorOptions | CustomBehaviorOptions<T> | boolean\n): T | void {\n // Browsers treats targets that aren't in the dom as a no-op and so should we\n if (!target.isConnected || !isInDocument(target)) {\n return\n }\n\n const margins = getScrollMargins(target)\n\n if (isCustomScrollBehavior<T>(options)) {\n return options.behavior(compute(target, options))\n }\n\n const behavior = typeof options === 'boolean' ? undefined : options?.behavior\n\n for (const { el, top, left } of compute(target, getOptions(options))) {\n const adjustedTop = top - margins.top + margins.bottom\n const adjustedLeft = left - margins.left + margins.right\n el.scroll({ top: adjustedTop, left: adjustedLeft, behavior })\n }\n}\n\nexport default scrollIntoView\n"],"names":["getOptions","options","block","inline","Object","keys","length","isStandardScrollBehavior","scrollIntoView","target","isConnected","element","currentElement","parentNode","document","ShadowRoot","host","isInDocument","margins","computedStyle","window","getComputedStyle","top","parseFloat","scrollMarginTop","right","scrollMarginRight","bottom","scrollMarginBottom","left","scrollMarginLeft","getScrollMargins","behavior","isCustomScrollBehavior","compute","el","adjustedTop","adjustedLeft","scroll"],"mappings":"mDAgDA,MAUMA,EAAcC,IAEF,IAAZA,EACK,CAAEC,MAAO,MAAOC,OAAQ,WAZjCF,IAEAA,IAAYG,OAAOH,IAA4C,IAAhCG,OAAOC,KAAKJ,GAASK,OAahDC,CAAyBN,GAEpBA,EAIF,CAAEC,MAAO,QAASC,OAAQ,WA4DnC,SAASK,EACPC,EACAR,GAGA,IAAKQ,EAAOC,cAjDQC,KACpB,IAAIC,EAAiBD,EACd,KAAAC,GAAkBA,EAAeC,YAAY,CAC9C,GAAAD,EAAeC,aAAeC,SACzB,OAAA,EAEPF,EADSA,EAAeC,sBAAsBE,WAC5BH,EAAeC,WAA0BG,KAE1CJ,EAAeC,UAEpC,CACO,OAAA,CAAA,EAsCqBI,CAAaR,GACvC,OAGI,MAAAS,EAlEkBT,KAClB,MAAAU,EAAgBC,OAAOC,iBAAiBZ,GACvC,MAAA,CACLa,IAAKC,WAAWJ,EAAcK,kBAAoB,EAClDC,MAAOF,WAAWJ,EAAcO,oBAAsB,EACtDC,OAAQJ,WAAWJ,EAAcS,qBAAuB,EACxDC,KAAMN,WAAWJ,EAAcW,mBAAqB,EACtD,EA2DgBC,CAAiBtB,GAE7B,GAvFJR,IAEmB,iBAAZA,GAAmD,mBAArBA,EAAQ+B,SAqFzCC,CAA0BhC,GAC5B,OAAOA,EAAQ+B,SAASE,EAAQzB,EAAQR,IAG1C,MAAM+B,EAA8B,kBAAZ/B,GAA6C,MAATA,OAAZ,EAAqBA,EAAA+B,SAE1D,IAAA,MAAAG,GAAEA,EAAIb,IAAAA,EAAAO,KAAKA,KAAUK,EAAQzB,EAAQT,EAAWC,IAAW,CACpE,MAAMmC,EAAcd,EAAMJ,EAAQI,IAAMJ,EAAQS,OAC1CU,EAAeR,EAAOX,EAAQW,KAAOX,EAAQO,MACnDU,EAAGG,OAAO,CAAEhB,IAAKc,EAAaP,KAAMQ,EAAcL,YACpD,CACF,QAAAxB"}
{
"name": "scroll-into-view-if-needed",
"version": "3.0.10",
"version": "3.1.0",
"description": "Ponyfill for upcoming Element.scrollIntoView() APIs like scrollMode: if-needed, behavior: smooth and block: center",

@@ -5,0 +5,0 @@ "keywords": [

@@ -74,2 +74,12 @@ import { compute } from 'compute-scroll-into-view'

const getScrollMargins = (target: Element) => {
const computedStyle = window.getComputedStyle(target)
return {
top: parseFloat(computedStyle.scrollMarginTop) || 0,
right: parseFloat(computedStyle.scrollMarginRight) || 0,
bottom: parseFloat(computedStyle.scrollMarginBottom) || 0,
left: parseFloat(computedStyle.scrollMarginLeft) || 0,
}
}
// Determine if the element is part of the document (including shadow dom)

@@ -131,2 +141,4 @@ // Derived from code of Andy Desmarais

const margins = getScrollMargins(target)
if (isCustomScrollBehavior<T>(options)) {

@@ -139,3 +151,5 @@ return options.behavior(compute(target, options))

for (const { el, top, left } of compute(target, getOptions(options))) {
el.scroll({ top, left, behavior })
const adjustedTop = top - margins.top + margins.bottom
const adjustedLeft = left - margins.left + margins.right
el.scroll({ top: adjustedTop, left: adjustedLeft, behavior })
}

@@ -142,0 +156,0 @@ }