-
Notifications
You must be signed in to change notification settings - Fork 6.8k
Description
Feature Description
It would be great if the CDK Menu could expose the transform origin as a CSS variable e.g. --cdk-menu-transform-origin: top left
It is currently impossible to make menus built with CDK menu aware of the correct transform origin.
Angular Material Menus sets the transform origin direction as part of their positionStrategy, which is built with withTransformOriginOn.
Angular Material Code
private _getOverlayConfig(menu: MatMenuPanel): OverlayConfig {
return new OverlayConfig({
positionStrategy: createFlexibleConnectedPositionStrategy(
this._injector,
this._getOverlayOrigin(),
)
.withLockedPosition()
.withGrowAfterOpen()
.withTransformOriginOn('.mat-menu-panel, .mat-mdc-menu-panel'),
backdropClass: menu.backdropClass || 'cdk-overlay-transparent-backdrop',
panelClass: menu.overlayPanelClass,
scrollStrategy: this._scrollStrategy(),
direction: this._dir || 'ltr',
disableAnimations: this._animationsDisabled,
});
}| private _getOverlayConfig(menu: MatMenuPanel): OverlayConfig { |
The CDK instead does not allow us to pass a selector, which can be used with withTransformOriginOn.
Angular CDK Code
/** Get the configuration object used to create the overlay. */
private _getOverlayConfig() {
return new OverlayConfig({
positionStrategy: this._getOverlayPositionStrategy(),
scrollStrategy: this.menuScrollStrategy(),
direction: this._directionality || undefined,
});
}
/** Build the position strategy for the overlay which specifies where to place the menu. */
private _getOverlayPositionStrategy(): FlexibleConnectedPositionStrategy {
return createFlexibleConnectedPositionStrategy(this._injector, this._elementRef)
.withLockedPosition()
.withFlexibleDimensions(false)
.withPositions(this._getOverlayPositions());
}
/** Get the preferred positions for the opened menu relative to the menu item. */
private _getOverlayPositions(): ConnectedPosition[] {
return (
this.menuPosition ??
(!this._parentMenu || this._parentMenu.orientation === 'horizontal'
? STANDARD_DROPDOWN_BELOW_POSITIONS
: STANDARD_DROPDOWN_ADJACENT_POSITIONS)
);
}components/src/cdk/menu/menu-trigger.ts
Line 273 in 2c0ba8d
| /** Get the configuration object used to create the overlay. */ |
However I still need to know the exact selector of the element I will use this on.
Building a headless component library I'd much rather be able to access this from a CSS variable.
My current workaround for dialogs is to set it on the .cdk-overlay-pane and then use a renderer call to transform it to a CSS variable.
For Menu's I am simply stuck with guessing a possible transform origin, which does not work well as the position can vary based on how much space is available, e.g. not enough space to the right of my context-menu trigger location and the menu moves to the left, but I cannot react to that.
Use Case
I am building a headless component library: https://github.com/spartan-ng/spartan (currently supporting v20 & v21)
Our menu is built on top of the Angular CDK menu.
This missing feature makes it impossible to build reliably transform origin aware menus.
Example below is our context menu:
As you see the transform origin is using the default center center, which is incorrect as we expect the animation to start on the top right on the first click or the top left on the second.