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
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.2.0] - 2025-01-09

### Added

- possibility to open modal view from your html element with directive ```<p simpleGallery [galleryItems]="galleryItems">Open my gallery</p>```
- list of thumbnails in modal view
- streamlined configuration model (emptyMessage, galleryThumbnailSize, modalStartIndex, showModalThumbnailList)

## [1.1.0] - 2024-11-08

### Added
Expand All @@ -16,7 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- navigation to previous/next images in the showcase view
- navigation to previous/next images in the modal view

## [0.1.0] - 2024-10-30

Expand Down
87 changes: 60 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,22 @@ A simple gallery lib for Angular [18]. It displays all the images as thumbnails
- mobile friendly
- lightweight
- use images from any source
- the gallery takes up as much space as you let it
- two main forms of use: component selector or directive
- navigate forwards/backwards with keyboard arrows or touch/click on arrows in the showcase dialog
- loading spinner while loading
- smooth animation of the next item
- you can define a thumbnail or leave it empty. It is recommended to provide it though, because of performance reasons.

### [**Demo**](https://zolcsi.github.io/ngx-simple-gallery/) | [**Changelog**](https://github.com/zolcsi/ngx-simple-gallery/blob/main/CHANGELOG.md)


## Versioning

| Gallery | Angular | Readme |
|-------------|---------| ------------------------------------------------------------ |
| `^18` | `18+` | here |


## Installation

```sh
Expand All @@ -25,13 +33,6 @@ add the following line to your global styles (by default "styles.(scss|css)") if
@import '@angular/cdk/overlay-prebuilt.css';
```

## Versioning

| Gallery | Angular | Readme |
|-------------|---------| ------------------------------------------------------------ |
| `^18` | `18+` | here |


## Usage

### 1. Import the gallery into your component
Expand All @@ -46,13 +47,14 @@ import { NgxSimpleGalleryComponent } from '@zolcsi/ngx-simple-gallery';
export class AppComponent {}
```

### 2. List the gallery items
### 2. Add the gallery items

```js
import { GalleryItem } from '@zolcsi/ngx-simple-gallery';

@Component({...})
export class AppComponent {

galleryItems: GalleryItem[] = [
{
src: '/img/image1.jpg'
Expand All @@ -64,29 +66,60 @@ export class AppComponent {
}
```

### 3. Render the gallery with the items assembled previously
### 3. You may configure the gallery with custom settings (optional)

```js
import { GalleryItem } from '@zolcsi/ngx-simple-gallery';

@Component({...})
export class AppComponent {

galleryItems: GalleryItem[] = [...];

galleryConfig: GalleryConfig = {
emptyMessage: 'No images found in the galleryItems',
galleryThumbnailSize: 140,
modalStartIndex: 2,
showModalThumbnailList: false
}
}
```

### 4. Render the gallery with the items assembled previously (2 ways)

#### 4a. Using the component selector (this renders the images on the page)
```html
<ngx-simple-gallery [galleryItems]="galleryItems" [galleryConfig]="galleryConfig"></ngx-simple-gallery>
```
or

#### 4b. Using the directive on your own element (this does not render the items on the page, directly opens the modal view)
```html
<ngx-simple-gallery [galleryItems]="galleryItems"></ngx-simple-gallery>
<p simpleGallery [galleryItems]="galleryItems" [galleryConfig]="galleryConfig">My Gallery</p>
```

## Parameters

### Input parameters
## Input parameters

| Name | Required | Type | Default | Description |
|-------------------|----------|---------------|---------------------------------------|----------------------------------------------------|
| emptyMessage | no | string | 'Empty gallery, no images provided.' | Message to show in case empty items provided |
| galleryItems | yes | GalleryItem[] | [ ] | Contains the list of images |
| showThumbnailList | no | boolean | true | Whether to show the thumbnail list in modal view | |
| thumbnailSize | no | number | 160 | The width/height of the thumbnails in px |
| Name | Required | Type | Default | Description |
|----------------|----------|---------------|---------|--------------------------------------|
| galleryItems | yes | GalleryItem[] | [ ] | Contains the list of images |
| galleryConfig | no | GalleryConfig | | Custom configuration for the gallery |

### With all the input parameters set:

```html
<ngx-simple-gallery [galleryItems]="galleryItems"
[showThumbnailList]="false"
[thumbnailSize]="65"
emptyMessage="Please provide some images">
</ngx-simple-gallery>
```
### GalleryItem (represents one single image)

| Name | Required | Type | Default | Description |
|-----------|----------|---------|---------|------------------------------------------------------------------|
| src | yes | string | - | Source of the image |
| thumbnail | no | string | src | Thumbnail of the image. If not provided, the source will be used |


### GalleryConfig (custom configuration for the gallery)

| Name | Required | Type | Default | Description | Applicable |
|------------------------|----------|---------|--------------------------------------|---------------------------------------------------------------------------------|----------------------|
| emptyMessage | no | string | 'Empty gallery, no images provided.' | Message to show in case empty items provided | component, directive |
| galleryThumbnailSize | no | number | 160 | The width/height of the thumbnails in px in the gallery (not in the modal view) | component |
| modalStartIndex | no | number | 0 | The index of the first image to show in the modal view | directive |
| showModalThumbnailList | no | boolean | true | Whether to show the thumbnail list in the modal view | component, directive |
2 changes: 1 addition & 1 deletion jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const config: Config = {
coverageDirectory: 'coverage',

// An array of regexp pattern strings used to skip coverage collection
coveragePathIgnorePatterns: ['/node_modules/', '/dist/', '/model/*', 'public-api.ts'],
coveragePathIgnorePatterns: ['/node_modules/', '/dist/', '/testing/*', 'public-api.ts'],

// Indicates which provider should be used to instrument code for coverage
coverageProvider: 'v8',
Expand Down
2 changes: 1 addition & 1 deletion projects/ngx-simple-gallery/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ngx-simple-gallery",
"version": "1.1.1",
"version": "1.2.0",
"description": "Simple Angular Gallery",
"author": "Zoltan Magyar <[email protected]> (https://github.com/zolcsi)",
"homepage": "https://github.com/zolcsi/ngx-simple-gallery",
Expand Down
5 changes: 3 additions & 2 deletions projects/ngx-simple-gallery/src/lib/core/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export const Constants = {
defaultEmptyMessage: 'Empty gallery, no images provided.',
defaultShowThumbnailList: true,
defaultThumbnailSize: 160,
defaultGalleryThumbnailSize: 160,
defaultModalStartIndex: 0,
defaultShowModalThumbnailList: true,
} as const;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { LibConfig } from './lib-config';

export type GalleryConfig = Partial<LibConfig>
6 changes: 6 additions & 0 deletions projects/ngx-simple-gallery/src/lib/core/model/lib-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface LibConfig {
emptyMessage: string;
galleryThumbnailSize: number;
modalStartIndex: number;
showModalThumbnailList: boolean;
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { TestBed } from '@angular/core/testing';

import { GalleryService } from './gallery.service';
import { GalleryItem } from '../model/gallery-item';
import { GalleryConfig } from '../model/gallery-config';
import { Constants } from '../constants';

const galleryItemsFixture: GalleryItem[] = [
{
Expand All @@ -21,7 +22,7 @@ describe('GalleryService', () => {
service = TestBed.inject(GalleryService);
});

it('should ', () => {
it('the initial items length should be 0', () => {
expect(service.galleryItems().length).toEqual(0);
});

Expand All @@ -35,7 +36,7 @@ describe('GalleryService', () => {
expect(service.getIsLoading()).toBeFalsy();
});

it('testing getIsLoading() default', () => {
it('stopLoading() should top loading indication', () => {
// arrange
service.setItemIndex(1);
expect(service.getIsLoading()).toBeTruthy();
Expand All @@ -56,14 +57,155 @@ describe('GalleryService', () => {
expect(service.getIsLoading()).toBeTruthy();
});

it('should return an empty string, as the index is out of bounds', () => {
it('should return the last item, as the index is out of bounds', () => {
service.setGalleryItems(galleryItemsFixture);
service.setItemIndex(25);
expect(service.imageSource()).toEqual(galleryItemsFixture[1].src);
expect(service.getIsLoading()).toBeTruthy();
});

it('should return the first, as the index is out of bounds in minus', () => {
service.setGalleryItems(galleryItemsFixture);
service.setItemIndex(-1);
expect(service.imageSource()).toEqual(galleryItemsFixture[0].src);
expect(service.getIsLoading()).toBeTruthy();
});

it('should return an empty string, as there are no items', () => {
service.setItemIndex(-1);
expect(service.imageSource()).toEqual('');
expect(service.getIsLoading()).toBeTruthy();
});
});

describe('testing applyGalleryConfig()', () => {

beforeEach(() => {
service.setGalleryItems(galleryItemsFixture);
});

describe('testing emptyMessage config attribute', () => {
it('should be the default when not set', () => {
// assert
expect(service.getLibConfig().emptyMessage).toEqual(Constants.defaultEmptyMessage);
});

it('should set emptyMessage to a new value', () => {
const config: GalleryConfig = { emptyMessage: 'new empty message' };

// act
service.applyGalleryConfig(config);

// assert
expect(service.getLibConfig().emptyMessage).toEqual('new empty message');
});

it('should not set emptyMessage when it is not provided', () => {
const config: GalleryConfig = { };

// act
service.applyGalleryConfig(config);

// assert
expect(service.getLibConfig().emptyMessage).toEqual(Constants.defaultEmptyMessage)
});
});

describe('testing galleryThumbnailSize config attribute', () => {
it('should be the default when not set', () => {
// assert
expect(service.getLibConfig().galleryThumbnailSize).toEqual(Constants.defaultGalleryThumbnailSize);
});

it('should set galleryThumbnailSize to a new value', () => {
const config: GalleryConfig = { galleryThumbnailSize: 123 };

// act
service.applyGalleryConfig(config);

// assert
expect(service.getLibConfig().galleryThumbnailSize).toEqual(123);
});

it('should not set galleryThumbnailSize when it is not provided', () => {
const config: GalleryConfig = { };

// act
service.applyGalleryConfig(config);

// assert
expect(service.getLibConfig().galleryThumbnailSize).toEqual(Constants.defaultGalleryThumbnailSize)
});
});

describe('testing modalStartIndex config attribute', () => {
it('should be the default when not set', () => {
expect(service.getLibConfig().modalStartIndex).toEqual(Constants.defaultModalStartIndex);
expect(service.getItemIndex()).toEqual(Constants.defaultModalStartIndex);
});

it('should set modalStartIndex 1', () => {
const config: GalleryConfig = { modalStartIndex: 1 };

// act
service.applyGalleryConfig(config);

// assert
expect(service.getLibConfig().modalStartIndex).toEqual(1);
expect(service.getItemIndex()).toEqual(1);
});

it('should set startIndex 0', () => {
const config: GalleryConfig = { modalStartIndex: 0 };

// act
service.applyGalleryConfig(config);

// assert
expect(service.getLibConfig().modalStartIndex).toEqual(0);
expect(service.getItemIndex()).toEqual(0);
});

it('should set modalStartIndex -1, but itemIndex is normalized', () => {
const config: GalleryConfig = { modalStartIndex: -1 };

// act
service.applyGalleryConfig(config);

// assert
expect(service.getLibConfig().modalStartIndex).toEqual(-1);
expect(service.getItemIndex()).toEqual(0);
});
});

describe('testing showModalThumbnailList config attribute', () => {
it('should be the default when not set', () => {
// assert
expect(service.getLibConfig().showModalThumbnailList).toEqual(Constants.defaultShowModalThumbnailList);
});

it('should set showModalThumbnailList true', () => {
const config: GalleryConfig = { showModalThumbnailList: true };

// act
service.applyGalleryConfig(config);

// assert
expect(service.getLibConfig().showModalThumbnailList).toBeTruthy();
});

it('should set showModalThumbnailList false', () => {
const config: GalleryConfig = { showModalThumbnailList: false };

// act
service.applyGalleryConfig(config);

// assert
expect(service.getLibConfig().showModalThumbnailList).toBeFalsy();
});
});
});

describe('testing loadNext()', () => {
it('should load the 2. image', () => {
// arrange
Expand Down
Loading
Loading