Skip to content

Commit

Permalink
feat: add properties to set popover content width and height (#7442)
Browse files Browse the repository at this point in the history
  • Loading branch information
web-padawan authored May 24, 2024
1 parent 92540a8 commit 66675cc
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 0 deletions.
7 changes: 7 additions & 0 deletions packages/popover/src/vaadin-popover-overlay.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ class PopoverOverlay extends PopoverOverlayMixin(DirMixin(ThemableMixin(PolylitM
return [
overlayStyles,
css`
:host {
--_vaadin-popover-content-width: auto;
--_vaadin-popover-content-height: auto;
}
:host([modeless][with-backdrop]) [part='backdrop'] {
pointer-events: none;
}
Expand All @@ -47,6 +52,8 @@ class PopoverOverlay extends PopoverOverlayMixin(DirMixin(ThemableMixin(PolylitM
[part='content'] {
overflow: auto;
width: var(--_vaadin-popover-content-width);
height: var(--_vaadin-popover-content-height);
}
/* Increase the area of the popover so the pointer can go from the target directly to it. */
Expand Down
14 changes: 14 additions & 0 deletions packages/popover/src/vaadin-popover.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,20 @@ export type PopoverEventMap = HTMLElementEventMap & PopoverCustomEventMap;
declare class Popover extends PopoverPositionMixin(
PopoverTargetMixin(OverlayClassMixin(ThemePropertyMixin(ElementMixin(HTMLElement)))),
) {
/**
* Height to be set on the overlay content.
*
* @attr {string} content-height
*/
contentHeight: string;

/**
* Width to be set on the overlay content.
*
* @attr {string} content-width
*/
contentWidth: string;

/**
* True if the popover overlay is opened, false otherwise.
*/
Expand Down
50 changes: 50 additions & 0 deletions packages/popover/src/vaadin-popover.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ class Popover extends PopoverPositionMixin(

static get properties() {
return {
/**
* Height to be set on the overlay content.
*
* @attr {string} content-height
*/
contentHeight: {
type: String,
},

/**
* Width to be set on the overlay content.
*
* @attr {string} content-width
*/
contentWidth: {
type: String,
},

/**
* True if the popover overlay is opened, false otherwise.
*/
Expand Down Expand Up @@ -138,6 +156,13 @@ class Popover extends PopoverPositionMixin(
};
}

static get observers() {
return [
'__updateContentHeight(contentHeight, _overlayElement)',
'__updateContentWidth(contentWidth, _overlayElement)',
];
}

constructor() {
super();
this.__onGlobalClick = this.__onGlobalClick.bind(this);
Expand Down Expand Up @@ -466,6 +491,31 @@ class Popover extends PopoverPositionMixin(
get __isManual() {
return this.trigger == null || (Array.isArray(this.trigger) && this.trigger.length === 0);
}

/** @private */
__updateDimension(overlay, dimension, value) {
const prop = `--_vaadin-popover-content-${dimension}`;

if (value) {
overlay.style.setProperty(prop, value);
} else {
overlay.style.removeProperty(prop);
}
}

/** @private */
__updateContentHeight(height, overlay) {
if (overlay) {
this.__updateDimension(overlay, 'height', height);
}
}

/** @private */
__updateContentWidth(width, overlay) {
if (overlay) {
this.__updateDimension(overlay, 'width', width);
}
}
}

defineCustomElement(Popover);
Expand Down
50 changes: 50 additions & 0 deletions packages/popover/test/basic.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,4 +289,54 @@ describe('popover', () => {
});
});
});

describe('dimensions', () => {
function getStyleValue(element) {
return element
.getAttribute('style')
.split(':')
.map((str) => str.trim().replace(';', ''));
}

beforeEach(async () => {
popover.opened = true;
await nextRender();
});

it('should update width after opening the popover', async () => {
popover.contentWidth = '300px';
await nextUpdate(popover);
expect(getComputedStyle(overlay.$.content).width).to.be.equal('300px');
});

it('should update height after opening the popover', async () => {
popover.contentHeight = '500px';
await nextUpdate(popover);
expect(getComputedStyle(overlay.$.content).height).to.equal('500px');
});

it('should reset style after setting width to null', async () => {
const prop = '--_vaadin-popover-content-width';

popover.contentWidth = '500px';
await nextUpdate(popover);
expect(getStyleValue(overlay)).to.eql([prop, '500px']);

popover.contentWidth = null;
await nextUpdate(popover);
expect(overlay.getAttribute('style')).to.be.not.ok;
});

it('should reset style after setting height to null', async () => {
const prop = '--_vaadin-popover-content-height';

popover.contentHeight = '500px';
await nextUpdate(popover);
expect(getStyleValue(overlay)).to.eql([prop, '500px']);

popover.contentHeight = null;
await nextUpdate(popover);
expect(overlay.getAttribute('style')).to.be.not.ok;
});
});
});
2 changes: 2 additions & 0 deletions packages/popover/test/typings/popover.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ assertType<HTMLElement | undefined>(popover.target);
assertType<PopoverPosition>(popover.position);
assertType<PopoverRenderer | null | undefined>(popover.renderer);
assertType<PopoverTrigger[] | null | undefined>(popover.trigger);
assertType<string>(popover.contentHeight);
assertType<string>(popover.contentWidth);
assertType<string>(popover.overlayClass);
assertType<boolean>(popover.opened);
assertType<boolean>(popover.modal);
Expand Down

0 comments on commit 66675cc

Please sign in to comment.