From ecdc02d9bf7c293b46ed5d49a554a3617194e065 Mon Sep 17 00:00:00 2001 From: Kirill Platonov Date: Fri, 29 Sep 2023 10:55:46 +0200 Subject: [PATCH] Rebuild Popover with Floating UI (#324) --- .../javascripts/polaris_view_components.js | 3025 +++++------------ .../popover_controller.js | 68 +- .../tooltip_controller.js | 56 +- app/components/polaris/popover_component.rb | 6 +- .../autocomplete_component_preview.rb | 3 + .../long_page.html.erb | 22 + package.json | 3 +- yarn.lock | 5 - 8 files changed, 894 insertions(+), 2294 deletions(-) create mode 100644 demo/app/previews/autocomplete_component_preview/long_page.html.erb diff --git a/app/assets/javascripts/polaris_view_components.js b/app/assets/javascripts/polaris_view_components.js index 4cf879e3..86a6c00b 100644 --- a/app/assets/javascripts/polaris_view_components.js +++ b/app/assets/javascripts/polaris_view_components.js @@ -159,7 +159,7 @@ function isEmpty(str) { return str.length === 0 || !str.trim(); } -function debounce$1(fn, wait) { +function debounce(fn, wait) { let timeoutId; return (...args) => { clearTimeout(timeoutId); @@ -210,7 +210,7 @@ class Autocomplete extends Controller { if (this.hasHiddenInputTarget) this.hiddenInputTarget.value = input.value; } } - onInputChange=debounce$1((() => { + onInputChange=debounce((() => { if (this.isRemote) { this.fetchResults(); } else { @@ -431,7 +431,7 @@ class Dropzone extends Controller { event.preventDefault(); this.onClick(); }; - onWindowResize=debounce$1((() => { + onWindowResize=debounce((() => { const size = this.calculateSize(); if (size !== this.size) { this.size = size; @@ -890,1933 +890,207 @@ class Polaris extends Controller { } } -var top = "top"; - -var bottom = "bottom"; - -var right = "right"; - -var left = "left"; - -var auto = "auto"; - -var basePlacements = [ top, bottom, right, left ]; - -var start = "start"; - -var end = "end"; - -var clippingParents = "clippingParents"; - -var viewport = "viewport"; - -var popper = "popper"; - -var reference = "reference"; - -var variationPlacements = basePlacements.reduce((function(acc, placement) { - return acc.concat([ placement + "-" + start, placement + "-" + end ]); -}), []); - -var placements = [].concat(basePlacements, [ auto ]).reduce((function(acc, placement) { - return acc.concat([ placement, placement + "-" + start, placement + "-" + end ]); -}), []); - -var beforeRead = "beforeRead"; - -var read = "read"; - -var afterRead = "afterRead"; - -var beforeMain = "beforeMain"; - -var main = "main"; - -var afterMain = "afterMain"; - -var beforeWrite = "beforeWrite"; +const min = Math.min; -var write = "write"; +const max = Math.max; -var afterWrite = "afterWrite"; +const round = Math.round; -var modifierPhases = [ beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite ]; +const floor = Math.floor; -function getNodeName$1(element) { - return element ? (element.nodeName || "").toLowerCase() : null; -} +const createCoords = v => ({ + x: v, + y: v +}); -function getWindow$1(node) { - if (node == null) { - return window; - } - if (node.toString() !== "[object Window]") { - var ownerDocument = node.ownerDocument; - return ownerDocument ? ownerDocument.defaultView || window : window; - } - return node; -} +const oppositeSideMap = { + left: "right", + right: "left", + bottom: "top", + top: "bottom" +}; -function isElement$1(node) { - var OwnElement = getWindow$1(node).Element; - return node instanceof OwnElement || node instanceof Element; -} +const oppositeAlignmentMap = { + start: "end", + end: "start" +}; -function isHTMLElement$1(node) { - var OwnElement = getWindow$1(node).HTMLElement; - return node instanceof OwnElement || node instanceof HTMLElement; +function clamp(start, value, end) { + return max(start, min(value, end)); } -function isShadowRoot$1(node) { - if (typeof ShadowRoot === "undefined") { - return false; - } - var OwnElement = getWindow$1(node).ShadowRoot; - return node instanceof OwnElement || node instanceof ShadowRoot; +function evaluate(value, param) { + return typeof value === "function" ? value(param) : value; } -function applyStyles(_ref) { - var state = _ref.state; - Object.keys(state.elements).forEach((function(name) { - var style = state.styles[name] || {}; - var attributes = state.attributes[name] || {}; - var element = state.elements[name]; - if (!isHTMLElement$1(element) || !getNodeName$1(element)) { - return; - } - Object.assign(element.style, style); - Object.keys(attributes).forEach((function(name) { - var value = attributes[name]; - if (value === false) { - element.removeAttribute(name); - } else { - element.setAttribute(name, value === true ? "" : value); - } - })); - })); +function getSide(placement) { + return placement.split("-")[0]; } -function effect$2(_ref2) { - var state = _ref2.state; - var initialStyles = { - popper: { - position: state.options.strategy, - left: "0", - top: "0", - margin: "0" - }, - arrow: { - position: "absolute" - }, - reference: {} - }; - Object.assign(state.elements.popper.style, initialStyles.popper); - state.styles = initialStyles; - if (state.elements.arrow) { - Object.assign(state.elements.arrow.style, initialStyles.arrow); - } - return function() { - Object.keys(state.elements).forEach((function(name) { - var element = state.elements[name]; - var attributes = state.attributes[name] || {}; - var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); - var style = styleProperties.reduce((function(style, property) { - style[property] = ""; - return style; - }), {}); - if (!isHTMLElement$1(element) || !getNodeName$1(element)) { - return; - } - Object.assign(element.style, style); - Object.keys(attributes).forEach((function(attribute) { - element.removeAttribute(attribute); - })); - })); - }; +function getAlignment(placement) { + return placement.split("-")[1]; } -var applyStyles$1 = { - name: "applyStyles", - enabled: true, - phase: "write", - fn: applyStyles, - effect: effect$2, - requires: [ "computeStyles" ] -}; - -function getBasePlacement(placement) { - return placement.split("-")[0]; +function getOppositeAxis(axis) { + return axis === "x" ? "y" : "x"; } -var max$1 = Math.max; - -var min$1 = Math.min; - -var round$1 = Math.round; - -function getUAString() { - var uaData = navigator.userAgentData; - if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) { - return uaData.brands.map((function(item) { - return item.brand + "/" + item.version; - })).join(" "); - } - return navigator.userAgent; +function getAxisLength(axis) { + return axis === "y" ? "height" : "width"; } -function isLayoutViewport() { - return !/^((?!chrome|android).)*safari/i.test(getUAString()); +function getSideAxis(placement) { + return [ "top", "bottom" ].includes(getSide(placement)) ? "y" : "x"; } -function getBoundingClientRect$1(element, includeScale, isFixedStrategy) { - if (includeScale === void 0) { - includeScale = false; - } - if (isFixedStrategy === void 0) { - isFixedStrategy = false; - } - var clientRect = element.getBoundingClientRect(); - var scaleX = 1; - var scaleY = 1; - if (includeScale && isHTMLElement$1(element)) { - scaleX = element.offsetWidth > 0 ? round$1(clientRect.width) / element.offsetWidth || 1 : 1; - scaleY = element.offsetHeight > 0 ? round$1(clientRect.height) / element.offsetHeight || 1 : 1; - } - var _ref = isElement$1(element) ? getWindow$1(element) : window, visualViewport = _ref.visualViewport; - var addVisualOffsets = !isLayoutViewport() && isFixedStrategy; - var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX; - var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY; - var width = clientRect.width / scaleX; - var height = clientRect.height / scaleY; - return { - width: width, - height: height, - top: y, - right: x + width, - bottom: y + height, - left: x, - x: x, - y: y - }; +function getAlignmentAxis(placement) { + return getOppositeAxis(getSideAxis(placement)); } -function getLayoutRect(element) { - var clientRect = getBoundingClientRect$1(element); - var width = element.offsetWidth; - var height = element.offsetHeight; - if (Math.abs(clientRect.width - width) <= 1) { - width = clientRect.width; - } - if (Math.abs(clientRect.height - height) <= 1) { - height = clientRect.height; +function getAlignmentSides(placement, rects, rtl) { + if (rtl === void 0) { + rtl = false; } - return { - x: element.offsetLeft, - y: element.offsetTop, - width: width, - height: height - }; -} - -function contains(parent, child) { - var rootNode = child.getRootNode && child.getRootNode(); - if (parent.contains(child)) { - return true; - } else if (rootNode && isShadowRoot$1(rootNode)) { - var next = child; - do { - if (next && parent.isSameNode(next)) { - return true; - } - next = next.parentNode || next.host; - } while (next); + const alignment = getAlignment(placement); + const alignmentAxis = getAlignmentAxis(placement); + const length = getAxisLength(alignmentAxis); + let mainAlignmentSide = alignmentAxis === "x" ? alignment === (rtl ? "end" : "start") ? "right" : "left" : alignment === "start" ? "bottom" : "top"; + if (rects.reference[length] > rects.floating[length]) { + mainAlignmentSide = getOppositePlacement(mainAlignmentSide); } - return false; + return [ mainAlignmentSide, getOppositePlacement(mainAlignmentSide) ]; } -function getComputedStyle$2(element) { - return getWindow$1(element).getComputedStyle(element); +function getExpandedPlacements(placement) { + const oppositePlacement = getOppositePlacement(placement); + return [ getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement) ]; } -function isTableElement$1(element) { - return [ "table", "td", "th" ].indexOf(getNodeName$1(element)) >= 0; +function getOppositeAlignmentPlacement(placement) { + return placement.replace(/start|end/g, (alignment => oppositeAlignmentMap[alignment])); } -function getDocumentElement$1(element) { - return ((isElement$1(element) ? element.ownerDocument : element.document) || window.document).documentElement; -} +function getSideList(side, isStart, rtl) { + const lr = [ "left", "right" ]; + const rl = [ "right", "left" ]; + const tb = [ "top", "bottom" ]; + const bt = [ "bottom", "top" ]; + switch (side) { + case "top": + case "bottom": + if (rtl) return isStart ? rl : lr; + return isStart ? lr : rl; -function getParentNode$1(element) { - if (getNodeName$1(element) === "html") { - return element; - } - return element.assignedSlot || element.parentNode || (isShadowRoot$1(element) ? element.host : null) || getDocumentElement$1(element); -} + case "left": + case "right": + return isStart ? tb : bt; -function getTrueOffsetParent$1(element) { - if (!isHTMLElement$1(element) || getComputedStyle$2(element).position === "fixed") { - return null; + default: + return []; } - return element.offsetParent; } -function getContainingBlock$1(element) { - var isFirefox = /firefox/i.test(getUAString()); - var isIE = /Trident/i.test(getUAString()); - if (isIE && isHTMLElement$1(element)) { - var elementCss = getComputedStyle$2(element); - if (elementCss.position === "fixed") { - return null; - } - } - var currentNode = getParentNode$1(element); - if (isShadowRoot$1(currentNode)) { - currentNode = currentNode.host; - } - while (isHTMLElement$1(currentNode) && [ "html", "body" ].indexOf(getNodeName$1(currentNode)) < 0) { - var css = getComputedStyle$2(currentNode); - if (css.transform !== "none" || css.perspective !== "none" || css.contain === "paint" || [ "transform", "perspective" ].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === "filter" || isFirefox && css.filter && css.filter !== "none") { - return currentNode; - } else { - currentNode = currentNode.parentNode; +function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) { + const alignment = getAlignment(placement); + let list = getSideList(getSide(placement), direction === "start", rtl); + if (alignment) { + list = list.map((side => side + "-" + alignment)); + if (flipAlignment) { + list = list.concat(list.map(getOppositeAlignmentPlacement)); } } - return null; -} - -function getOffsetParent$1(element) { - var window = getWindow$1(element); - var offsetParent = getTrueOffsetParent$1(element); - while (offsetParent && isTableElement$1(offsetParent) && getComputedStyle$2(offsetParent).position === "static") { - offsetParent = getTrueOffsetParent$1(offsetParent); - } - if (offsetParent && (getNodeName$1(offsetParent) === "html" || getNodeName$1(offsetParent) === "body" && getComputedStyle$2(offsetParent).position === "static")) { - return window; - } - return offsetParent || getContainingBlock$1(element) || window; -} - -function getMainAxisFromPlacement(placement) { - return [ "top", "bottom" ].indexOf(placement) >= 0 ? "x" : "y"; -} - -function within(min, value, max) { - return max$1(min, min$1(value, max)); + return list; } -function withinMaxClamp(min, value, max) { - var v = within(min, value, max); - return v > max ? max : v; +function getOppositePlacement(placement) { + return placement.replace(/left|right|bottom|top/g, (side => oppositeSideMap[side])); } -function getFreshSideObject() { +function expandPaddingObject(padding) { return { top: 0, right: 0, bottom: 0, - left: 0 + left: 0, + ...padding }; } -function mergePaddingObject(paddingObject) { - return Object.assign({}, getFreshSideObject(), paddingObject); +function getPaddingObject(padding) { + return typeof padding !== "number" ? expandPaddingObject(padding) : { + top: padding, + right: padding, + bottom: padding, + left: padding + }; } -function expandToHashMap(value, keys) { - return keys.reduce((function(hashMap, key) { - hashMap[key] = value; - return hashMap; - }), {}); +function rectToClientRect(rect) { + return { + ...rect, + top: rect.y, + left: rect.x, + right: rect.x + rect.width, + bottom: rect.y + rect.height + }; } -var toPaddingObject = function toPaddingObject(padding, state) { - padding = typeof padding === "function" ? padding(Object.assign({}, state.rects, { - placement: state.placement - })) : padding; - return mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements)); -}; +function computeCoordsFromPlacement(_ref, placement, rtl) { + let {reference: reference, floating: floating} = _ref; + const sideAxis = getSideAxis(placement); + const alignmentAxis = getAlignmentAxis(placement); + const alignLength = getAxisLength(alignmentAxis); + const side = getSide(placement); + const isVertical = sideAxis === "y"; + const commonX = reference.x + reference.width / 2 - floating.width / 2; + const commonY = reference.y + reference.height / 2 - floating.height / 2; + const commonAlign = reference[alignLength] / 2 - floating[alignLength] / 2; + let coords; + switch (side) { + case "top": + coords = { + x: commonX, + y: reference.y - floating.height + }; + break; -function arrow$1(_ref) { - var _state$modifiersData$; - var state = _ref.state, name = _ref.name, options = _ref.options; - var arrowElement = state.elements.arrow; - var popperOffsets = state.modifiersData.popperOffsets; - var basePlacement = getBasePlacement(state.placement); - var axis = getMainAxisFromPlacement(basePlacement); - var isVertical = [ left, right ].indexOf(basePlacement) >= 0; - var len = isVertical ? "height" : "width"; - if (!arrowElement || !popperOffsets) { - return; - } - var paddingObject = toPaddingObject(options.padding, state); - var arrowRect = getLayoutRect(arrowElement); - var minProp = axis === "y" ? top : left; - var maxProp = axis === "y" ? bottom : right; - var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len]; - var startDiff = popperOffsets[axis] - state.rects.reference[axis]; - var arrowOffsetParent = getOffsetParent$1(arrowElement); - var clientSize = arrowOffsetParent ? axis === "y" ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0; - var centerToReference = endDiff / 2 - startDiff / 2; - var min = paddingObject[minProp]; - var max = clientSize - arrowRect[len] - paddingObject[maxProp]; - var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference; - var offset = within(min, center, max); - var axisProp = axis; - state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, - _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$); -} - -function effect$1(_ref2) { - var state = _ref2.state, options = _ref2.options; - var _options$element = options.element, arrowElement = _options$element === void 0 ? "[data-popper-arrow]" : _options$element; - if (arrowElement == null) { - return; - } - if (typeof arrowElement === "string") { - arrowElement = state.elements.popper.querySelector(arrowElement); - if (!arrowElement) { - return; - } - } - if (!contains(state.elements.popper, arrowElement)) { - return; - } - state.elements.arrow = arrowElement; -} + case "bottom": + coords = { + x: commonX, + y: reference.y + reference.height + }; + break; -var arrow$2 = { - name: "arrow", - enabled: true, - phase: "main", - fn: arrow$1, - effect: effect$1, - requires: [ "popperOffsets" ], - requiresIfExists: [ "preventOverflow" ] -}; + case "right": + coords = { + x: reference.x + reference.width, + y: commonY + }; + break; -function getVariation(placement) { - return placement.split("-")[1]; -} + case "left": + coords = { + x: reference.x - floating.width, + y: commonY + }; + break; -var unsetSides = { - top: "auto", - right: "auto", - bottom: "auto", - left: "auto" -}; + default: + coords = { + x: reference.x, + y: reference.y + }; + } + switch (getAlignment(placement)) { + case "start": + coords[alignmentAxis] -= commonAlign * (rtl && isVertical ? -1 : 1); + break; -function roundOffsetsByDPR(_ref, win) { - var x = _ref.x, y = _ref.y; - var dpr = win.devicePixelRatio || 1; - return { - x: round$1(x * dpr) / dpr || 0, - y: round$1(y * dpr) / dpr || 0 - }; -} - -function mapToStyles(_ref2) { - var _Object$assign2; - var popper = _ref2.popper, popperRect = _ref2.popperRect, placement = _ref2.placement, variation = _ref2.variation, offsets = _ref2.offsets, position = _ref2.position, gpuAcceleration = _ref2.gpuAcceleration, adaptive = _ref2.adaptive, roundOffsets = _ref2.roundOffsets, isFixed = _ref2.isFixed; - var _offsets$x = offsets.x, x = _offsets$x === void 0 ? 0 : _offsets$x, _offsets$y = offsets.y, y = _offsets$y === void 0 ? 0 : _offsets$y; - var _ref3 = typeof roundOffsets === "function" ? roundOffsets({ - x: x, - y: y - }) : { - x: x, - y: y - }; - x = _ref3.x; - y = _ref3.y; - var hasX = offsets.hasOwnProperty("x"); - var hasY = offsets.hasOwnProperty("y"); - var sideX = left; - var sideY = top; - var win = window; - if (adaptive) { - var offsetParent = getOffsetParent$1(popper); - var heightProp = "clientHeight"; - var widthProp = "clientWidth"; - if (offsetParent === getWindow$1(popper)) { - offsetParent = getDocumentElement$1(popper); - if (getComputedStyle$2(offsetParent).position !== "static" && position === "absolute") { - heightProp = "scrollHeight"; - widthProp = "scrollWidth"; - } - } - offsetParent = offsetParent; - if (placement === top || (placement === left || placement === right) && variation === end) { - sideY = bottom; - var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : offsetParent[heightProp]; - y -= offsetY - popperRect.height; - y *= gpuAcceleration ? 1 : -1; - } - if (placement === left || (placement === top || placement === bottom) && variation === end) { - sideX = right; - var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : offsetParent[widthProp]; - x -= offsetX - popperRect.width; - x *= gpuAcceleration ? 1 : -1; - } - } - var commonStyles = Object.assign({ - position: position - }, adaptive && unsetSides); - var _ref4 = roundOffsets === true ? roundOffsetsByDPR({ - x: x, - y: y - }, getWindow$1(popper)) : { - x: x, - y: y - }; - x = _ref4.x; - y = _ref4.y; - if (gpuAcceleration) { - var _Object$assign; - return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? "0" : "", - _Object$assign[sideX] = hasX ? "0" : "", _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", - _Object$assign)); - } - return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : "", - _Object$assign2[sideX] = hasX ? x + "px" : "", _Object$assign2.transform = "", _Object$assign2)); -} - -function computeStyles(_ref5) { - var state = _ref5.state, options = _ref5.options; - var _options$gpuAccelerat = options.gpuAcceleration, gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, _options$adaptive = options.adaptive, adaptive = _options$adaptive === void 0 ? true : _options$adaptive, _options$roundOffsets = options.roundOffsets, roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets; - var commonStyles = { - placement: getBasePlacement(state.placement), - variation: getVariation(state.placement), - popper: state.elements.popper, - popperRect: state.rects.popper, - gpuAcceleration: gpuAcceleration, - isFixed: state.options.strategy === "fixed" - }; - if (state.modifiersData.popperOffsets != null) { - state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, { - offsets: state.modifiersData.popperOffsets, - position: state.options.strategy, - adaptive: adaptive, - roundOffsets: roundOffsets - }))); - } - if (state.modifiersData.arrow != null) { - state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, { - offsets: state.modifiersData.arrow, - position: "absolute", - adaptive: false, - roundOffsets: roundOffsets - }))); - } - state.attributes.popper = Object.assign({}, state.attributes.popper, { - "data-popper-placement": state.placement - }); -} - -var computeStyles$1 = { - name: "computeStyles", - enabled: true, - phase: "beforeWrite", - fn: computeStyles, - data: {} -}; - -var passive = { - passive: true -}; - -function effect(_ref) { - var state = _ref.state, instance = _ref.instance, options = _ref.options; - var _options$scroll = options.scroll, scroll = _options$scroll === void 0 ? true : _options$scroll, _options$resize = options.resize, resize = _options$resize === void 0 ? true : _options$resize; - var window = getWindow$1(state.elements.popper); - var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper); - if (scroll) { - scrollParents.forEach((function(scrollParent) { - scrollParent.addEventListener("scroll", instance.update, passive); - })); - } - if (resize) { - window.addEventListener("resize", instance.update, passive); - } - return function() { - if (scroll) { - scrollParents.forEach((function(scrollParent) { - scrollParent.removeEventListener("scroll", instance.update, passive); - })); - } - if (resize) { - window.removeEventListener("resize", instance.update, passive); - } - }; -} - -var eventListeners = { - name: "eventListeners", - enabled: true, - phase: "write", - fn: function fn() {}, - effect: effect, - data: {} -}; - -var hash$1 = { - left: "right", - right: "left", - bottom: "top", - top: "bottom" -}; - -function getOppositePlacement$1(placement) { - return placement.replace(/left|right|bottom|top/g, (function(matched) { - return hash$1[matched]; - })); -} - -var hash = { - start: "end", - end: "start" -}; - -function getOppositeVariationPlacement(placement) { - return placement.replace(/start|end/g, (function(matched) { - return hash[matched]; - })); -} - -function getWindowScroll(node) { - var win = getWindow$1(node); - var scrollLeft = win.pageXOffset; - var scrollTop = win.pageYOffset; - return { - scrollLeft: scrollLeft, - scrollTop: scrollTop - }; -} - -function getWindowScrollBarX$1(element) { - return getBoundingClientRect$1(getDocumentElement$1(element)).left + getWindowScroll(element).scrollLeft; -} - -function getViewportRect$1(element, strategy) { - var win = getWindow$1(element); - var html = getDocumentElement$1(element); - var visualViewport = win.visualViewport; - var width = html.clientWidth; - var height = html.clientHeight; - var x = 0; - var y = 0; - if (visualViewport) { - width = visualViewport.width; - height = visualViewport.height; - var layoutViewport = isLayoutViewport(); - if (layoutViewport || !layoutViewport && strategy === "fixed") { - x = visualViewport.offsetLeft; - y = visualViewport.offsetTop; - } - } - return { - width: width, - height: height, - x: x + getWindowScrollBarX$1(element), - y: y - }; -} - -function getDocumentRect$1(element) { - var _element$ownerDocumen; - var html = getDocumentElement$1(element); - var winScroll = getWindowScroll(element); - var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body; - var width = max$1(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0); - var height = max$1(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0); - var x = -winScroll.scrollLeft + getWindowScrollBarX$1(element); - var y = -winScroll.scrollTop; - if (getComputedStyle$2(body || html).direction === "rtl") { - x += max$1(html.clientWidth, body ? body.clientWidth : 0) - width; - } - return { - width: width, - height: height, - x: x, - y: y - }; -} - -function isScrollParent(element) { - var _getComputedStyle = getComputedStyle$2(element), overflow = _getComputedStyle.overflow, overflowX = _getComputedStyle.overflowX, overflowY = _getComputedStyle.overflowY; - return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX); -} - -function getScrollParent(node) { - if ([ "html", "body", "#document" ].indexOf(getNodeName$1(node)) >= 0) { - return node.ownerDocument.body; - } - if (isHTMLElement$1(node) && isScrollParent(node)) { - return node; - } - return getScrollParent(getParentNode$1(node)); -} - -function listScrollParents(element, list) { - var _element$ownerDocumen; - if (list === void 0) { - list = []; - } - var scrollParent = getScrollParent(element); - var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body); - var win = getWindow$1(scrollParent); - var target = isBody ? [ win ].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent; - var updatedList = list.concat(target); - return isBody ? updatedList : updatedList.concat(listScrollParents(getParentNode$1(target))); -} - -function rectToClientRect$1(rect) { - return Object.assign({}, rect, { - left: rect.x, - top: rect.y, - right: rect.x + rect.width, - bottom: rect.y + rect.height - }); -} - -function getInnerBoundingClientRect$1(element, strategy) { - var rect = getBoundingClientRect$1(element, false, strategy === "fixed"); - rect.top = rect.top + element.clientTop; - rect.left = rect.left + element.clientLeft; - rect.bottom = rect.top + element.clientHeight; - rect.right = rect.left + element.clientWidth; - rect.width = element.clientWidth; - rect.height = element.clientHeight; - rect.x = rect.left; - rect.y = rect.top; - return rect; -} - -function getClientRectFromMixedType(element, clippingParent, strategy) { - return clippingParent === viewport ? rectToClientRect$1(getViewportRect$1(element, strategy)) : isElement$1(clippingParent) ? getInnerBoundingClientRect$1(clippingParent, strategy) : rectToClientRect$1(getDocumentRect$1(getDocumentElement$1(element))); -} - -function getClippingParents(element) { - var clippingParents = listScrollParents(getParentNode$1(element)); - var canEscapeClipping = [ "absolute", "fixed" ].indexOf(getComputedStyle$2(element).position) >= 0; - var clipperElement = canEscapeClipping && isHTMLElement$1(element) ? getOffsetParent$1(element) : element; - if (!isElement$1(clipperElement)) { - return []; - } - return clippingParents.filter((function(clippingParent) { - return isElement$1(clippingParent) && contains(clippingParent, clipperElement) && getNodeName$1(clippingParent) !== "body"; - })); -} - -function getClippingRect$1(element, boundary, rootBoundary, strategy) { - var mainClippingParents = boundary === "clippingParents" ? getClippingParents(element) : [].concat(boundary); - var clippingParents = [].concat(mainClippingParents, [ rootBoundary ]); - var firstClippingParent = clippingParents[0]; - var clippingRect = clippingParents.reduce((function(accRect, clippingParent) { - var rect = getClientRectFromMixedType(element, clippingParent, strategy); - accRect.top = max$1(rect.top, accRect.top); - accRect.right = min$1(rect.right, accRect.right); - accRect.bottom = min$1(rect.bottom, accRect.bottom); - accRect.left = max$1(rect.left, accRect.left); - return accRect; - }), getClientRectFromMixedType(element, firstClippingParent, strategy)); - clippingRect.width = clippingRect.right - clippingRect.left; - clippingRect.height = clippingRect.bottom - clippingRect.top; - clippingRect.x = clippingRect.left; - clippingRect.y = clippingRect.top; - return clippingRect; -} - -function computeOffsets(_ref) { - var reference = _ref.reference, element = _ref.element, placement = _ref.placement; - var basePlacement = placement ? getBasePlacement(placement) : null; - var variation = placement ? getVariation(placement) : null; - var commonX = reference.x + reference.width / 2 - element.width / 2; - var commonY = reference.y + reference.height / 2 - element.height / 2; - var offsets; - switch (basePlacement) { - case top: - offsets = { - x: commonX, - y: reference.y - element.height - }; - break; - - case bottom: - offsets = { - x: commonX, - y: reference.y + reference.height - }; - break; - - case right: - offsets = { - x: reference.x + reference.width, - y: commonY - }; - break; - - case left: - offsets = { - x: reference.x - element.width, - y: commonY - }; - break; - - default: - offsets = { - x: reference.x, - y: reference.y - }; - } - var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null; - if (mainAxis != null) { - var len = mainAxis === "y" ? "height" : "width"; - switch (variation) { - case start: - offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2); - break; - - case end: - offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2); - break; - } - } - return offsets; -} - -function detectOverflow$1(state, options) { - if (options === void 0) { - options = {}; - } - var _options = options, _options$placement = _options.placement, placement = _options$placement === void 0 ? state.placement : _options$placement, _options$strategy = _options.strategy, strategy = _options$strategy === void 0 ? state.strategy : _options$strategy, _options$boundary = _options.boundary, boundary = _options$boundary === void 0 ? clippingParents : _options$boundary, _options$rootBoundary = _options.rootBoundary, rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary, _options$elementConte = _options.elementContext, elementContext = _options$elementConte === void 0 ? popper : _options$elementConte, _options$altBoundary = _options.altBoundary, altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary, _options$padding = _options.padding, padding = _options$padding === void 0 ? 0 : _options$padding; - var paddingObject = mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements)); - var altContext = elementContext === popper ? reference : popper; - var popperRect = state.rects.popper; - var element = state.elements[altBoundary ? altContext : elementContext]; - var clippingClientRect = getClippingRect$1(isElement$1(element) ? element : element.contextElement || getDocumentElement$1(state.elements.popper), boundary, rootBoundary, strategy); - var referenceClientRect = getBoundingClientRect$1(state.elements.reference); - var popperOffsets = computeOffsets({ - reference: referenceClientRect, - element: popperRect, - strategy: "absolute", - placement: placement - }); - var popperClientRect = rectToClientRect$1(Object.assign({}, popperRect, popperOffsets)); - var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; - var overflowOffsets = { - top: clippingClientRect.top - elementClientRect.top + paddingObject.top, - bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom, - left: clippingClientRect.left - elementClientRect.left + paddingObject.left, - right: elementClientRect.right - clippingClientRect.right + paddingObject.right - }; - var offsetData = state.modifiersData.offset; - if (elementContext === popper && offsetData) { - var offset = offsetData[placement]; - Object.keys(overflowOffsets).forEach((function(key) { - var multiply = [ right, bottom ].indexOf(key) >= 0 ? 1 : -1; - var axis = [ top, bottom ].indexOf(key) >= 0 ? "y" : "x"; - overflowOffsets[key] += offset[axis] * multiply; - })); - } - return overflowOffsets; -} - -function computeAutoPlacement(state, options) { - if (options === void 0) { - options = {}; - } - var _options = options, placement = _options.placement, boundary = _options.boundary, rootBoundary = _options.rootBoundary, padding = _options.padding, flipVariations = _options.flipVariations, _options$allowedAutoP = _options.allowedAutoPlacements, allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP; - var variation = getVariation(placement); - var placements$1 = variation ? flipVariations ? variationPlacements : variationPlacements.filter((function(placement) { - return getVariation(placement) === variation; - })) : basePlacements; - var allowedPlacements = placements$1.filter((function(placement) { - return allowedAutoPlacements.indexOf(placement) >= 0; - })); - if (allowedPlacements.length === 0) { - allowedPlacements = placements$1; - } - var overflows = allowedPlacements.reduce((function(acc, placement) { - acc[placement] = detectOverflow$1(state, { - placement: placement, - boundary: boundary, - rootBoundary: rootBoundary, - padding: padding - })[getBasePlacement(placement)]; - return acc; - }), {}); - return Object.keys(overflows).sort((function(a, b) { - return overflows[a] - overflows[b]; - })); -} - -function getExpandedFallbackPlacements(placement) { - if (getBasePlacement(placement) === auto) { - return []; - } - var oppositePlacement = getOppositePlacement$1(placement); - return [ getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement) ]; -} - -function flip$1(_ref) { - var state = _ref.state, options = _ref.options, name = _ref.name; - if (state.modifiersData[name]._skip) { - return; - } - var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis, specifiedFallbackPlacements = options.fallbackPlacements, padding = options.padding, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, _options$flipVariatio = options.flipVariations, flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio, allowedAutoPlacements = options.allowedAutoPlacements; - var preferredPlacement = state.options.placement; - var basePlacement = getBasePlacement(preferredPlacement); - var isBasePlacement = basePlacement === preferredPlacement; - var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [ getOppositePlacement$1(preferredPlacement) ] : getExpandedFallbackPlacements(preferredPlacement)); - var placements = [ preferredPlacement ].concat(fallbackPlacements).reduce((function(acc, placement) { - return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, { - placement: placement, - boundary: boundary, - rootBoundary: rootBoundary, - padding: padding, - flipVariations: flipVariations, - allowedAutoPlacements: allowedAutoPlacements - }) : placement); - }), []); - var referenceRect = state.rects.reference; - var popperRect = state.rects.popper; - var checksMap = new Map; - var makeFallbackChecks = true; - var firstFittingPlacement = placements[0]; - for (var i = 0; i < placements.length; i++) { - var placement = placements[i]; - var _basePlacement = getBasePlacement(placement); - var isStartVariation = getVariation(placement) === start; - var isVertical = [ top, bottom ].indexOf(_basePlacement) >= 0; - var len = isVertical ? "width" : "height"; - var overflow = detectOverflow$1(state, { - placement: placement, - boundary: boundary, - rootBoundary: rootBoundary, - altBoundary: altBoundary, - padding: padding - }); - var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top; - if (referenceRect[len] > popperRect[len]) { - mainVariationSide = getOppositePlacement$1(mainVariationSide); - } - var altVariationSide = getOppositePlacement$1(mainVariationSide); - var checks = []; - if (checkMainAxis) { - checks.push(overflow[_basePlacement] <= 0); - } - if (checkAltAxis) { - checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0); - } - if (checks.every((function(check) { - return check; - }))) { - firstFittingPlacement = placement; - makeFallbackChecks = false; - break; - } - checksMap.set(placement, checks); - } - if (makeFallbackChecks) { - var numberOfChecks = flipVariations ? 3 : 1; - var _loop = function _loop(_i) { - var fittingPlacement = placements.find((function(placement) { - var checks = checksMap.get(placement); - if (checks) { - return checks.slice(0, _i).every((function(check) { - return check; - })); - } - })); - if (fittingPlacement) { - firstFittingPlacement = fittingPlacement; - return "break"; - } - }; - for (var _i = numberOfChecks; _i > 0; _i--) { - var _ret = _loop(_i); - if (_ret === "break") break; - } - } - if (state.placement !== firstFittingPlacement) { - state.modifiersData[name]._skip = true; - state.placement = firstFittingPlacement; - state.reset = true; - } -} - -var flip$2 = { - name: "flip", - enabled: true, - phase: "main", - fn: flip$1, - requiresIfExists: [ "offset" ], - data: { - _skip: false - } -}; - -function getSideOffsets(overflow, rect, preventedOffsets) { - if (preventedOffsets === void 0) { - preventedOffsets = { - x: 0, - y: 0 - }; - } - return { - top: overflow.top - rect.height - preventedOffsets.y, - right: overflow.right - rect.width + preventedOffsets.x, - bottom: overflow.bottom - rect.height + preventedOffsets.y, - left: overflow.left - rect.width - preventedOffsets.x - }; -} - -function isAnySideFullyClipped(overflow) { - return [ top, right, bottom, left ].some((function(side) { - return overflow[side] >= 0; - })); -} - -function hide(_ref) { - var state = _ref.state, name = _ref.name; - var referenceRect = state.rects.reference; - var popperRect = state.rects.popper; - var preventedOffsets = state.modifiersData.preventOverflow; - var referenceOverflow = detectOverflow$1(state, { - elementContext: "reference" - }); - var popperAltOverflow = detectOverflow$1(state, { - altBoundary: true - }); - var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect); - var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets); - var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets); - var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets); - state.modifiersData[name] = { - referenceClippingOffsets: referenceClippingOffsets, - popperEscapeOffsets: popperEscapeOffsets, - isReferenceHidden: isReferenceHidden, - hasPopperEscaped: hasPopperEscaped - }; - state.attributes.popper = Object.assign({}, state.attributes.popper, { - "data-popper-reference-hidden": isReferenceHidden, - "data-popper-escaped": hasPopperEscaped - }); -} - -var hide$1 = { - name: "hide", - enabled: true, - phase: "main", - requiresIfExists: [ "preventOverflow" ], - fn: hide -}; - -function distanceAndSkiddingToXY(placement, rects, offset) { - var basePlacement = getBasePlacement(placement); - var invertDistance = [ left, top ].indexOf(basePlacement) >= 0 ? -1 : 1; - var _ref = typeof offset === "function" ? offset(Object.assign({}, rects, { - placement: placement - })) : offset, skidding = _ref[0], distance = _ref[1]; - skidding = skidding || 0; - distance = (distance || 0) * invertDistance; - return [ left, right ].indexOf(basePlacement) >= 0 ? { - x: distance, - y: skidding - } : { - x: skidding, - y: distance - }; -} - -function offset$1(_ref2) { - var state = _ref2.state, options = _ref2.options, name = _ref2.name; - var _options$offset = options.offset, offset = _options$offset === void 0 ? [ 0, 0 ] : _options$offset; - var data = placements.reduce((function(acc, placement) { - acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset); - return acc; - }), {}); - var _data$state$placement = data[state.placement], x = _data$state$placement.x, y = _data$state$placement.y; - if (state.modifiersData.popperOffsets != null) { - state.modifiersData.popperOffsets.x += x; - state.modifiersData.popperOffsets.y += y; - } - state.modifiersData[name] = data; -} - -var offset$2 = { - name: "offset", - enabled: true, - phase: "main", - requires: [ "popperOffsets" ], - fn: offset$1 -}; - -function popperOffsets(_ref) { - var state = _ref.state, name = _ref.name; - state.modifiersData[name] = computeOffsets({ - reference: state.rects.reference, - element: state.rects.popper, - strategy: "absolute", - placement: state.placement - }); -} - -var popperOffsets$1 = { - name: "popperOffsets", - enabled: true, - phase: "read", - fn: popperOffsets, - data: {} -}; - -function getAltAxis(axis) { - return axis === "x" ? "y" : "x"; -} - -function preventOverflow(_ref) { - var state = _ref.state, options = _ref.options, name = _ref.name; - var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, padding = options.padding, _options$tether = options.tether, tether = _options$tether === void 0 ? true : _options$tether, _options$tetherOffset = options.tetherOffset, tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset; - var overflow = detectOverflow$1(state, { - boundary: boundary, - rootBoundary: rootBoundary, - padding: padding, - altBoundary: altBoundary - }); - var basePlacement = getBasePlacement(state.placement); - var variation = getVariation(state.placement); - var isBasePlacement = !variation; - var mainAxis = getMainAxisFromPlacement(basePlacement); - var altAxis = getAltAxis(mainAxis); - var popperOffsets = state.modifiersData.popperOffsets; - var referenceRect = state.rects.reference; - var popperRect = state.rects.popper; - var tetherOffsetValue = typeof tetherOffset === "function" ? tetherOffset(Object.assign({}, state.rects, { - placement: state.placement - })) : tetherOffset; - var normalizedTetherOffsetValue = typeof tetherOffsetValue === "number" ? { - mainAxis: tetherOffsetValue, - altAxis: tetherOffsetValue - } : Object.assign({ - mainAxis: 0, - altAxis: 0 - }, tetherOffsetValue); - var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null; - var data = { - x: 0, - y: 0 - }; - if (!popperOffsets) { - return; - } - if (checkMainAxis) { - var _offsetModifierState$; - var mainSide = mainAxis === "y" ? top : left; - var altSide = mainAxis === "y" ? bottom : right; - var len = mainAxis === "y" ? "height" : "width"; - var offset = popperOffsets[mainAxis]; - var min = offset + overflow[mainSide]; - var max = offset - overflow[altSide]; - var additive = tether ? -popperRect[len] / 2 : 0; - var minLen = variation === start ? referenceRect[len] : popperRect[len]; - var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; - var arrowElement = state.elements.arrow; - var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : { - width: 0, - height: 0 - }; - var arrowPaddingObject = state.modifiersData["arrow#persistent"] ? state.modifiersData["arrow#persistent"].padding : getFreshSideObject(); - var arrowPaddingMin = arrowPaddingObject[mainSide]; - var arrowPaddingMax = arrowPaddingObject[altSide]; - var arrowLen = within(0, referenceRect[len], arrowRect[len]); - var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis; - var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis; - var arrowOffsetParent = state.elements.arrow && getOffsetParent$1(state.elements.arrow); - var clientOffset = arrowOffsetParent ? mainAxis === "y" ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0; - var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0; - var tetherMin = offset + minOffset - offsetModifierValue - clientOffset; - var tetherMax = offset + maxOffset - offsetModifierValue; - var preventedOffset = within(tether ? min$1(min, tetherMin) : min, offset, tether ? max$1(max, tetherMax) : max); - popperOffsets[mainAxis] = preventedOffset; - data[mainAxis] = preventedOffset - offset; - } - if (checkAltAxis) { - var _offsetModifierState$2; - var _mainSide = mainAxis === "x" ? top : left; - var _altSide = mainAxis === "x" ? bottom : right; - var _offset = popperOffsets[altAxis]; - var _len = altAxis === "y" ? "height" : "width"; - var _min = _offset + overflow[_mainSide]; - var _max = _offset - overflow[_altSide]; - var isOriginSide = [ top, left ].indexOf(basePlacement) !== -1; - var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0; - var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis; - var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max; - var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max); - popperOffsets[altAxis] = _preventedOffset; - data[altAxis] = _preventedOffset - _offset; - } - state.modifiersData[name] = data; -} - -var preventOverflow$1 = { - name: "preventOverflow", - enabled: true, - phase: "main", - fn: preventOverflow, - requiresIfExists: [ "offset" ] -}; - -function getHTMLElementScroll(element) { - return { - scrollLeft: element.scrollLeft, - scrollTop: element.scrollTop - }; -} - -function getNodeScroll$1(node) { - if (node === getWindow$1(node) || !isHTMLElement$1(node)) { - return getWindowScroll(node); - } else { - return getHTMLElementScroll(node); - } -} - -function isElementScaled(element) { - var rect = element.getBoundingClientRect(); - var scaleX = round$1(rect.width) / element.offsetWidth || 1; - var scaleY = round$1(rect.height) / element.offsetHeight || 1; - return scaleX !== 1 || scaleY !== 1; -} - -function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) { - if (isFixed === void 0) { - isFixed = false; - } - var isOffsetParentAnElement = isHTMLElement$1(offsetParent); - var offsetParentIsScaled = isHTMLElement$1(offsetParent) && isElementScaled(offsetParent); - var documentElement = getDocumentElement$1(offsetParent); - var rect = getBoundingClientRect$1(elementOrVirtualElement, offsetParentIsScaled, isFixed); - var scroll = { - scrollLeft: 0, - scrollTop: 0 - }; - var offsets = { - x: 0, - y: 0 - }; - if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) { - if (getNodeName$1(offsetParent) !== "body" || isScrollParent(documentElement)) { - scroll = getNodeScroll$1(offsetParent); - } - if (isHTMLElement$1(offsetParent)) { - offsets = getBoundingClientRect$1(offsetParent, true); - offsets.x += offsetParent.clientLeft; - offsets.y += offsetParent.clientTop; - } else if (documentElement) { - offsets.x = getWindowScrollBarX$1(documentElement); - } - } - return { - x: rect.left + scroll.scrollLeft - offsets.x, - y: rect.top + scroll.scrollTop - offsets.y, - width: rect.width, - height: rect.height - }; -} - -function order(modifiers) { - var map = new Map; - var visited = new Set; - var result = []; - modifiers.forEach((function(modifier) { - map.set(modifier.name, modifier); - })); - function sort(modifier) { - visited.add(modifier.name); - var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []); - requires.forEach((function(dep) { - if (!visited.has(dep)) { - var depModifier = map.get(dep); - if (depModifier) { - sort(depModifier); - } - } - })); - result.push(modifier); - } - modifiers.forEach((function(modifier) { - if (!visited.has(modifier.name)) { - sort(modifier); - } - })); - return result; -} - -function orderModifiers(modifiers) { - var orderedModifiers = order(modifiers); - return modifierPhases.reduce((function(acc, phase) { - return acc.concat(orderedModifiers.filter((function(modifier) { - return modifier.phase === phase; - }))); - }), []); -} - -function debounce(fn) { - var pending; - return function() { - if (!pending) { - pending = new Promise((function(resolve) { - Promise.resolve().then((function() { - pending = undefined; - resolve(fn()); - })); - })); - } - return pending; - }; -} - -function mergeByName(modifiers) { - var merged = modifiers.reduce((function(merged, current) { - var existing = merged[current.name]; - merged[current.name] = existing ? Object.assign({}, existing, current, { - options: Object.assign({}, existing.options, current.options), - data: Object.assign({}, existing.data, current.data) - }) : current; - return merged; - }), {}); - return Object.keys(merged).map((function(key) { - return merged[key]; - })); -} - -var DEFAULT_OPTIONS = { - placement: "bottom", - modifiers: [], - strategy: "absolute" -}; - -function areValidElements() { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - return !args.some((function(element) { - return !(element && typeof element.getBoundingClientRect === "function"); - })); -} - -function popperGenerator(generatorOptions) { - if (generatorOptions === void 0) { - generatorOptions = {}; - } - var _generatorOptions = generatorOptions, _generatorOptions$def = _generatorOptions.defaultModifiers, defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, _generatorOptions$def2 = _generatorOptions.defaultOptions, defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2; - return function createPopper(reference, popper, options) { - if (options === void 0) { - options = defaultOptions; - } - var state = { - placement: "bottom", - orderedModifiers: [], - options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions), - modifiersData: {}, - elements: { - reference: reference, - popper: popper - }, - attributes: {}, - styles: {} - }; - var effectCleanupFns = []; - var isDestroyed = false; - var instance = { - state: state, - setOptions: function setOptions(setOptionsAction) { - var options = typeof setOptionsAction === "function" ? setOptionsAction(state.options) : setOptionsAction; - cleanupModifierEffects(); - state.options = Object.assign({}, defaultOptions, state.options, options); - state.scrollParents = { - reference: isElement$1(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [], - popper: listScrollParents(popper) - }; - var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); - state.orderedModifiers = orderedModifiers.filter((function(m) { - return m.enabled; - })); - runModifierEffects(); - return instance.update(); - }, - forceUpdate: function forceUpdate() { - if (isDestroyed) { - return; - } - var _state$elements = state.elements, reference = _state$elements.reference, popper = _state$elements.popper; - if (!areValidElements(reference, popper)) { - return; - } - state.rects = { - reference: getCompositeRect(reference, getOffsetParent$1(popper), state.options.strategy === "fixed"), - popper: getLayoutRect(popper) - }; - state.reset = false; - state.placement = state.options.placement; - state.orderedModifiers.forEach((function(modifier) { - return state.modifiersData[modifier.name] = Object.assign({}, modifier.data); - })); - for (var index = 0; index < state.orderedModifiers.length; index++) { - if (state.reset === true) { - state.reset = false; - index = -1; - continue; - } - var _state$orderedModifie = state.orderedModifiers[index], fn = _state$orderedModifie.fn, _state$orderedModifie2 = _state$orderedModifie.options, _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, name = _state$orderedModifie.name; - if (typeof fn === "function") { - state = fn({ - state: state, - options: _options, - name: name, - instance: instance - }) || state; - } - } - }, - update: debounce((function() { - return new Promise((function(resolve) { - instance.forceUpdate(); - resolve(state); - })); - })), - destroy: function destroy() { - cleanupModifierEffects(); - isDestroyed = true; - } - }; - if (!areValidElements(reference, popper)) { - return instance; - } - instance.setOptions(options).then((function(state) { - if (!isDestroyed && options.onFirstUpdate) { - options.onFirstUpdate(state); - } - })); - function runModifierEffects() { - state.orderedModifiers.forEach((function(_ref) { - var name = _ref.name, _ref$options = _ref.options, options = _ref$options === void 0 ? {} : _ref$options, effect = _ref.effect; - if (typeof effect === "function") { - var cleanupFn = effect({ - state: state, - name: name, - instance: instance, - options: options - }); - var noopFn = function noopFn() {}; - effectCleanupFns.push(cleanupFn || noopFn); - } - })); - } - function cleanupModifierEffects() { - effectCleanupFns.forEach((function(fn) { - return fn(); - })); - effectCleanupFns = []; - } - return instance; - }; -} - -var defaultModifiers = [ eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1, offset$2, flip$2, preventOverflow$1, arrow$2, hide$1 ]; - -var createPopper = popperGenerator({ - defaultModifiers: defaultModifiers -}); - -class Popover extends Controller { - static targets=[ "activator", "popover", "template" ]; - static classes=[ "open", "closed" ]; - static values={ - appendToBody: Boolean, - placement: String, - active: Boolean - }; - connect() { - const popperOptions = { - placement: this.placementValue, - modifiers: [ { - name: "offset", - options: { - offset: [ 0, 5 ] - } - }, { - name: "flip", - options: { - allowedAutoPlacements: [ "top-start", "bottom-start", "top-end", "bottom-end" ] - } - } ] - }; - if (this.appendToBodyValue) { - const clonedTemplate = this.templateTarget.content.cloneNode(true); - this.target = clonedTemplate.firstElementChild; - popperOptions["strategy"] = "fixed"; - document.body.appendChild(clonedTemplate); - } - this.popper = createPopper(this.activatorTarget, this.target, popperOptions); - if (this.activeValue) { - this.show(); - } - } - async toggle() { - this.target.classList.toggle(this.closedClass); - this.target.classList.toggle(this.openClass); - await this.popper.update(); - } - async show() { - this.target.classList.remove(this.closedClass); - this.target.classList.add(this.openClass); - await this.popper.update(); - } - hide(event) { - if (this.element.contains(event.target)) return; - if (this.target.classList.contains(this.closedClass)) return; - if (this.appendToBodyValue && this.target.contains(event.target)) return; - this.forceHide(); - } - forceHide() { - this.target.classList.remove(this.openClass); - this.target.classList.add(this.closedClass); - } - get target() { - if (this.hasPopoverTarget) { - return this.popoverTarget; - } else { - return this._target; - } - } - set target(value) { - this._target = value; - } -} - -class ResourceItem extends Controller { - static targets=[ "link" ]; - open(event) { - if (this.hasLinkTarget && this.targetNotClickable(event.target)) { - this.linkTarget.click(); - } - } - targetNotClickable(element) { - return !element.closest("a") && !element.closest("button") && element.nodeName !== "INPUT"; - } -} - -class Scrollable extends Controller { - static targets=[ "topEdge", "bottomEdge" ]; - static classes=[ "topShadow", "bottomShadow" ]; - static values={ - shadow: Boolean - }; - initialize() { - this.topEdgeReached = false; - this.bottomEdgeReached = true; - } - connect() { - if (this.shadowValue) { - this.observer = new IntersectionObserver(this.handleIntersection); - this.observer.observe(this.topEdgeTarget); - this.observer.observe(this.bottomEdgeTarget); - } - } - disconnect() { - if (this.shadowValue) { - this.observer.disconnect(); - } - } - handleIntersection=entries => { - entries.forEach((entry => { - const target = entry.target.dataset.polarisScrollableTarget; - switch (target) { - case "topEdge": - this.topEdgeReached = entry.isIntersecting; - break; - - case "bottomEdge": - this.bottomEdgeReached = entry.isIntersecting; - break; - } - })); - this.updateShadows(); - }; - updateShadows() { - if (!this.topEdgeReached && !this.bottomEdgeReached) { - this.element.classList.add(this.topShadowClass, this.bottomShadowClass); - } else if (this.topEdgeReached && this.bottomEdgeReached) { - this.element.classList.remove(this.topShadowClass, this.bottomShadowClass); - } else if (this.topEdgeReached) { - this.element.classList.remove(this.topShadowClass); - this.element.classList.add(this.bottomShadowClass); - } else if (this.bottomEdgeReached) { - this.element.classList.add(this.topShadowClass); - this.element.classList.remove(this.bottomShadowClass); - } - } -} - -class Select extends Controller { - static targets=[ "select", "selectedOption" ]; - connect() { - this.update(); - } - update() { - const option = this.selectTarget.options[this.selectTarget.selectedIndex]; - this.selectedOptionTarget.innerText = option.text; - } -} - -class TextField extends Controller { - static targets=[ "input", "clearButton", "characterCount" ]; - static classes=[ "hasValue", "clearButtonHidden" ]; - static values={ - value: String, - labelTemplate: String, - textTemplate: String, - step: Number, - min: Number, - max: Number - }; - connect() { - this.syncValue(); - this.stepValue = this.inputTarget.getAttribute("step"); - this.minValue = this.inputTarget.getAttribute("min"); - this.maxValue = this.inputTarget.getAttribute("max"); - } - syncValue() { - this.valueValue = this.inputTarget.value; - } - clear() { - const oldValue = this.value; - this.value = null; - if (this.value != oldValue) { - this.inputTarget.dispatchEvent(new Event("change")); - } - } - increase() { - this.changeNumber(1); - } - decrease() { - this.changeNumber(-1); - } - valueValueChanged() { - this.toggleHasValueClass(); - if (this.hasClearButtonTarget) { - this.toggleClearButton(); - } - if (this.hasCharacterCountTarget) { - this.updateCharacterCount(); - } - } - get value() { - return this.valueValue; - } - set value(newValue) { - this.inputTarget.value = newValue; - this.syncValue(); - } - toggleHasValueClass() { - if (this.value.length > 0) { - this.element.classList.add(this.hasValueClass); - } else { - this.element.classList.remove(this.hasValueClass); - } - } - toggleClearButton() { - if (this.value.length > 0) { - this.clearButtonTarget.classList.remove(this.clearButtonHiddenClass); - this.clearButtonTarget.setAttribute("tab-index", "-"); - } else { - this.clearButtonTarget.classList.add(this.clearButtonHiddenClass); - this.clearButtonTarget.setAttribute("tab-index", "-1"); - } - } - updateCharacterCount() { - this.characterCountTarget.textContent = this.textTemplateValue.replace(`{count}`, this.value.length); - this.characterCountTarget.setAttribute("aria-label", this.labelTemplateValue.replace(`{count}`, this.value.length)); - } - changeNumber(steps) { - const dpl = num => (num.toString().split(".")[1] || []).length; - const numericValue = this.value ? parseFloat(this.value) : 0; - if (isNaN(numericValue)) { - return; - } - const decimalPlaces = Math.max(dpl(numericValue), dpl(this.stepValue)); - const oldValue = this.value; - const newValue = Math.min(Number(this.maxValue), Math.max(numericValue + steps * this.stepValue, Number(this.minValue))); - this.value = String(newValue.toFixed(decimalPlaces)); - if (this.value != oldValue) { - this.inputTarget.dispatchEvent(new Event("change")); - } - } -} - -class Toast extends Controller { - static activeClass="Polaris-Frame-ToastManager--toastWrapperEnterDone"; - static defaultDuration=5e3; - static defaultDurationWithAction=1e4; - static values={ - hidden: Boolean, - duration: Number, - hasAction: Boolean - }; - connect() { - if (!this.hiddenValue) { - this.show(); - } - } - show=() => { - this.element.dataset.position = this.position; - this.element.style.cssText = this.getStyle(this.position); - this.element.classList.add(this.constructor.activeClass); - setTimeout(this.close, this.timeoutDuration); - }; - close=() => { - this.element.classList.remove(this.constructor.activeClass); - this.element.addEventListener("transitionend", this.updatePositions, false); - }; - updatePositions=() => { - this.visibleToasts.sort(((a, b) => parseInt(a.dataset.position) - parseInt(b.dataset.position))).forEach(((toast, index) => { - const position = index + 1; - toast.dataset.position = position; - toast.style.cssText = this.getStyle(position); - })); - this.element.removeEventListener("transitionend", this.updatePositions, false); - }; - getStyle(position) { - const height = this.element.offsetHeight + this.heightOffset; - const translateIn = height * -1; - const translateOut = 150 - height; - return `--pc-toast-manager-translate-y-in: ${translateIn}px; --pc-toast-manager-translate-y-out: ${translateOut}px;`; - } - get timeoutDuration() { - if (this.durationValue > 0) { - return this.durationValue; - } else if (this.hasActionValue) { - return this.constructor.defaultDurationWithAction; - } else { - return this.constructor.defaultDuration; - } - } - get toastManager() { - return this.element.closest(".Polaris-Frame-ToastManager"); - } - get visibleToasts() { - return [ ...this.toastManager.querySelectorAll(`.${this.constructor.activeClass}`) ]; - } - get position() { - return this.visibleToasts.filter((el => !this.element.isEqualNode(el))).length + 1; - } - get heightOffset() { - return this.visibleToasts.filter((el => !this.element.isEqualNode(el) && this.element.dataset.position > el.dataset.position)).map((el => el.offsetHeight)).reduce(((a, b) => a + b), 0); - } -} - -const min = Math.min; - -const max = Math.max; - -const round = Math.round; - -const floor = Math.floor; - -const createCoords = v => ({ - x: v, - y: v -}); - -const oppositeSideMap = { - left: "right", - right: "left", - bottom: "top", - top: "bottom" -}; - -const oppositeAlignmentMap = { - start: "end", - end: "start" -}; - -function clamp(start, value, end) { - return max(start, min(value, end)); -} - -function evaluate(value, param) { - return typeof value === "function" ? value(param) : value; -} - -function getSide(placement) { - return placement.split("-")[0]; -} - -function getAlignment(placement) { - return placement.split("-")[1]; -} - -function getOppositeAxis(axis) { - return axis === "x" ? "y" : "x"; -} - -function getAxisLength(axis) { - return axis === "y" ? "height" : "width"; -} - -function getSideAxis(placement) { - return [ "top", "bottom" ].includes(getSide(placement)) ? "y" : "x"; -} - -function getAlignmentAxis(placement) { - return getOppositeAxis(getSideAxis(placement)); -} - -function getAlignmentSides(placement, rects, rtl) { - if (rtl === void 0) { - rtl = false; - } - const alignment = getAlignment(placement); - const alignmentAxis = getAlignmentAxis(placement); - const length = getAxisLength(alignmentAxis); - let mainAlignmentSide = alignmentAxis === "x" ? alignment === (rtl ? "end" : "start") ? "right" : "left" : alignment === "start" ? "bottom" : "top"; - if (rects.reference[length] > rects.floating[length]) { - mainAlignmentSide = getOppositePlacement(mainAlignmentSide); - } - return [ mainAlignmentSide, getOppositePlacement(mainAlignmentSide) ]; -} - -function getExpandedPlacements(placement) { - const oppositePlacement = getOppositePlacement(placement); - return [ getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement) ]; -} - -function getOppositeAlignmentPlacement(placement) { - return placement.replace(/start|end/g, (alignment => oppositeAlignmentMap[alignment])); -} - -function getSideList(side, isStart, rtl) { - const lr = [ "left", "right" ]; - const rl = [ "right", "left" ]; - const tb = [ "top", "bottom" ]; - const bt = [ "bottom", "top" ]; - switch (side) { - case "top": - case "bottom": - if (rtl) return isStart ? rl : lr; - return isStart ? lr : rl; - - case "left": - case "right": - return isStart ? tb : bt; - - default: - return []; - } -} - -function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) { - const alignment = getAlignment(placement); - let list = getSideList(getSide(placement), direction === "start", rtl); - if (alignment) { - list = list.map((side => side + "-" + alignment)); - if (flipAlignment) { - list = list.concat(list.map(getOppositeAlignmentPlacement)); - } - } - return list; -} - -function getOppositePlacement(placement) { - return placement.replace(/left|right|bottom|top/g, (side => oppositeSideMap[side])); -} - -function expandPaddingObject(padding) { - return { - top: 0, - right: 0, - bottom: 0, - left: 0, - ...padding - }; -} - -function getPaddingObject(padding) { - return typeof padding !== "number" ? expandPaddingObject(padding) : { - top: padding, - right: padding, - bottom: padding, - left: padding - }; -} - -function rectToClientRect(rect) { - return { - ...rect, - top: rect.y, - left: rect.x, - right: rect.x + rect.width, - bottom: rect.y + rect.height - }; -} - -function computeCoordsFromPlacement(_ref, placement, rtl) { - let {reference: reference, floating: floating} = _ref; - const sideAxis = getSideAxis(placement); - const alignmentAxis = getAlignmentAxis(placement); - const alignLength = getAxisLength(alignmentAxis); - const side = getSide(placement); - const isVertical = sideAxis === "y"; - const commonX = reference.x + reference.width / 2 - floating.width / 2; - const commonY = reference.y + reference.height / 2 - floating.height / 2; - const commonAlign = reference[alignLength] / 2 - floating[alignLength] / 2; - let coords; - switch (side) { - case "top": - coords = { - x: commonX, - y: reference.y - floating.height - }; - break; - - case "bottom": - coords = { - x: commonX, - y: reference.y + reference.height - }; - break; - - case "right": - coords = { - x: reference.x + reference.width, - y: commonY - }; - break; - - case "left": - coords = { - x: reference.x - floating.width, - y: commonY - }; - break; - - default: - coords = { - x: reference.x, - y: reference.y - }; - } - switch (getAlignment(placement)) { - case "start": - coords[alignmentAxis] -= commonAlign * (rtl && isVertical ? -1 : 1); - break; - - case "end": - coords[alignmentAxis] += commonAlign * (rtl && isVertical ? -1 : 1); - break; - } - return coords; + case "end": + coords[alignmentAxis] += commonAlign * (rtl && isVertical ? -1 : 1); + break; + } + return coords; } const computePosition$1 = async (reference, floating, config) => { @@ -3422,402 +1696,701 @@ function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) { scrollLeft: 0, scrollTop: 0 }; - let scale = createCoords(1); + let scale = createCoords(1); + const offsets = createCoords(0); + if (isOffsetParentAnElement || !isOffsetParentAnElement && strategy !== "fixed") { + if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) { + scroll = getNodeScroll(offsetParent); + } + if (isHTMLElement(offsetParent)) { + const offsetRect = getBoundingClientRect(offsetParent); + scale = getScale(offsetParent); + offsets.x = offsetRect.x + offsetParent.clientLeft; + offsets.y = offsetRect.y + offsetParent.clientTop; + } + } + return { + width: rect.width * scale.x, + height: rect.height * scale.y, + x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x, + y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + }; +} + +function getClientRects(element) { + return Array.from(element.getClientRects()); +} + +function getWindowScrollBarX(element) { + return getBoundingClientRect(getDocumentElement(element)).left + getNodeScroll(element).scrollLeft; +} + +function getDocumentRect(element) { + const html = getDocumentElement(element); + const scroll = getNodeScroll(element); + const body = element.ownerDocument.body; + const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth); + const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight); + let x = -scroll.scrollLeft + getWindowScrollBarX(element); + const y = -scroll.scrollTop; + if (getComputedStyle$1(body).direction === "rtl") { + x += max(html.clientWidth, body.clientWidth) - width; + } + return { + width: width, + height: height, + x: x, + y: y + }; +} + +function getViewportRect(element, strategy) { + const win = getWindow(element); + const html = getDocumentElement(element); + const visualViewport = win.visualViewport; + let width = html.clientWidth; + let height = html.clientHeight; + let x = 0; + let y = 0; + if (visualViewport) { + width = visualViewport.width; + height = visualViewport.height; + const visualViewportBased = isWebKit(); + if (!visualViewportBased || visualViewportBased && strategy === "fixed") { + x = visualViewport.offsetLeft; + y = visualViewport.offsetTop; + } + } + return { + width: width, + height: height, + x: x, + y: y + }; +} + +function getInnerBoundingClientRect(element, strategy) { + const clientRect = getBoundingClientRect(element, true, strategy === "fixed"); + const top = clientRect.top + element.clientTop; + const left = clientRect.left + element.clientLeft; + const scale = isHTMLElement(element) ? getScale(element) : createCoords(1); + const width = element.clientWidth * scale.x; + const height = element.clientHeight * scale.y; + const x = left * scale.x; + const y = top * scale.y; + return { + width: width, + height: height, + x: x, + y: y + }; +} + +function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) { + let rect; + if (clippingAncestor === "viewport") { + rect = getViewportRect(element, strategy); + } else if (clippingAncestor === "document") { + rect = getDocumentRect(getDocumentElement(element)); + } else if (isElement(clippingAncestor)) { + rect = getInnerBoundingClientRect(clippingAncestor, strategy); + } else { + const visualOffsets = getVisualOffsets(element); + rect = { + ...clippingAncestor, + x: clippingAncestor.x - visualOffsets.x, + y: clippingAncestor.y - visualOffsets.y + }; + } + return rectToClientRect(rect); +} + +function hasFixedPositionAncestor(element, stopNode) { + const parentNode = getParentNode(element); + if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) { + return false; + } + return getComputedStyle$1(parentNode).position === "fixed" || hasFixedPositionAncestor(parentNode, stopNode); +} + +function getClippingElementAncestors(element, cache) { + const cachedResult = cache.get(element); + if (cachedResult) { + return cachedResult; + } + let result = getOverflowAncestors(element, [], false).filter((el => isElement(el) && getNodeName(el) !== "body")); + let currentContainingBlockComputedStyle = null; + const elementIsFixed = getComputedStyle$1(element).position === "fixed"; + let currentNode = elementIsFixed ? getParentNode(element) : element; + while (isElement(currentNode) && !isLastTraversableNode(currentNode)) { + const computedStyle = getComputedStyle$1(currentNode); + const currentNodeIsContaining = isContainingBlock(currentNode); + if (!currentNodeIsContaining && computedStyle.position === "fixed") { + currentContainingBlockComputedStyle = null; + } + const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === "static" && !!currentContainingBlockComputedStyle && [ "absolute", "fixed" ].includes(currentContainingBlockComputedStyle.position) || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode); + if (shouldDropCurrentNode) { + result = result.filter((ancestor => ancestor !== currentNode)); + } else { + currentContainingBlockComputedStyle = computedStyle; + } + currentNode = getParentNode(currentNode); + } + cache.set(element, result); + return result; +} + +function getClippingRect(_ref) { + let {element: element, boundary: boundary, rootBoundary: rootBoundary, strategy: strategy} = _ref; + const elementClippingAncestors = boundary === "clippingAncestors" ? getClippingElementAncestors(element, this._c) : [].concat(boundary); + const clippingAncestors = [ ...elementClippingAncestors, rootBoundary ]; + const firstClippingAncestor = clippingAncestors[0]; + const clippingRect = clippingAncestors.reduce(((accRect, clippingAncestor) => { + const rect = getClientRectFromClippingAncestor(element, clippingAncestor, strategy); + accRect.top = max(rect.top, accRect.top); + accRect.right = min(rect.right, accRect.right); + accRect.bottom = min(rect.bottom, accRect.bottom); + accRect.left = max(rect.left, accRect.left); + return accRect; + }), getClientRectFromClippingAncestor(element, firstClippingAncestor, strategy)); + return { + width: clippingRect.right - clippingRect.left, + height: clippingRect.bottom - clippingRect.top, + x: clippingRect.left, + y: clippingRect.top + }; +} + +function getDimensions(element) { + return getCssDimensions(element); +} + +function getRectRelativeToOffsetParent(element, offsetParent, strategy) { + const isOffsetParentAnElement = isHTMLElement(offsetParent); + const documentElement = getDocumentElement(offsetParent); + const isFixed = strategy === "fixed"; + const rect = getBoundingClientRect(element, true, isFixed, offsetParent); + let scroll = { + scrollLeft: 0, + scrollTop: 0 + }; const offsets = createCoords(0); - if (isOffsetParentAnElement || !isOffsetParentAnElement && strategy !== "fixed") { + if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) { if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) { scroll = getNodeScroll(offsetParent); } - if (isHTMLElement(offsetParent)) { - const offsetRect = getBoundingClientRect(offsetParent); - scale = getScale(offsetParent); + if (isOffsetParentAnElement) { + const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent); offsets.x = offsetRect.x + offsetParent.clientLeft; offsets.y = offsetRect.y + offsetParent.clientTop; + } else if (documentElement) { + offsets.x = getWindowScrollBarX(documentElement); } } return { - width: rect.width * scale.x, - height: rect.height * scale.y, - x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x, - y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + x: rect.left + scroll.scrollLeft - offsets.x, + y: rect.top + scroll.scrollTop - offsets.y, + width: rect.width, + height: rect.height }; } -function getClientRects(element) { - return Array.from(element.getClientRects()); +function getTrueOffsetParent(element, polyfill) { + if (!isHTMLElement(element) || getComputedStyle$1(element).position === "fixed") { + return null; + } + if (polyfill) { + return polyfill(element); + } + return element.offsetParent; } -function getWindowScrollBarX(element) { - return getBoundingClientRect(getDocumentElement(element)).left + getNodeScroll(element).scrollLeft; +function getOffsetParent(element, polyfill) { + const window = getWindow(element); + if (!isHTMLElement(element)) { + return window; + } + let offsetParent = getTrueOffsetParent(element, polyfill); + while (offsetParent && isTableElement(offsetParent) && getComputedStyle$1(offsetParent).position === "static") { + offsetParent = getTrueOffsetParent(offsetParent, polyfill); + } + if (offsetParent && (getNodeName(offsetParent) === "html" || getNodeName(offsetParent) === "body" && getComputedStyle$1(offsetParent).position === "static" && !isContainingBlock(offsetParent))) { + return window; + } + return offsetParent || getContainingBlock(element) || window; } -function getDocumentRect(element) { - const html = getDocumentElement(element); - const scroll = getNodeScroll(element); - const body = element.ownerDocument.body; - const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth); - const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight); - let x = -scroll.scrollLeft + getWindowScrollBarX(element); - const y = -scroll.scrollTop; - if (getComputedStyle$1(body).direction === "rtl") { - x += max(html.clientWidth, body.clientWidth) - width; - } +const getElementRects = async function(_ref) { + let {reference: reference, floating: floating, strategy: strategy} = _ref; + const getOffsetParentFn = this.getOffsetParent || getOffsetParent; + const getDimensionsFn = this.getDimensions; return { - width: width, - height: height, - x: x, - y: y + reference: getRectRelativeToOffsetParent(reference, await getOffsetParentFn(floating), strategy), + floating: { + x: 0, + y: 0, + ...await getDimensionsFn(floating) + } }; +}; + +function isRTL(element) { + return getComputedStyle$1(element).direction === "rtl"; } -function getViewportRect(element, strategy) { - const win = getWindow(element); - const html = getDocumentElement(element); - const visualViewport = win.visualViewport; - let width = html.clientWidth; - let height = html.clientHeight; - let x = 0; - let y = 0; - if (visualViewport) { - width = visualViewport.width; - height = visualViewport.height; - const visualViewportBased = isWebKit(); - if (!visualViewportBased || visualViewportBased && strategy === "fixed") { - x = visualViewport.offsetLeft; - y = visualViewport.offsetTop; +const platform = { + convertOffsetParentRelativeRectToViewportRelativeRect: convertOffsetParentRelativeRectToViewportRelativeRect, + getDocumentElement: getDocumentElement, + getClippingRect: getClippingRect, + getOffsetParent: getOffsetParent, + getElementRects: getElementRects, + getClientRects: getClientRects, + getDimensions: getDimensions, + getScale: getScale, + isElement: isElement, + isRTL: isRTL +}; + +function observeMove(element, onMove) { + let io = null; + let timeoutId; + const root = getDocumentElement(element); + function cleanup() { + clearTimeout(timeoutId); + io && io.disconnect(); + io = null; + } + function refresh(skip, threshold) { + if (skip === void 0) { + skip = false; + } + if (threshold === void 0) { + threshold = 1; + } + cleanup(); + const {left: left, top: top, width: width, height: height} = element.getBoundingClientRect(); + if (!skip) { + onMove(); + } + if (!width || !height) { + return; + } + const insetTop = floor(top); + const insetRight = floor(root.clientWidth - (left + width)); + const insetBottom = floor(root.clientHeight - (top + height)); + const insetLeft = floor(left); + const rootMargin = -insetTop + "px " + -insetRight + "px " + -insetBottom + "px " + -insetLeft + "px"; + const options = { + rootMargin: rootMargin, + threshold: max(0, min(1, threshold)) || 1 + }; + let isFirstUpdate = true; + function handleObserve(entries) { + const ratio = entries[0].intersectionRatio; + if (ratio !== threshold) { + if (!isFirstUpdate) { + return refresh(); + } + if (!ratio) { + timeoutId = setTimeout((() => { + refresh(false, 1e-7); + }), 100); + } else { + refresh(false, ratio); + } + } + isFirstUpdate = false; + } + try { + io = new IntersectionObserver(handleObserve, { + ...options, + root: root.ownerDocument + }); + } catch (e) { + io = new IntersectionObserver(handleObserve, options); } + io.observe(element); } - return { - width: width, - height: height, - x: x, - y: y - }; -} - -function getInnerBoundingClientRect(element, strategy) { - const clientRect = getBoundingClientRect(element, true, strategy === "fixed"); - const top = clientRect.top + element.clientTop; - const left = clientRect.left + element.clientLeft; - const scale = isHTMLElement(element) ? getScale(element) : createCoords(1); - const width = element.clientWidth * scale.x; - const height = element.clientHeight * scale.y; - const x = left * scale.x; - const y = top * scale.y; - return { - width: width, - height: height, - x: x, - y: y - }; + refresh(true); + return cleanup; } -function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) { - let rect; - if (clippingAncestor === "viewport") { - rect = getViewportRect(element, strategy); - } else if (clippingAncestor === "document") { - rect = getDocumentRect(getDocumentElement(element)); - } else if (isElement(clippingAncestor)) { - rect = getInnerBoundingClientRect(clippingAncestor, strategy); - } else { - const visualOffsets = getVisualOffsets(element); - rect = { - ...clippingAncestor, - x: clippingAncestor.x - visualOffsets.x, - y: clippingAncestor.y - visualOffsets.y - }; +function autoUpdate(reference, floating, update, options) { + if (options === void 0) { + options = {}; } - return rectToClientRect(rect); + const {ancestorScroll: ancestorScroll = true, ancestorResize: ancestorResize = true, elementResize: elementResize = typeof ResizeObserver === "function", layoutShift: layoutShift = typeof IntersectionObserver === "function", animationFrame: animationFrame = false} = options; + const referenceEl = unwrapElement(reference); + const ancestors = ancestorScroll || ancestorResize ? [ ...referenceEl ? getOverflowAncestors(referenceEl) : [], ...getOverflowAncestors(floating) ] : []; + ancestors.forEach((ancestor => { + ancestorScroll && ancestor.addEventListener("scroll", update, { + passive: true + }); + ancestorResize && ancestor.addEventListener("resize", update); + })); + const cleanupIo = referenceEl && layoutShift ? observeMove(referenceEl, update) : null; + let reobserveFrame = -1; + let resizeObserver = null; + if (elementResize) { + resizeObserver = new ResizeObserver((_ref => { + let [firstEntry] = _ref; + if (firstEntry && firstEntry.target === referenceEl && resizeObserver) { + resizeObserver.unobserve(floating); + cancelAnimationFrame(reobserveFrame); + reobserveFrame = requestAnimationFrame((() => { + resizeObserver && resizeObserver.observe(floating); + })); + } + update(); + })); + if (referenceEl && !animationFrame) { + resizeObserver.observe(referenceEl); + } + resizeObserver.observe(floating); + } + let frameId; + let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null; + if (animationFrame) { + frameLoop(); + } + function frameLoop() { + const nextRefRect = getBoundingClientRect(reference); + if (prevRefRect && (nextRefRect.x !== prevRefRect.x || nextRefRect.y !== prevRefRect.y || nextRefRect.width !== prevRefRect.width || nextRefRect.height !== prevRefRect.height)) { + update(); + } + prevRefRect = nextRefRect; + frameId = requestAnimationFrame(frameLoop); + } + update(); + return () => { + ancestors.forEach((ancestor => { + ancestorScroll && ancestor.removeEventListener("scroll", update); + ancestorResize && ancestor.removeEventListener("resize", update); + })); + cleanupIo && cleanupIo(); + resizeObserver && resizeObserver.disconnect(); + resizeObserver = null; + if (animationFrame) { + cancelAnimationFrame(frameId); + } + }; } -function hasFixedPositionAncestor(element, stopNode) { - const parentNode = getParentNode(element); - if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) { - return false; - } - return getComputedStyle$1(parentNode).position === "fixed" || hasFixedPositionAncestor(parentNode, stopNode); -} +const computePosition = (reference, floating, options) => { + const cache = new Map; + const mergedOptions = { + platform: platform, + ...options + }; + const platformWithCache = { + ...mergedOptions.platform, + _c: cache + }; + return computePosition$1(reference, floating, { + ...mergedOptions, + platform: platformWithCache + }); +}; -function getClippingElementAncestors(element, cache) { - const cachedResult = cache.get(element); - if (cachedResult) { - return cachedResult; +class Popover extends Controller { + static targets=[ "activator", "popover", "template" ]; + static classes=[ "open", "closed" ]; + static values={ + appendToBody: Boolean, + placement: String, + active: Boolean + }; + connect() { + if (this.appendToBodyValue) { + const clonedTemplate = this.templateTarget.content.cloneNode(true); + this.target = clonedTemplate.firstElementChild; + document.body.appendChild(clonedTemplate); + } + this.target.style.display = "none"; + if (this.activeValue) { + this.show(); + } } - let result = getOverflowAncestors(element, [], false).filter((el => isElement(el) && getNodeName(el) !== "body")); - let currentContainingBlockComputedStyle = null; - const elementIsFixed = getComputedStyle$1(element).position === "fixed"; - let currentNode = elementIsFixed ? getParentNode(element) : element; - while (isElement(currentNode) && !isLastTraversableNode(currentNode)) { - const computedStyle = getComputedStyle$1(currentNode); - const currentNodeIsContaining = isContainingBlock(currentNode); - if (!currentNodeIsContaining && computedStyle.position === "fixed") { - currentContainingBlockComputedStyle = null; + disconnect() { + if (this.cleanup) { + this.cleanup(); } - const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === "static" && !!currentContainingBlockComputedStyle && [ "absolute", "fixed" ].includes(currentContainingBlockComputedStyle.position) || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode); - if (shouldDropCurrentNode) { - result = result.filter((ancestor => ancestor !== currentNode)); + } + updatePosition() { + if (this.cleanup) { + this.cleanup(); + } + this.cleanup = autoUpdate(this.activatorTarget, this.target, (() => { + computePosition(this.activatorTarget, this.target, { + placement: this.placementValue, + middleware: [ offset(5), flip(), shift({ + padding: 5 + }) ] + }).then((({x: x, y: y}) => { + Object.assign(this.target.style, { + left: `${x}px`, + top: `${y}px` + }); + })); + })); + } + toggle() { + if (this.target.classList.contains(this.openClass)) { + this.forceHide(); } else { - currentContainingBlockComputedStyle = computedStyle; + this.show(); } - currentNode = getParentNode(currentNode); } - cache.set(element, result); - return result; -} - -function getClippingRect(_ref) { - let {element: element, boundary: boundary, rootBoundary: rootBoundary, strategy: strategy} = _ref; - const elementClippingAncestors = boundary === "clippingAncestors" ? getClippingElementAncestors(element, this._c) : [].concat(boundary); - const clippingAncestors = [ ...elementClippingAncestors, rootBoundary ]; - const firstClippingAncestor = clippingAncestors[0]; - const clippingRect = clippingAncestors.reduce(((accRect, clippingAncestor) => { - const rect = getClientRectFromClippingAncestor(element, clippingAncestor, strategy); - accRect.top = max(rect.top, accRect.top); - accRect.right = min(rect.right, accRect.right); - accRect.bottom = min(rect.bottom, accRect.bottom); - accRect.left = max(rect.left, accRect.left); - return accRect; - }), getClientRectFromClippingAncestor(element, firstClippingAncestor, strategy)); - return { - width: clippingRect.right - clippingRect.left, - height: clippingRect.bottom - clippingRect.top, - x: clippingRect.left, - y: clippingRect.top - }; + show() { + this.target.style.display = "block"; + this.target.classList.remove(this.closedClass); + this.target.classList.add(this.openClass); + this.updatePosition(); + } + hide(event) { + if (this.element.contains(event.target)) return; + if (this.target.classList.contains(this.closedClass)) return; + if (this.appendToBodyValue && this.target.contains(event.target)) return; + this.forceHide(); + } + forceHide() { + this.target.style.display = "none"; + this.target.classList.remove(this.openClass); + this.target.classList.add(this.closedClass); + } + get target() { + if (this.hasPopoverTarget) { + return this.popoverTarget; + } else { + return this._target; + } + } + set target(value) { + this._target = value; + } } -function getDimensions(element) { - return getCssDimensions(element); +class ResourceItem extends Controller { + static targets=[ "link" ]; + open(event) { + if (this.hasLinkTarget && this.targetNotClickable(event.target)) { + this.linkTarget.click(); + } + } + targetNotClickable(element) { + return !element.closest("a") && !element.closest("button") && element.nodeName !== "INPUT"; + } } -function getRectRelativeToOffsetParent(element, offsetParent, strategy) { - const isOffsetParentAnElement = isHTMLElement(offsetParent); - const documentElement = getDocumentElement(offsetParent); - const isFixed = strategy === "fixed"; - const rect = getBoundingClientRect(element, true, isFixed, offsetParent); - let scroll = { - scrollLeft: 0, - scrollTop: 0 +class Scrollable extends Controller { + static targets=[ "topEdge", "bottomEdge" ]; + static classes=[ "topShadow", "bottomShadow" ]; + static values={ + shadow: Boolean }; - const offsets = createCoords(0); - if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) { - if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) { - scroll = getNodeScroll(offsetParent); + initialize() { + this.topEdgeReached = false; + this.bottomEdgeReached = true; + } + connect() { + if (this.shadowValue) { + this.observer = new IntersectionObserver(this.handleIntersection); + this.observer.observe(this.topEdgeTarget); + this.observer.observe(this.bottomEdgeTarget); } - if (isOffsetParentAnElement) { - const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent); - offsets.x = offsetRect.x + offsetParent.clientLeft; - offsets.y = offsetRect.y + offsetParent.clientTop; - } else if (documentElement) { - offsets.x = getWindowScrollBarX(documentElement); + } + disconnect() { + if (this.shadowValue) { + this.observer.disconnect(); } } - return { - x: rect.left + scroll.scrollLeft - offsets.x, - y: rect.top + scroll.scrollTop - offsets.y, - width: rect.width, - height: rect.height + handleIntersection=entries => { + entries.forEach((entry => { + const target = entry.target.dataset.polarisScrollableTarget; + switch (target) { + case "topEdge": + this.topEdgeReached = entry.isIntersecting; + break; + + case "bottomEdge": + this.bottomEdgeReached = entry.isIntersecting; + break; + } + })); + this.updateShadows(); }; + updateShadows() { + if (!this.topEdgeReached && !this.bottomEdgeReached) { + this.element.classList.add(this.topShadowClass, this.bottomShadowClass); + } else if (this.topEdgeReached && this.bottomEdgeReached) { + this.element.classList.remove(this.topShadowClass, this.bottomShadowClass); + } else if (this.topEdgeReached) { + this.element.classList.remove(this.topShadowClass); + this.element.classList.add(this.bottomShadowClass); + } else if (this.bottomEdgeReached) { + this.element.classList.add(this.topShadowClass); + this.element.classList.remove(this.bottomShadowClass); + } + } } -function getTrueOffsetParent(element, polyfill) { - if (!isHTMLElement(element) || getComputedStyle$1(element).position === "fixed") { - return null; +class Select extends Controller { + static targets=[ "select", "selectedOption" ]; + connect() { + this.update(); } - if (polyfill) { - return polyfill(element); + update() { + const option = this.selectTarget.options[this.selectTarget.selectedIndex]; + this.selectedOptionTarget.innerText = option.text; } - return element.offsetParent; } -function getOffsetParent(element, polyfill) { - const window = getWindow(element); - if (!isHTMLElement(element)) { - return window; - } - let offsetParent = getTrueOffsetParent(element, polyfill); - while (offsetParent && isTableElement(offsetParent) && getComputedStyle$1(offsetParent).position === "static") { - offsetParent = getTrueOffsetParent(offsetParent, polyfill); +class TextField extends Controller { + static targets=[ "input", "clearButton", "characterCount" ]; + static classes=[ "hasValue", "clearButtonHidden" ]; + static values={ + value: String, + labelTemplate: String, + textTemplate: String, + step: Number, + min: Number, + max: Number + }; + connect() { + this.syncValue(); + this.stepValue = this.inputTarget.getAttribute("step"); + this.minValue = this.inputTarget.getAttribute("min"); + this.maxValue = this.inputTarget.getAttribute("max"); } - if (offsetParent && (getNodeName(offsetParent) === "html" || getNodeName(offsetParent) === "body" && getComputedStyle$1(offsetParent).position === "static" && !isContainingBlock(offsetParent))) { - return window; + syncValue() { + this.valueValue = this.inputTarget.value; } - return offsetParent || getContainingBlock(element) || window; -} - -const getElementRects = async function(_ref) { - let {reference: reference, floating: floating, strategy: strategy} = _ref; - const getOffsetParentFn = this.getOffsetParent || getOffsetParent; - const getDimensionsFn = this.getDimensions; - return { - reference: getRectRelativeToOffsetParent(reference, await getOffsetParentFn(floating), strategy), - floating: { - x: 0, - y: 0, - ...await getDimensionsFn(floating) + clear() { + const oldValue = this.value; + this.value = null; + if (this.value != oldValue) { + this.inputTarget.dispatchEvent(new Event("change")); } - }; -}; - -function isRTL(element) { - return getComputedStyle$1(element).direction === "rtl"; -} - -const platform = { - convertOffsetParentRelativeRectToViewportRelativeRect: convertOffsetParentRelativeRectToViewportRelativeRect, - getDocumentElement: getDocumentElement, - getClippingRect: getClippingRect, - getOffsetParent: getOffsetParent, - getElementRects: getElementRects, - getClientRects: getClientRects, - getDimensions: getDimensions, - getScale: getScale, - isElement: isElement, - isRTL: isRTL -}; - -function observeMove(element, onMove) { - let io = null; - let timeoutId; - const root = getDocumentElement(element); - function cleanup() { - clearTimeout(timeoutId); - io && io.disconnect(); - io = null; } - function refresh(skip, threshold) { - if (skip === void 0) { - skip = false; + increase() { + this.changeNumber(1); + } + decrease() { + this.changeNumber(-1); + } + valueValueChanged() { + this.toggleHasValueClass(); + if (this.hasClearButtonTarget) { + this.toggleClearButton(); } - if (threshold === void 0) { - threshold = 1; + if (this.hasCharacterCountTarget) { + this.updateCharacterCount(); } - cleanup(); - const {left: left, top: top, width: width, height: height} = element.getBoundingClientRect(); - if (!skip) { - onMove(); + } + get value() { + return this.valueValue; + } + set value(newValue) { + this.inputTarget.value = newValue; + this.syncValue(); + } + toggleHasValueClass() { + if (this.value.length > 0) { + this.element.classList.add(this.hasValueClass); + } else { + this.element.classList.remove(this.hasValueClass); } - if (!width || !height) { - return; + } + toggleClearButton() { + if (this.value.length > 0) { + this.clearButtonTarget.classList.remove(this.clearButtonHiddenClass); + this.clearButtonTarget.setAttribute("tab-index", "-"); + } else { + this.clearButtonTarget.classList.add(this.clearButtonHiddenClass); + this.clearButtonTarget.setAttribute("tab-index", "-1"); } - const insetTop = floor(top); - const insetRight = floor(root.clientWidth - (left + width)); - const insetBottom = floor(root.clientHeight - (top + height)); - const insetLeft = floor(left); - const rootMargin = -insetTop + "px " + -insetRight + "px " + -insetBottom + "px " + -insetLeft + "px"; - const options = { - rootMargin: rootMargin, - threshold: max(0, min(1, threshold)) || 1 - }; - let isFirstUpdate = true; - function handleObserve(entries) { - const ratio = entries[0].intersectionRatio; - if (ratio !== threshold) { - if (!isFirstUpdate) { - return refresh(); - } - if (!ratio) { - timeoutId = setTimeout((() => { - refresh(false, 1e-7); - }), 100); - } else { - refresh(false, ratio); - } - } - isFirstUpdate = false; + } + updateCharacterCount() { + this.characterCountTarget.textContent = this.textTemplateValue.replace(`{count}`, this.value.length); + this.characterCountTarget.setAttribute("aria-label", this.labelTemplateValue.replace(`{count}`, this.value.length)); + } + changeNumber(steps) { + const dpl = num => (num.toString().split(".")[1] || []).length; + const numericValue = this.value ? parseFloat(this.value) : 0; + if (isNaN(numericValue)) { + return; } - try { - io = new IntersectionObserver(handleObserve, { - ...options, - root: root.ownerDocument - }); - } catch (e) { - io = new IntersectionObserver(handleObserve, options); + const decimalPlaces = Math.max(dpl(numericValue), dpl(this.stepValue)); + const oldValue = this.value; + const newValue = Math.min(Number(this.maxValue), Math.max(numericValue + steps * this.stepValue, Number(this.minValue))); + this.value = String(newValue.toFixed(decimalPlaces)); + if (this.value != oldValue) { + this.inputTarget.dispatchEvent(new Event("change")); } - io.observe(element); } - refresh(true); - return cleanup; } -function autoUpdate(reference, floating, update, options) { - if (options === void 0) { - options = {}; +class Toast extends Controller { + static activeClass="Polaris-Frame-ToastManager--toastWrapperEnterDone"; + static defaultDuration=5e3; + static defaultDurationWithAction=1e4; + static values={ + hidden: Boolean, + duration: Number, + hasAction: Boolean + }; + connect() { + if (!this.hiddenValue) { + this.show(); + } } - const {ancestorScroll: ancestorScroll = true, ancestorResize: ancestorResize = true, elementResize: elementResize = typeof ResizeObserver === "function", layoutShift: layoutShift = typeof IntersectionObserver === "function", animationFrame: animationFrame = false} = options; - const referenceEl = unwrapElement(reference); - const ancestors = ancestorScroll || ancestorResize ? [ ...referenceEl ? getOverflowAncestors(referenceEl) : [], ...getOverflowAncestors(floating) ] : []; - ancestors.forEach((ancestor => { - ancestorScroll && ancestor.addEventListener("scroll", update, { - passive: true - }); - ancestorResize && ancestor.addEventListener("resize", update); - })); - const cleanupIo = referenceEl && layoutShift ? observeMove(referenceEl, update) : null; - let reobserveFrame = -1; - let resizeObserver = null; - if (elementResize) { - resizeObserver = new ResizeObserver((_ref => { - let [firstEntry] = _ref; - if (firstEntry && firstEntry.target === referenceEl && resizeObserver) { - resizeObserver.unobserve(floating); - cancelAnimationFrame(reobserveFrame); - reobserveFrame = requestAnimationFrame((() => { - resizeObserver && resizeObserver.observe(floating); - })); - } - update(); + show=() => { + this.element.dataset.position = this.position; + this.element.style.cssText = this.getStyle(this.position); + this.element.classList.add(this.constructor.activeClass); + setTimeout(this.close, this.timeoutDuration); + }; + close=() => { + this.element.classList.remove(this.constructor.activeClass); + this.element.addEventListener("transitionend", this.updatePositions, false); + }; + updatePositions=() => { + this.visibleToasts.sort(((a, b) => parseInt(a.dataset.position) - parseInt(b.dataset.position))).forEach(((toast, index) => { + const position = index + 1; + toast.dataset.position = position; + toast.style.cssText = this.getStyle(position); })); - if (referenceEl && !animationFrame) { - resizeObserver.observe(referenceEl); + this.element.removeEventListener("transitionend", this.updatePositions, false); + }; + getStyle(position) { + const height = this.element.offsetHeight + this.heightOffset; + const translateIn = height * -1; + const translateOut = 150 - height; + return `--pc-toast-manager-translate-y-in: ${translateIn}px; --pc-toast-manager-translate-y-out: ${translateOut}px;`; + } + get timeoutDuration() { + if (this.durationValue > 0) { + return this.durationValue; + } else if (this.hasActionValue) { + return this.constructor.defaultDurationWithAction; + } else { + return this.constructor.defaultDuration; } - resizeObserver.observe(floating); } - let frameId; - let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null; - if (animationFrame) { - frameLoop(); + get toastManager() { + return this.element.closest(".Polaris-Frame-ToastManager"); } - function frameLoop() { - const nextRefRect = getBoundingClientRect(reference); - if (prevRefRect && (nextRefRect.x !== prevRefRect.x || nextRefRect.y !== prevRefRect.y || nextRefRect.width !== prevRefRect.width || nextRefRect.height !== prevRefRect.height)) { - update(); - } - prevRefRect = nextRefRect; - frameId = requestAnimationFrame(frameLoop); + get visibleToasts() { + return [ ...this.toastManager.querySelectorAll(`.${this.constructor.activeClass}`) ]; + } + get position() { + return this.visibleToasts.filter((el => !this.element.isEqualNode(el))).length + 1; + } + get heightOffset() { + return this.visibleToasts.filter((el => !this.element.isEqualNode(el) && this.element.dataset.position > el.dataset.position)).map((el => el.offsetHeight)).reduce(((a, b) => a + b), 0); } - update(); - return () => { - ancestors.forEach((ancestor => { - ancestorScroll && ancestor.removeEventListener("scroll", update); - ancestorResize && ancestor.removeEventListener("resize", update); - })); - cleanupIo && cleanupIo(); - resizeObserver && resizeObserver.disconnect(); - resizeObserver = null; - if (animationFrame) { - cancelAnimationFrame(frameId); - } - }; } -const computePosition = (reference, floating, options) => { - const cache = new Map; - const mergedOptions = { - platform: platform, - ...options - }; - const platformWithCache = { - ...mergedOptions.platform, - _c: cache - }; - return computePosition$1(reference, floating, { - ...mergedOptions, - platform: platformWithCache - }); -}; - class Tooltip extends Controller { static targets=[ "template" ]; static values={ @@ -3832,34 +2405,32 @@ class Tooltip extends Controller { tooltip.innerHTML = this.templateTarget.innerHTML; this.tooltip = element.appendChild(tooltip); const arrowElement = element.querySelector("[data-tooltip-arrow]"); - autoUpdate(element, this.tooltip, (() => { - computePosition(element, this.tooltip, { - placement: this.positionValue, - middleware: [ offset(this.offsetValue), flip(), shift({ - padding: 5 - }), arrow({ - element: arrowElement - }) ] - }).then((({x: x, y: y, placement: placement, middlewareData: middlewareData}) => { - Object.assign(this.tooltip.style, { - left: `${x}px`, - top: `${y}px` - }); - const {x: arrowX, y: arrowY} = middlewareData.arrow; - const staticSide = { - top: "bottom", - right: "left", - bottom: "top", - left: "right" - }[placement.split("-")[0]]; - Object.assign(arrowElement.style, { - left: arrowX != null ? `${arrowX}px` : "", - top: arrowY != null ? `${arrowY}px` : "", - right: "", - bottom: "", - [staticSide]: "-4px" - }); - })); + computePosition(element, this.tooltip, { + placement: this.positionValue, + middleware: [ offset(this.offsetValue), flip(), shift({ + padding: 5 + }), arrow({ + element: arrowElement + }) ] + }).then((({x: x, y: y, placement: placement, middlewareData: middlewareData}) => { + Object.assign(this.tooltip.style, { + left: `${x}px`, + top: `${y}px` + }); + const {x: arrowX, y: arrowY} = middlewareData.arrow; + const staticSide = { + top: "bottom", + right: "left", + bottom: "top", + left: "right" + }[placement.split("-")[0]]; + Object.assign(arrowElement.style, { + left: arrowX != null ? `${arrowX}px` : "", + top: arrowY != null ? `${arrowY}px` : "", + right: "", + bottom: "", + [staticSide]: "-4px" + }); })); } hide() { diff --git a/app/assets/javascripts/polaris_view_components/popover_controller.js b/app/assets/javascripts/polaris_view_components/popover_controller.js index 06709d42..8bc05378 100644 --- a/app/assets/javascripts/polaris_view_components/popover_controller.js +++ b/app/assets/javascripts/polaris_view_components/popover_controller.js @@ -1,5 +1,5 @@ import { Controller } from "@hotwired/stimulus" -import { createPopper } from "@popperjs/core/dist/esm" +import { computePosition, autoUpdate, offset, flip, shift } from "@floating-ui/dom" export default class extends Controller { static targets = ["activator", "popover", "template"] @@ -11,48 +11,59 @@ export default class extends Controller { } connect() { - const popperOptions = { - placement: this.placementValue, - modifiers: [ - { - name: 'offset', - options: { - offset: [0, 5], - }, - }, - { - name: 'flip', - options: { - allowedAutoPlacements: ['top-start', 'bottom-start', 'top-end', 'bottom-end'] - }, - } - ] - } - if (this.appendToBodyValue) { const clonedTemplate = this.templateTarget.content.cloneNode(true) this.target = clonedTemplate.firstElementChild - popperOptions['strategy'] = 'fixed' - document.body.appendChild(clonedTemplate) } - this.popper = createPopper(this.activatorTarget, this.target, popperOptions) + this.target.style.display = 'none' + if (this.activeValue) { this.show() } } - async toggle() { - this.target.classList.toggle(this.closedClass) - this.target.classList.toggle(this.openClass) - await this.popper.update() + disconnect() { + if (this.cleanup) { + this.cleanup() + } + } + + updatePosition() { + if (this.cleanup) { + this.cleanup() + } + this.cleanup = autoUpdate(this.activatorTarget, this.target, () => { + computePosition(this.activatorTarget, this.target, { + placement: this.placementValue, + middleware: [ + offset(5), + flip(), + shift({ padding: 5 }) + ] + }).then(({x, y}) => { + Object.assign(this.target.style, { + left: `${x}px`, + top: `${y}px`, + }) + }) + }) + } + + toggle() { + if (this.target.classList.contains(this.openClass)) { + this.forceHide() + } else { + this.show() + } } - async show() { + show() { + this.target.style.display = 'block' this.target.classList.remove(this.closedClass) this.target.classList.add(this.openClass) - await this.popper.update() + this.updatePosition() } hide(event) { @@ -64,6 +75,7 @@ export default class extends Controller { } forceHide() { + this.target.style.display = 'none' this.target.classList.remove(this.openClass) this.target.classList.add(this.closedClass) } diff --git a/app/assets/javascripts/polaris_view_components/tooltip_controller.js b/app/assets/javascripts/polaris_view_components/tooltip_controller.js index 37b91a68..c1ef6819 100644 --- a/app/assets/javascripts/polaris_view_components/tooltip_controller.js +++ b/app/assets/javascripts/polaris_view_components/tooltip_controller.js @@ -17,38 +17,36 @@ export default class extends Controller { const arrowElement = element.querySelector("[data-tooltip-arrow]"); - autoUpdate(element, this.tooltip, () => { - computePosition(element, this.tooltip, { - placement: this.positionValue, - middleware: [ - offset(this.offsetValue), - flip(), - shift({ padding: 5 }), - arrow({ element: arrowElement }) - ] - }).then(({x, y, placement, middlewareData}) => { - Object.assign(this.tooltip.style, { - left: `${x}px`, - top: `${y}px`, - }) + computePosition(element, this.tooltip, { + placement: this.positionValue, + middleware: [ + offset(this.offsetValue), + flip(), + shift({ padding: 5 }), + arrow({ element: arrowElement }) + ] + }).then(({x, y, placement, middlewareData}) => { + Object.assign(this.tooltip.style, { + left: `${x}px`, + top: `${y}px`, + }) - const {x: arrowX, y: arrowY} = middlewareData.arrow; + const {x: arrowX, y: arrowY} = middlewareData.arrow; - const staticSide = { - top: 'bottom', - right: 'left', - bottom: 'top', - left: 'right', - }[placement.split('-')[0]]; + const staticSide = { + top: 'bottom', + right: 'left', + bottom: 'top', + left: 'right', + }[placement.split('-')[0]]; - Object.assign(arrowElement.style, { - left: arrowX != null ? `${arrowX}px` : '', - top: arrowY != null ? `${arrowY}px` : '', - right: '', - bottom: '', - [staticSide]: '-4px', - }); - }) + Object.assign(arrowElement.style, { + left: arrowX != null ? `${arrowX}px` : '', + top: arrowY != null ? `${arrowY}px` : '', + right: '', + bottom: '', + [staticSide]: '-4px', + }); }) } diff --git a/app/components/polaris/popover_component.rb b/app/components/polaris/popover_component.rb index b9a9c4cf..1c0fbced 100644 --- a/app/components/polaris/popover_component.rb +++ b/app/components/polaris/popover_component.rb @@ -55,7 +55,7 @@ def wrapper_arguments prepend_option(opts[:data], :controller, "polaris-popover") opts[:data][:polaris_popover_append_to_body_value] = @append_to_body opts[:data][:polaris_popover_active_value] = @active - opts[:data][:polaris_popover_placement_value] = popperjs_placement + opts[:data][:polaris_popover_placement_value] = popover_placement opts[:data][:polaris_popover_open_class] = "Polaris-Popover__PopoverOverlay--open" opts[:data][:polaris_popover_closed_class] = "Polaris-Popover__PopoverOverlay--closed" if @inline @@ -106,13 +106,13 @@ def content_arguments end end - def popperjs_placement + def popover_placement placement = case @position when :above then "top" when :below then "bottom" else - "auto" + "bottom" end placement += "-start" if @alignment == :left placement += "-end" if @alignment == :right diff --git a/demo/app/previews/autocomplete_component_preview.rb b/demo/app/previews/autocomplete_component_preview.rb index 434c5217..f3222630 100644 --- a/demo/app/previews/autocomplete_component_preview.rb +++ b/demo/app/previews/autocomplete_component_preview.rb @@ -19,4 +19,7 @@ def empty_state def event_handler end + + def long_page + end end diff --git a/demo/app/previews/autocomplete_component_preview/long_page.html.erb b/demo/app/previews/autocomplete_component_preview/long_page.html.erb new file mode 100644 index 00000000..09e41e4d --- /dev/null +++ b/demo/app/previews/autocomplete_component_preview/long_page.html.erb @@ -0,0 +1,22 @@ +<% 3.times do %> + <%= polaris_card do %> + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + <% end %> +<% end %> + +<%= polaris_card do %> + <%= polaris_autocomplete do |autocomplete| %> + <% autocomplete.with_text_field(name: :tags, label: "Tags", placeholder: "Search") do |c| %> + <% c.with_prefix do %> + <%= polaris_icon(name: "SearchMinor") %> + <% end %> + <% end %> + + <% autocomplete.with_option(label: "Rustic", value: "rustic") %> + <% autocomplete.with_option(label: "Antique", value: "antique") %> + <% autocomplete.with_option(label: "Vinyl", value: "vinyl") %> + <% autocomplete.with_option(label: "Vintage", value: "vintage") %> + <% autocomplete.with_option(label: "Refurbished", value: "refurbished") %> + <% end %> +<% end %> diff --git a/package.json b/package.json index d9e7f774..8f5fc590 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "release": "npm publish" }, "devDependencies": { - "@popperjs/core": "^2.11.8", + "@floating-ui/dom": "^1.5.3", "@rollup/plugin-node-resolve": "^15.2.1", "@shopify/polaris": "^11.19.0", "postcss": "^8.4.29", @@ -40,7 +40,6 @@ "rollup-plugin-terser": "^7.0.2" }, "dependencies": { - "@floating-ui/dom": "^1.5.3", "@hotwired/stimulus": "^3.2.2", "@rails/request.js": "^0.0.8" } diff --git a/yarn.lock b/yarn.lock index c6d8924e..8bf9533b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -76,11 +76,6 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@popperjs/core@^2.11.8": - version "2.11.8" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" - integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== - "@rails/request.js@^0.0.8": version "0.0.8" resolved "https://registry.yarnpkg.com/@rails/request.js/-/request.js-0.0.8.tgz#5e2e8da15013b1af7f04d759e4e9d1cff981865c"