Right-Side Panel Positioning with UxPortal
How to position a panel/sidebar on the right edge using UxPortal
Right-Side Panel Positioning with UxPortal
Challenge
Position a properties panel on the far right edge of the screen using UxPortalService, maintaining fixed positioning and full viewport height.
Solution: Component-Level Positioning
The UxPortal service's positioning configuration doesn't directly apply styles to the component content. Instead, apply positioning directly to the component's root element.
Implementation
1. Component SCSS (Direct Positioning)
.properties-panel {
position: fixed !important; // Override any portal styles
top: 0 !important;
right: 0 !important; // Pin to right edge
width: 320px;
height: 100vh; // Full viewport height
z-index: 10000; // Above other content
background: rgba(255, 255, 255, 0.98);
backdrop-filter: blur(12px);
border-left: 1px solid rgba(255, 255, 255, 0.5);
box-shadow:
-10px 0 25px rgba(0, 0, 0, 0.15),
-6px 0 12px rgba(0, 0, 0, 0.1);
}
2. Portal Configuration (Minimal)
private openPortal() {
const config: UxPortalConfig = {
id: this.portalId,
reusePortal: true,
content: {
type: 'component',
data: PropertiesPanelContentComponent,
context: { component: this }
},
container: {
mode: 'overlay',
pointerEvents: 'none', // Host doesn't block clicks
closeOnOutsideClick: false,
closeOnEscape: false,
constrainToViewport: false
},
backdrop: {
type: 'none',
enabled: false
},
styling: {
theme: 'custom',
customClass: 'properties-panel-portal-host'
},
animation: {
entrance: 'slide-right',
exit: 'slide-right',
duration: 200
}
};
this.portalService.openPortal(config);
}
3. Prevent Infinite Loop
private isPortalOpen = false;
constructor() {
effect(() => {
const mod = this._module();
if (mod && !this.isPortalOpen) {
this.openPortal();
} else if (!mod && this.isPortalOpen) {
this.closePortal();
}
});
}
private openPortal() {
if (this.isPortalOpen) return;
this.isPortalOpen = true;
// ... open portal
}
private closePortal() {
if (!this.isPortalOpen) return;
this.isPortalOpen = false;
this.portalService.closePortal(this.portalId);
}
Key Takeaways
- Component controls positioning - Use
!importantin component SCSS for fixed positioning - Portal handles rendering - Use portal for overlay management and animations
- Guard against loops - Use flag to prevent repeated open/close calls
- Host transparency - Set
pointerEvents: 'none'on host so only content receives clicks
Result
✅ Panel appears at right edge
✅ Full viewport height
✅ Smooth slide animations
✅ No infinite loop issues
✅ Proper z-index layering