Skip to content

mateuszbilicz/ngx-windows

Repository files navigation

Angular Windows

Angular version: 18.1.0

Previous versions of Angular aren't supported.

License: ISC

Using Angular Windows

Installation

Install ngx-windows: npm i ngx-windows. Edit, build and use in example app: npm run update-ngx-windows.

Add ngx-windows style to your angular.json config file:

"styles": [
  "./node_modules/ngx-windows/ngx-windows-style.css",
  "src/styles.scss"
]

Usage

  1. You should provide NgwWindowsManagerService in app config or if you need multiple instances - in specific component that will contain windows.

  2. Add NgwWindowsContainerComponent to your template

<ngw-windows-container [style]="{width: '100vw', height: '100vh'}"/>

You must set width and height of this container for windows.

Current version uses only window inner width and height.

  1. Creating window

In any component inject NgwWindowsManagerService and use it commands to control, filter and manage windows globally. You must provide class of component that will be displayed inside window. Component should have overflow:auto, width:100% and height:100% for more fail-safe experience. If you want to change window component while window is already active you need to use NgwWindowsManagerService.findFN.component = AnotherComponent.

export class YourComponent {
  constructor(public nwm: NgwWindowsManagerService,
              private destroyRef: DestroyRef) {
    const win = this.nwm.createWindow({
      name: 'Test Window',
      component: TestWindowComponent
    });
    win.onRegister$
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe(service => {
        // Change window properties after it's registered...
      });
    // Don't change window properties through win.service here - explaination in HowItWorks section
  }
}

Your window component must contain windowController input!

  windowController = input.required<NgwWindowControllerService>();

Also, remember to set window placement after register:

constructor(private nwm: NgwWindowsManagerService) {
  const win = this.nwm.createWindow({
    name: 'My Window',
    component: TestCpmComponent
  });

  win.onRegister$
    .pipe(takeUntilDestroyed())
    .subscribe(service => {
      service.placementSvc.setAll(
        800,
        600,
        30,
        30
      );
    });
}

HowItWorks

When you call NgwWindowsManagerService.createWindow function adds default properties, ID and onRegister$ Subject to window object and pushes it to activeWindows. After pushed, it's rendered inside NgwWindowsContainerComponent as NgwWindowComponent that calls NgwWindowsManagerService.register after initialization of its service and self. onRegister$: Subject<NgwWindowControllerService> was called after registration which means that you can use all properties and services inside NgwWindowComponent.

Examples

Simple window

src/app/app.component - creating window after init

src/app/test-app - window contents

Window with close confirmation dialog

src/app/app.component - add button

src/app/close-confirm-dialog-example - primary window with close confirmation checkbox

src/app/close-confirm-dialog - close confirmation dialog that fires close/cancel event to parent

API

NgwWindowsManagerService

Properties
Property Type Description
activeWindows WritableSignal<ActiveNgwWindowProps[]> Full windows list
currentActiveWindow WritableSignal<ActiveNgwWindowProps | undefined> Currently active window object. If all windows are not active then it's undefined.
onPlacementChange$ BehaviorSubject<NgwWindowPlacement | undefined> Window placement information while moving - for preview of window placement while user moves window.

Warning

Functions that update window properties, add window or remove window uses write operations. If you want to use these functions in effect then you need to set effect property {allowWriteSignals: true}.

Functions
Function Arguments Returns Description
createWindow properties: NgwWindowPropsWithoutId, activate?: boolean ActiveNgwWindowProps Creates window instance with all properties. Window is not fully initialized yet.
removeWindow windowId: string void Removes window.
filterWindowsByName nameFilter?: string NgwWindowPropsWithService[] Find windows that name contains specified nameFilter.
getWindowById windowId: string NgwWindowPropsWithService | undefined Get window by its ID. If there's no such window then return undefined.
getOpenWindows none NgwWindowPropsWithService[] Get all not minimized windows.
getMaximizedWindows none NgwWindowPropsWithService[] Get all maximized windows.
getMinimizedWindows none NgwWindowPropsWithService[] Get all minimized windows.
getActiveWindow none NgwWindowPropsWithService | undefined Get current active window or undefined if there's no focused window.
activateWindow windowId: string void Activate (focus) window. If there's focused window then it will be deactivated. If window that you're activating is minimized, then it will open it.
deactivateCurrentActiveWindow none void Deactivate (unfocus) window.
removeAllWindows none void Instantly removes all active window. If some windows has close confirmation, then it will be skipped.
onPlacementPrediction placement?: NgwWindowPlacement void Window calls this function when user moves it and placement prediction is enabled.
registerWindow id: string, service: NgwWindowControllerService void Window calls this function after it's initialized. This function also calls ActiveNgwWindowProps.onRegister$ and completes it.

NgwWindowControllerService

Each window has its own instance of NgwWindowControllerService that can be accessed via NgwWindowsManagerService.createWindow(...).onRegister$ or NgwWindowsManagerService.findFN.service (after initialization). It's also passed to window app component as required input windowController: InputSignal<NgwWindowControllerService>.

Properties
Property Type Description
properties WritableSignal<NgwWindowProps | undefined> Window properties.
onMenu$ Subject<MouseEvent> Menu button click Subject.
onClose$ Subject<MouseEvent> Window Close Subject.
leftControlsTemplate TemplateRef<any> Window topbar left controls template (optional).
rightControlsTemplate TemplateRef<any> Window topbar right controls template (optional).
windowNameTemplate TemplateRef<any> Window topbar name template (optional).
id Signal<string> Read-only window id.
name Signal<string> Read-only window name.
component Signal<string> Read-only window component (app).
data WriteableSignal<any> Read-only window data (any data passed to window via properties).

Warning

Functions that update window properties, add window or remove window uses write operations. If you want to use these functions in effect then you need to set effect property {allowWriteSignals: true}.

Functions
Function Arguments Returns Description
moveWindow x: number, y: number void Moves window with checking max/min position to user viewport. Checks minimized and maximized state, if some of them is true, then cancels execution.
resizeWindow width: number, height: number void Resize window, uses window mix and max size. Cancels if window is minimized or maximized.
doNgwWindowPlacementIfPossible x: number, y: number void Checks possible window placement mode and if it's not "free", then applies this placement to window.
getPlacementMode x: number, y: number WindowPlacementKeyName | undefined Predicts window placement mode or undefined if it's "free".
isOverResizingPoint x: number, y: number boolean Checks distance to window resizing point and returns if mouse cursor is over this point.
minimize none void Sets window minimized state. If current active window is focused (active), then deactivates it.
toggleMaximize none void Toggles window maximized state.
setLocked locked: boolean void Sets window locked state.
close ev: MouseEvent void If window has preventClose option then emits onClose$ Subject, else calls removeWindow.

NgwWindowConfigurationService

Provided in and used by NgwWindowComponent.

Properties
Property Type Description
displayProperties WritableSignal<NgwWindowConfiguration> All window display properties.
displayName Signal<boolean> Display window name in topbar.
showLeftControls Signal<boolean> Show window left controls, by default - menu button.
showRightControls Signal<boolean> Show window right controls, by default - minimize, maximize, close.
showMenuButton Signal<boolean> Show window menu button which emits onMenu$ on click.
maximizable Signal<boolean> Sets if window can be maximized.
minimizable Signal<boolean> Sets if window can be minimized.
closeable Signal<boolean> Sets if window can be closed by user.
preventClose Signal<boolean> Sets close prevention by user. You can use onClose$ to show close confirmation dialog and then use removeWindow.
showTopBar Signal<boolean> Sets if window topbar could be shown. Without it you need to manually manage window state, close and move.
placementDistanceTolerance Signal<boolean> Tolerance of placement prediction & alignment (distance from placement point).
resizeDistanceTolerance Signal<boolean> Distance to window resize point for resize activation (right bottom corner).
allowOutboundMovements Signal<boolean> Sets if window could be moved outside user viewport.
allowPlacementAlignment Signal<boolean> Sets if window could be aligned to placement point.
borderless Signal<boolean> Disables window border.
noShadow Signal<boolean> Disabled window shadow.
transparent Signal<boolean> Sets if window should be transparent.
background Signal<boolean> Sets css window background (if not transparent).
backdropFilter Signal<boolean> Sets css backdrop filter.
moveable Signal<boolean> Sets if window could be moveable.
resizeable Signal<boolean> Sets if window could be resizeable.
Functions
Function Arguments Returns Description
setProperty property: T, value: NgwWindowConfiguration[T] void Sets specific property defined in NgwWindowConfiguration.
setProperties properties: NgwWindowConfiguration void Overrides all window configuration properties.
appendProperties properties: Partial<NgwWindowConfiguration> void Concat new properties with previous.

NgwWindowPlacementService

Provided in and used by NgwWindowComponent.

Properties
Property Type Description
placementMode WritableSignal<WindowPlacementsKeyName | undefined> Current window placement mode.
placementBeforeAuto WritableSignal<NgwWindowPlacement | undefined> Window placement before alignment.
width WritableSignal<number> Window width.
height WritableSignal<number> Window height.
offsetX WritableSignal<number> Window X position.
offsetY WritableSignal<number> Window Y position.
minWidth WritableSignal<number> Window minimum width.
maxWidth WritableSignal<number> Window maximum width.
minHeight WritableSignal<number> Window minimum height.
maxHeight WritableSignal<number> Window maximum height.
Functions
Function Arguments Returns Description
setWH width: number, height: number void Sets window width and height.
setOffset offsetX: number, offsetY: number void Set window XY position.
setAll width: number, height: number, offsetX: number, offsetY: number void Sets all window placement properties.
getPlacementObject none NgwWindowPlacement Current window placement object.

NgwWindowStateService

Provided in and used by NgwWindowComponent.

Properties
Property Type Description
minimized WritableSignal<boolean> Window minimized state signal.
maximized WritableSignal<boolean> Window maximized state signal.
focused WritableSignal<boolean> Window focused state signal.
locked WritableSignal<boolean> Window locked state signal.

Styling

You can create custom scss file with styles and import it in your styles.scss file. Example file can be found in public/custom-window-style.scss file.

Default style:

ngw-window {
  &:not(.transparent) {
    background: #efefef !important;
  }

  &:not(&.borderless) {
    border: solid 1px #373737;
  }

  &:not(&.noshadow) {
    box-shadow: 1px 1px 6px rgba(0, 0, 0, 0.1);
  }

  &.focused:not(&.noshadow) {
    box-shadow: 1px 1px 6px rgba(0, 0, 0, .35),
    1px 1px 4px rgba(0, 0, 0, .2);
  }

  .ngw-window-topbar {
    background: #373737;
    color: #fff;
  }

  ngw-icon:hover {
    background-color: rgba(255, 255, 255, .15);
  }

  .ngw-window-content {
    color: #000;
    padding: 0;
  }
}

ngw-windows-container .ngw-window-placement-prediction.show {
  background-color: rgba(150, 200, 255, .5);
  border: solid 2px rgba(150, 200, 255, .95);
  backdrop-filter: blur(1px);
}

ngw-icon svg path {
  fill: #fff;
  stroke: #fff;
}

Testing

Running tests: npm run test-ngx-windows.

Test coverage
Class Has tests Comments
NgwWindowsManagerService ☑️ Missing tests for onPlacementPrediction and registerWindow
NgwWindowComponent Full
NgwWindowStateService Full
NgwWindowPlacementService Full
NgwWindowControllerService Full
NgwWindowConfigurationService Full
IconComponent Full

TODO

  • Fix ExpressionChangedAfterItHasBeenCheckedError error after window creation