Skip to content
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
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"cSpell.words": [
"WCAG"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,44 @@ By default, `ngx-configurable-layout` always provides minimal styling. Several c
| ngx-layout-item-inactive | A class to style the inactive items used in `editable` layouts. |
| ngx-layout-item-disabled | A class to style the disabled items used in `editable` layouts. |
| ngx-layout-grid-inactive-shown | A class given to the container when the inactive items are being shown. |


## Image marker

The `ngx-image-marker` components provides the ability to visualize and add annotations to an image by using both the [MarkerJs2 and the MarkerLive packages ](https://markerjs.com/).

**Important:** Due to the nature of the package and ZoneJS, some of the features from MarkerJs2 are overwritten with an Angular approach, as they currently do not work with ZoneJS.

### Setup

To setup the `ngx-image-marker`, we simply need to provide an image url to `image` and a description of the image to the `imageDescription` input of the component. From there on out, we can add and visualize annotations to the provided image.

We can switch between edit mode and view mode by using the `canEdit` Input. Simultaneously we can add starter data by providing `startState`.

The `stateUpdated` Output will emit whenever a change has been made to the annotations during edit mode, whilst `markerClicked` will emit whenever a marker is clicked during view mode.

Additionally, we can pass a set of `markerTypes` we want the MarkerJs package to be restricted to. It's important to know that we need to provide markers for both the view and the edit mode, given they both use different packages and interfaces; being `marker-live` and `markerjs2` respectively.

Copy link
Contributor

Choose a reason for hiding this comment

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

Would be nice if a small demo could be provided here

### Future improvements

In the future we aim to make the `ngx-image-marker` work as a `ControlValueAccessor`. Both the current and a form based implementations will be supported initially. At a later date, based on input through a [RFC](https://github.com/studiohyperdrive/hyperdrive-opensource/discussions) we might change that.

### Styling
By default, `ngx-image-marker` always provides minimal styling from the marker packages. These classes have been set by the `ngx-image-marker` component and match with the corresponding classes of the marker package.

We refer to the [styling settings documentation](https://markerjs.com/reference/interfaces/istylesettings.html) for more information regarding these classes.

| Class | |
| -------------------------------------- | ------------------------------------------------------------------- |
| ngx-image-marker-notes-area | notesAreaStyleClassName |
| ngx-image-marker-toolbar | toolbarStyleColorsClassName |
| ngx-image-marker-toolbox | toolboxStyleColorsClassName |
| ngx-image-marker-toolbar-button | toolbarButtonStyleColorsClassName |
| ngx-image-marker-toolbar-button-active | toolbarActiveButtonStyleColorsClassName |
| ngx-image-marker-toolbox-button | toolboxButtonStyleColorsClassName |
| ngx-image-marker-toolbox-button-active | toolboxActiveButtonStyleColorsClassName |

### Accessibility
Currently, both the [MarkerJs2 and the MarkerLive packages ](https://markerjs.com/) do not allow for keyboard interaction. Because of that, it is important to correctly inform users about the WCAG/WAI-ARIA implications.

Efforts are being made to improve the WCAG/WAI-ARIA compliance of the package, but no deadline has been set at the time of writing.
Binary file added apps/layout-test/src/assets/klimmuur.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<ngx-image-marker
image="assets/klimmuur.webp"
imageDescription="Floor-plan of a climbing place"
[canEdit]="allowEdit"
[startState]="currentState"
(stateUpdated)="updateState($event)"
(markerClicked)="markerClicked()"
>
</ngx-image-marker>

<button [disabled]="!allowEdit" (click)="save()">Save</button>
<br />
<button [disabled]="allowEdit" (click)="edit()">Edit</button>
31 changes: 31 additions & 0 deletions apps/layout-test/src/pages/image-marker/image-marker.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgxImageMarkerComponent, NgxImageMarkerState } from '@ngx/layout';

@Component({
selector: 'ngx-image-marker-page',
templateUrl: './image-marker.component.html',
imports: [NgxImageMarkerComponent],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class NgxImageMarkerPageComponent {
public currentState: NgxImageMarkerState;
public newState: NgxImageMarkerState;
public allowEdit: boolean = true;

public save() {
this.currentState = this.newState;
this.allowEdit = false;
}

public edit() {
this.allowEdit = true;
}

public updateState(event: NgxImageMarkerState) {
this.newState = event;
}

public markerClicked() {
window.alert('Clicked!');
}
}
4 changes: 2 additions & 2 deletions apps/layout-test/src/pages/main/main.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component } from '@angular/core';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';

import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { from, map, of, tap } from 'rxjs';
Expand Down Expand Up @@ -30,7 +30,7 @@ import { NgxTourItemDirective, NgxTourService, useMockDataDuringTour } from '@ng
],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MainComponent {
export class MainComponent implements OnInit {
public control: FormControl<NgxConfigurableLayoutGrid> = new FormControl([]);
public isActive: FormControl<boolean> = new FormControl(false);
public dragAndDrop: FormControl<boolean> = new FormControl(true);
Expand Down
4 changes: 2 additions & 2 deletions apps/layout-test/src/pages/secondary/secondary.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { CommonModule } from '@angular/common';
import { NgxTourItemDirective } from '@ngx/tour';
Expand All @@ -8,7 +8,7 @@ import { NgxTourItemDirective } from '@ngx/tour';
templateUrl: './secondary.component.html',
imports: [NgxTourItemDirective, CommonModule],
})
export class SecondaryComponent {
export class SecondaryComponent implements OnInit {
public data$ = new BehaviorSubject(undefined);

ngOnInit() {
Expand Down
7 changes: 7 additions & 0 deletions apps/layout-test/src/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,11 @@ export const routes: Routes = [
loadComponent: () =>
import('./pages/mediaquery/mediaquery.component').then((m) => m.MediaQueryComponent),
},
{
path: 'marker',
loadComponent: () =>
import('./pages/image-marker/image-marker.component').then(
(m) => m.NgxImageMarkerPageComponent
),
},
];
90 changes: 48 additions & 42 deletions libs/angular/layout/package.json
Original file line number Diff line number Diff line change
@@ -1,46 +1,52 @@
{
"name": "@studiohyperdrive/ngx-layout",
"version": "19.0.0",
"description": "A lightweight customizable approach for common and complex layouts in Angular.",
"keywords": [
"angular",
"angular2",
"layout",
"loading",
"error",
"dynamic dashboard",
"dynamic layout",
"visual",
"accordion",
"wcag",
"aria",
"display-content",
"loading",
"error",
"name": "@studiohyperdrive/ngx-layout",
"version": "19.0.0",
"description": "A lightweight customizable approach for common and complex layouts in Angular.",
"keywords": [
"angular",
"angular2",
"layout",
"loading",
"error",
"dynamic dashboard",
"dynamic layout",
"visual",
"accordion",
"wcag",
"aria",
"display-content",
"loading",
"error",
"drag and drop",
"accessible drag and drop",
"drag-and-drop",
"accessible drag-and-drop"
],
"homepage": "https://open-source.studiohyperdrive.be/docs/angular/layout/introduction",
"license": "MIT",
"author": {
"name": "Studio Hyperdrive",
"url": "https://studiohyperdrive.be/"
},
"repository": {
"type": "git",
"url": "https://github.com/studiohyperdrive/hyperdrive-opensource",
"directory": "libs/angular/layout/src"
},
"peerDependencies": {
"@angular/common": "^19.0.0",
"@angular/core": "^19.0.0",
"@angular/forms": "^19.0.0",
"@angular/cdk": "^19.0.0"
},
"dependencies": {
"tslib": "^2.3.0"
},
"sideEffects": false
}
"accessible drag-and-drop",
"markerjs2",
"markerjs-live"
],
"homepage": "https://open-source.studiohyperdrive.be/docs/angular/layout/introduction",
"license": "MIT",
"author": {
"name": "Studio Hyperdrive",
"url": "https://studiohyperdrive.be/"
},
"repository": {
"type": "git",
"url": "https://github.com/studiohyperdrive/hyperdrive-opensource",
"directory": "libs/angular/layout/src"
},
"peerDependencies": {
"@angular/common": "^19.0.0",
"@angular/core": "^19.0.0",
"@angular/forms": "^19.0.0",
"@angular/cdk": "^19.0.0",
"@studiohyperdrive/ngx-core": "^19.1.0",
"markerjs-live": "1.2.1",
"markerjs2": "2.32.3",
"angular2-uuid": "^1.1.1"
},
"dependencies": {
"tslib": "^2.3.0"
},
"sideEffects": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Iben: Add a margin-bottom of 40px so the toolbar is compensated
:host {
display: block;
position: relative;
margin-bottom: 40px;

// Iben: Because of issues with the close and save flow in MarkerJs2 in Angular, we remove the save and close buttons
// Saving goes through the Angular flow
::ng-deep {

[data-action="render"],
[data-action="close"] {
display: none;
}

// Iben: Remove the margin top so the entire image is visible and the toolbox is not visible on top of the image
img {
margin-top: 0 !important;
}

// Iben: Because setting the style classes overwrites the existing style we need to set the color to white
.ngx-image-marker-toolbox-button {
fill: white;
}
}
}
Loading