New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@vaadin-component-factory/vcf-popup

Package Overview
Dependencies
Maintainers
10
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vaadin-component-factory/vcf-popup - npm Package Compare versions

Comparing version 24.0.1 to 24.0.2

7

package.json
{
"name": "@vaadin-component-factory/vcf-popup",
"version": "24.0.1",
"version": "24.0.2",
"description": "Vaadin Component Factory Popup for Polymer 3",

@@ -58,2 +58,7 @@ "main": "theme/lumo/vcf-popup.js",

"@vaadin/button": "^24.0.0",
"@vaadin/radio-group": "^24.0.0",
"@vaadin/checkbox-group": "^24.0.0",
"@vaadin/text-area": "^24.0.0",
"@vaadin/text-field": "^24.0.0",
"@vaadin/time-picker": "^24.0.0",
"@polymer/iron-demo-helpers": "^3.0.0-pre.19",

@@ -60,0 +65,0 @@ "@polymer/test-fixture": "^4.0.2",

@@ -119,2 +119,6 @@ /*

const pointerArrow = document.createElement('div');
pointerArrow.setAttribute('part', 'pointer-arrow');
overlayPart.appendChild(pointerArrow);
const headerContainer = document.createElement('header');

@@ -163,3 +167,28 @@ headerContainer.setAttribute('part', 'header');

footerRenderer: Function
footerRenderer: Function,
/**
* Position of the popup overlay with respect to its target.
* Supported values:
* `bottom` - under the target element
* `end` - in LTR environment to the right of the target element, in RTL environment to the left
*/
preferredPosition: {
type: String,
value: 'bottom',
reflectToAttribute: true,
observer: '__preferredPositionChanged'
},
/**
* Alignment of the popup with respect to its target.
* Supported values:
* `center` - the popup will be aligned to the center of the target element
* By default alignment is not set
*/
preferredAlignment: {
type: String,
reflectToAttribute: true,
observer: '__preferredAlignmentChanged'
}
};

@@ -209,4 +238,20 @@ }

});
this._pointerArrow = this.shadowRoot.querySelector('[part="pointer-arrow"]');
}
__preferredPositionChanged(position) {
if (position === 'bottom') {
this.noHorizontalOverlap = false;
this.noVerticalOverlap = true;
} else if (position === 'end') {
this.noHorizontalOverlap = true;
this.noVerticalOverlap = false;
}
}
__preferredAlignmentChanged() {
this._updatePosition();
}
/** @private */

@@ -395,4 +440,195 @@ __createContainer(slot) {

}
/**
* @protected
* @override
*/
_updatePosition() {
super._updatePosition();
if (!this.positionTarget) {
return;
}
if (this.preferredPosition === 'end' && this.preferredAlignment === 'center') {
this._centerVertically();
}
if (this.hasAttribute('highlight-target')) {
this.highlightTargetInBackdrop();
} else {
this.$.backdrop.style.clipPath = null;
}
if (this._theme && this._theme.includes('pointer-arrow')) {
this._updatePointerArrowPosition();
}
}
highlightTargetInBackdrop() {
const ENLARGE_TARGET_HOLE_BY_PIXELS = 5;
let targetRect = this.positionTarget.getBoundingClientRect();
targetRect = this._addPixelsAroundRect(targetRect, ENLARGE_TARGET_HOLE_BY_PIXELS);
this._makeHoleInBackdrop(targetRect);
this._repositionPopupToPointToBackropHole(ENLARGE_TARGET_HOLE_BY_PIXELS);
}
_repositionPopupToPointToBackropHole(pixelsToMove) {
let pxShift = pixelsToMove;
if (this.preferredPosition === 'end') {
pxShift = -pxShift;
}
if (this.style.bottom) {
this.style.bottom = parseFloat(this.style.bottom) + pxShift + 'px';
}
if (this.style.left) {
this.style.left = parseFloat(this.style.left) - pxShift + 'px';
}
if (this.style.top) {
this.style.top = parseFloat(this.style.top) + pxShift + 'px';
}
if (this.style.right) {
this.style.right = parseFloat(this.style.right) - pxShift + 'px';
}
}
_makeHoleInBackdrop(targetRect) {
const topLeft = targetRect.x + 'px ' + targetRect.y + 'px';
const topRight = targetRect.right + 'px ' + targetRect.y + 'px';
const bottomRight = targetRect.right + 'px ' + targetRect.bottom + 'px';
const bottomLeft = targetRect.x + 'px ' + targetRect.bottom + 'px';
this.$.backdrop.style.clipPath = `polygon(0px 0px,0 100%,100% 100%,100% 0px,0px 0px, ${topLeft}, ${topRight},${bottomRight},${bottomLeft},${topLeft})`;
}
_centerVertically() {
const targetRect = this.positionTarget.getBoundingClientRect();
const offset = targetRect.height / 2 - this._getNormalizedOverlayHeight() / 2;
if (this.style.top) {
const currentValue = parseFloat(this.style.top);
this.style.top = Math.max(currentValue + offset, 15) + 'px';
}
if (this.style.bottom) {
const currentValue = parseFloat(this.style.bottom);
this.style.bottom = Math.max(currentValue + offset, 15) + 'px';
}
}
_updatePointerArrowPosition() {
new PopupPointerArrowPositionUpdater(this).updatePosition();
}
_getNormalizedOverlayHeight() {
// Using previous size to fix a case where window resize may cause the overlay to be squeezed
// smaller than its current space before the fit-calculations. Taken from PositionMixin#__shouldAlignStartHorizontally().
return this.requiredVerticalSpace || Math.max(this.__oldContentHeight || 0, this.$.overlay.offsetHeight);
}
_getNormalizedOverlayWidth() {
// Using previous size to fix a case where window resize may cause the overlay to be squeezed
// smaller than its current space before the fit-calculations. Taken from PositionMixin#__shouldAlignStartVertically().
return Math.max(this.__oldContentWidth || 0, this.$.overlay.offsetWidth);
}
_addPixelsAroundRect(targetRect, pixels) {
targetRect.x = targetRect.x - pixels;
targetRect.y = targetRect.y - pixels;
targetRect.width = targetRect.width + 2 * pixels;
targetRect.height = targetRect.height + 2 * pixels;
return targetRect;
}
}
class PopupPointerArrowPositionUpdater {
constructor(popupOverlay) {
this._pointerArrow = popupOverlay._pointerArrow;
this._preferredPosition = popupOverlay.preferredPosition;
this._isPopupStartAligned = popupOverlay.hasAttribute('start-aligned');
this._isPopupTopAligned = popupOverlay.hasAttribute('top-aligned');
this._targetRect = popupOverlay.positionTarget.getBoundingClientRect();
this._pointerArrowRect = this._pointerArrow.getBoundingClientRect();
this._overlayRect = popupOverlay.$.overlay.getBoundingClientRect();
this._overlayWidth = popupOverlay._getNormalizedOverlayWidth();
this._overlayHeight = popupOverlay._getNormalizedOverlayHeight();
}
updatePosition() {
this._clearPositionProperties();
if (this._preferredPosition === 'bottom') {
this._positionArrowHorizontally();
}
if (this._preferredPosition === 'end') {
this._positionArrowVertically();
}
}
_clearPositionProperties() {
this._pointerArrow.style.top = null;
this._pointerArrow.style.bottom = null;
this._pointerArrow.style.left = null;
this._pointerArrow.style.right = null;
}
_positionArrowHorizontally() {
if (this._isTargetWiderThanOverlay()) {
this._alignToHorizontalCenterOfOverlay();
} else {
this._alignToHorizontalCenterOfTarget();
}
}
_positionArrowVertically() {
if (this._isTargetTallerThanOverlay()) {
this._alignToVerticalCenterOfOverlay();
} else {
this._alignToVerticalCenterOfTarget();
}
}
_isTargetWiderThanOverlay() {
return this._targetRect.width > this._overlayWidth;
}
_isTargetTallerThanOverlay() {
return this._targetRect.height > this._overlayHeight;
}
_alignToHorizontalCenterOfTarget() {
const offset = this._targetRect.width / 2 - this._pointerArrowRect.width / 2;
if (this._isPopupStartAligned) {
this._pointerArrow.style.left = offset + 'px';
} else {
this._pointerArrow.style.right = offset + 'px';
}
}
_alignToHorizontalCenterOfOverlay() {
const offset = this._overlayWidth / 2 - this._pointerArrowRect.width / 2;
this._pointerArrow.style.left = offset + 'px';
}
_alignToVerticalCenterOfOverlay() {
const offset = this._overlayHeight / 2 - this._pointerArrowRect.height / 2;
this._pointerArrow.style.top = offset + 'px';
}
_alignToVerticalCenterOfTarget() {
let offset = this._targetRect.height / 2 - this._pointerArrowRect.height / 2;
if (this._isPopupTopAligned) {
offset = offset + (this._targetRect.y - this._overlayRect.y);
offset = Math.max(offset, 3); // do not display pointer arrow at the very corner of the popup, but slightly below it
this._pointerArrow.style.top = offset + 'px';
} else {
offset = offset + (this._overlayRect.bottom - this._targetRect.bottom);
offset = Math.max(offset, 3); // do not display pointer arrow at the very corner of the popup, but slightly above it
this._pointerArrow.style.bottom = offset + 'px';
}
}
}
customElements.define(PopupOverlayElement.is, PopupOverlayElement);

@@ -38,9 +38,9 @@ /*

theme$="[[theme]]"
with-backdrop="[[_phone]]"
with-backdrop="[[_withBackdrop]]"
phone$="[[_phone]]"
position-target="[[target]]"
no-vertical-overlap
position-target="[[_positionTarget]]"
close-on-scroll="[[closeOnScroll]]"
modeless="[[modeless]]"
focus-trap
focus-trap="[[focusTrap]]"
highlight-target$="[[highlightTarget]]"
restore-focus-on-close

@@ -59,3 +59,3 @@ >

static get version() {
return '24.0.1';
return '24.0.2';
}

@@ -95,2 +95,14 @@

/**
* When set to false (default), the Popup will be shown when the target element (set either by 'for' or 'target' property)
* is clicked. When set to true, you have to open the Popup manually by calling the 'show()' method on the Popup element.
*
* By default, it's set to 'false' for backwards compatibility.
*/
ignoreTargetClick: {
type: Boolean,
value: false,
reflectToAttribute: true
},
closeOnClick: {

@@ -161,2 +173,44 @@ type: Boolean,

/**
* When true the overlay will receive focus when opened and
* the Tab and Shift+Tab keys will cycle through the Popup's
* tabbable elements but will not leave the Popup.
*/
focusTrap: {
type: Boolean,
value: false
},
/**
* Position of the popup with respect to its target.
* Supported values:
* `bottom` - under the target element
* `end` - in LTR environment to the right of the target element, in RTL environment to the left
*/
position: {
type: String,
value: 'bottom',
observer: '__positionChanged'
},
/**
* When true, the popup target will be highlighted, to make it absolutely clear what is the target of the popup.
*/
highlightTarget: {
type: Boolean,
value: false,
reflectToAttribute: true
},
/**
* Alignment of the popup with respect to its target.
* Supported values:
* `center` - the popup will be aligned to the center of the target element
* By default alignment is not set
*/
alignment: {
type: String,
observer: '__alignmentChanged'
},
_phone: Boolean,

@@ -166,3 +220,7 @@

value: '(max-width: 420px), (max-height: 420px)'
}
},
_positionTarget: Object,
_withBackdrop: Boolean
};

@@ -172,3 +230,3 @@ }

static get observers() {
return ['_rendererChanged(headerRenderer, footerRenderer)'];
return ['_rendererChanged(headerRenderer, footerRenderer)', '_backdropDisplayChanged(_phone, highlightTarget)'];
}

@@ -181,2 +239,3 @@

this.hide = this.hide.bind(this);
this.__targetClicked = this.__targetClicked.bind(this);
this._handleOverlayClick = this._handleOverlayClick.bind(this);

@@ -279,2 +338,3 @@

}
__forChanged(forId) {

@@ -292,2 +352,14 @@ if (forId) {

__positionChanged(position) {
this.$.popupOverlay.preferredPosition = position;
}
__alignmentChanged(alignment) {
this.$.popupOverlay.preferredAlignment = alignment;
}
_backdropDisplayChanged(phone, highlightTarget) {
this._withBackdrop = phone || highlightTarget;
}
__targetChanged(target, oldTarget) {

@@ -303,2 +375,8 @@ if (oldTarget) {

__targetClicked() {
if (!this.ignoreTargetClick) {
this.show();
}
}
show() {

@@ -313,3 +391,3 @@ this.opened = true;

_handleOverlayClick(event) {
if (!this.closeOnClick && !this._phone) {
if (!this.closeOnClick && !this._withBackdrop) {
event.stopPropagation();

@@ -321,4 +399,5 @@ }

if (target) {
target.addEventListener('click', this.show);
target.addEventListener('click', this.__targetClicked);
target.setAttribute('has-popup', '');
this.__setPositionTarget(target);

@@ -332,5 +411,16 @@ // Wait before observing to avoid Chrome issue.

__setPositionTarget(target) {
// Make sure that target element is rendered including shadowRoot
setTimeout(() => {
// position the popup relative to the internal input field for Vaadin components
// which have input fields rather than overall copmonents (including label,
// helper texts etc.)
const inputField = target.shadowRoot && target.shadowRoot.querySelector('[part="input-field"]');
this._positionTarget = inputField ? inputField : target;
});
}
_detachFromTarget(target) {
if (target) {
target.removeEventListener('click', this.show);
target.removeEventListener('click', this.__targetClicked);
target.removeAttribute('has-popup');

@@ -337,0 +427,0 @@ this.__targetVisibilityObserver.unobserve(target);

@@ -82,2 +82,6 @@ import '@vaadin/vaadin-lumo-styles/spacing.js';

:host([highlight-target]) [part='backdrop'] {
background-color: var(--lumo-shade-50pct);
}
/* Animations */

@@ -97,4 +101,85 @@

}
/* Pointer arrow theme */
:host([theme~='pointer-arrow'][top-aligned][preferred-position='bottom']:not([phone])) {
padding-top: 0.5rem;
}
:host([theme~='pointer-arrow'][top-aligned][preferred-position='bottom']:not([phone])) [part='pointer-arrow'] {
position: absolute;
border-left: 0.5rem solid transparent;
border-right: 0.5rem solid transparent;
border-bottom: 0.5rem solid var(--lumo-base-color);
top: 0;
height: 0;
width: 0;
filter: drop-shadow(0px -2px 1px var(--lumo-shade-10pct));
}
:host([theme~='pointer-arrow'][bottom-aligned][preferred-position='bottom']:not([phone])) {
padding-bottom: 0.5rem;
}
/* the following will color the pointer arrow to the same color as the popup footer */
:host([theme~='pointer-arrow'][has-footer][bottom-aligned][preferred-position='bottom']:not([phone]))
[part='pointer-arrow']:after {
content: '';
display: block;
position: absolute;
border-left: 0.5rem solid transparent;
border-right: 0.5rem solid transparent;
border-top: 0.5rem solid var(--lumo-contrast-5pct);
bottom: 0;
left: -0.5rem;
height: 0;
width: 0;
}
:host([theme~='pointer-arrow'][bottom-aligned][preferred-position='bottom']:not([phone])) [part='pointer-arrow'] {
position: absolute;
border-left: 0.5rem solid transparent;
border-right: 0.5rem solid transparent;
border-top: 0.5rem solid var(--lumo-base-color);
bottom: 0;
height: 0;
width: 0;
filter: drop-shadow(0px 2px 1px var(--lumo-shade-10pct));
}
:host([theme~='pointer-arrow'][start-aligned][preferred-position='end']:not([phone])) {
padding-inline-start: 0.5rem;
}
:host([theme~='pointer-arrow'][start-aligned][preferred-position='end']:not([phone])) [part='pointer-arrow'] {
position: absolute;
border-top: 0.5rem solid transparent;
border-bottom: 0.5rem solid transparent;
border-right: 0.5rem solid var(--lumo-base-color);
left: 0;
height: 0;
width: 0;
filter: drop-shadow(-2px 0 1px var(--lumo-shade-10pct));
}
:host([theme~='pointer-arrow'][end-aligned][preferred-position='end']:not([phone])) {
padding-inline-end: 0.5rem;
}
:host([theme~='pointer-arrow'][end-aligned][preferred-position='end']:not([phone])) [part='pointer-arrow'] {
position: absolute;
border-top: 0.5rem solid transparent;
border-bottom: 0.5rem solid transparent;
border-left: 0.5rem solid var(--lumo-base-color);
right: 0;
height: 0;
width: 0;
filter: drop-shadow(2px 0 1px var(--lumo-shade-10pct));
}
`;
registerStyles('vcf-popup-overlay', [overlay, popupOverlay], { moduleId: 'lumo-vcf-popup-overlay' });
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc