Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor #12031 - Component: Responsive Overlay #12096

Merged
merged 4 commits into from
Oct 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions src/app/components/api/overlayoptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { AnimationEvent } from '@angular/animations';

export type OverlayModeType = 'modal' | 'overlay' | undefined;

export type ResponsiveOverlayDirectionType = 'start' | 'center' | 'end' | undefined;

export interface OverlayListenerOptions {
type?: 'scroll' | 'outside' | 'resize' | undefined;
mode?: OverlayModeType;
valid?: boolean;
}

export interface ResponsiveOverlayOptions {
style?: any;
styleClass?: string;
breakpoint?: string;
media?: string;
direction?: ResponsiveOverlayDirectionType;
}

export interface OverlayOnShowEvent {
container?: HTMLElement | undefined;
target?: HTMLElement | undefined;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not the same?

target?: HTMLElement;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the container is an 'overlay' element like dropdown's overlay. The target is an element that manages the overlay.
Exp;

container: div.p-overlay.p-component.ng-star-inserted....

target: div.p-dropdown.p-component.p-dropdown-open.p-dropdown-clearable...

The container is an HTML element with a 'p-overlay'(mode: 'overlay') or 'p-overlay-modal'(mode: 'modal') class depending on the mode.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: This line has been updated.

mode?: OverlayModeType;
}

export interface OverlayOnHideEvent extends OverlayOnShowEvent {}

export interface OverlayOptions {
mode?: OverlayModeType;
style?: any;
styleClass?: string;
appendTo?: 'body' | HTMLElement | undefined;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I think you should also add 'self' for type

 appendTo?: 'body' | 'self' | HTMLElement;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this enhancement already exists in our roadmap. We will port a structure like in PrimeReact. https://www.primefaces.org/primereact/setup/

autoZIndex?: boolean;
baseZIndex?: number;
showTransitionOptions?: string;
hideTransitionOptions?: string;
listener?: (event: Event, options?: OverlayListenerOptions) => boolean | void;
responsive?: ResponsiveOverlayOptions | undefined;
onShow?: (event?: OverlayOnShowEvent) => void;
onHide?: (event?: OverlayOnHideEvent) => void;
onAnimationStart?: (event?: AnimationEvent) => void;
onAnimationDone?: (event?: AnimationEvent) => void;
}
12 changes: 7 additions & 5 deletions src/app/components/api/primengconfig.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
import { FilterMatchMode } from './filtermatchmode';
import { OverlayOptions } from './overlayoptions';
import { Translation } from './translation';

interface OverlayOptions {
breakpoint: number;
}

@Injectable({ providedIn: 'root' })
export class PrimeNGConfig {
ripple: boolean = false;

overlayOptions: OverlayOptions;
overlayOptions: OverlayOptions = {
responsive: {
breakpoint: '640px',
direction: 'end'
}
};

filterMatchModeOptions = {
text: [FilterMatchMode.STARTS_WITH, FilterMatchMode.CONTAINS, FilterMatchMode.NOT_CONTAINS, FilterMatchMode.ENDS_WITH, FilterMatchMode.EQUALS, FilterMatchMode.NOT_EQUALS],
Expand Down
15 changes: 8 additions & 7 deletions src/app/components/api/public_api.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
export * from './primengconfig';
export * from './translation';
export * from './translationkeys';
export * from './blockableui';
export * from './confirmation';
export * from './confirmaeventtype';
export * from './confirmation';
export * from './confirmationservice';
export * from './contextmenuservice';
export * from './filtermatchmode';
export * from './filtermetadata';
export * from './filteroperator';
export * from './filterservice';
export * from './contextmenuservice';
export * from './lazyloadevent';
export * from './megamenuitem';
export * from './menuitem';
export * from './message';
export * from './messageservice';
export * from './overlayoptions';
export * from './overlayservice';
export * from './primeicons';
export * from './filtermatchmode';
export * from './filteroperator';
export * from './primengconfig';
export * from './selectitem';
export * from './selectitemgroup';
export * from './shared';
export * from './sortevent';
export * from './sortmeta';
export * from './tablestate';
export * from './translation';
export * from './translationkeys';
export * from './treedragdropservice';
export * from './treenode';
export * from './treenodedragevent';
32 changes: 31 additions & 1 deletion src/app/components/dom/domhandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,24 @@ export class DomHandler {
return -1;
}

public static appendOverlay(overlay: any, target: any, appendTo: any = 'self') {
if (appendTo !== 'self' && overlay && target) {
this.appendChild(overlay, target);
}
}

public static alignOverlay(overlay: any, target: any, appendTo: any = 'self', calculateMinWidth: boolean = true) {
if (overlay && target) {
calculateMinWidth && (overlay.style.minWidth || (overlay.style.minWidth = DomHandler.getOuterWidth(target) + 'px'));

if (appendTo === 'self') {
this.relativePosition(overlay, target);
} else {
this.absolutePosition(overlay, target);
}
}
}

public static relativePosition(element: any, target: any): void {
let elementDimensions = element.offsetParent ? { width: element.offsetWidth, height: element.offsetHeight } : this.getHiddenElementDimensions(element);
const targetHeight = target.offsetHeight;
Expand Down Expand Up @@ -550,7 +568,19 @@ export class DomHandler {
}

public static isHidden(element: HTMLElement): boolean {
return element.offsetParent === null;
return !element || element.offsetParent === null;
}

public static isVisible(element: HTMLElement) {
return element && element.offsetParent != null;
}

public static isExist(element: HTMLElement) {
return element !== null && typeof element !== 'undefined' && element.nodeName && element.parentNode;
}

public static focus(element: HTMLElement, options?: FocusOptions): void {
element && document.activeElement !== element && element.focus(options);
}

public static getFocusableElements(element: HTMLElement) {
Expand Down
12 changes: 1 addition & 11 deletions src/app/components/dropdown/dropdown.css
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,6 @@ input.p-dropdown-label {
cursor: default;
}

.p-dropdown .p-dropdown-panel {
min-width: 100%;
}

.p-dropdown-panel {
position: absolute;
top: 0;
left: 0;
}

.p-dropdown-items-wrapper {
overflow: auto;
}
Expand Down Expand Up @@ -85,4 +75,4 @@ input.p-dropdown-label {

.p-fluid .p-dropdown .p-dropdown-label {
width: 1%;
}
}
Loading