Skip to content

Commit

Permalink
feat(slideout-stack): Refactoring the 'push' method. Custom data can …
Browse files Browse the repository at this point in the history
…now be passed to the component.
  • Loading branch information
dmolinet-nexus committed Mar 31, 2024
1 parent 4c7f59a commit 0eab5c0
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 39 deletions.
96 changes: 69 additions & 27 deletions projects/slideout-stack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,71 +30,86 @@ Add the styles in your `angular.json` file:
]
```

## Usage
### Injection

Inject `SlideOutStackController` into your component or service:

```typescript
import { SlideOutStackController } from "@molinet/slideout-stack";

constructor(private slideOutStackController: SlideOutStackController) { }
public constructor(private slideOutStackCtrl: SlideOutStackController) { }
```

## API
## API Reference

### Methods

#### `config(options: SlideOutStackOptions): void`

Configures the global options for the slideouts. When a slideout is pushed without options, the global options will be used.

- `options`: The default [`SlideOutStackOptions`](#slideoutstackoptions) for all the slideouts.
| Parameter | Type | Description |
| -- | -- | -- |
| `options` | [`SlideOutStackOptions`](#slideoutstackoptions) | Default options for all the slideouts. |

#### `push(component: ComponentType<any>, options?: SlideOutStackOptions): SlideOutElement`
#### `push(params: SlideOutStackParams): SlideOutElement`

Pushes and displays a new [`SlideOutElement`](#slideoutelement) to the stack.

The [`SlideOutElement`](#slideoutelement) will be presented with the `options` passed.
Custom data can be passed to the component with the `params.properties` parameter.

The [`SlideOutElement`](#slideoutelement) will be presented with the `params.options` passed.

If an option is not passed, the global option configured with the `config` method will be used.

If no global option is configured, the default option will be used.

- `component`: The component to be presented into the slideout.
- `options` (optional): Options for the slideout.
| Parameter | Type | Description |
| -- | -- | -- |
| `params` | [`SlideOutStackParams`](#slideoutstackparams) | The parameters for the slideout. |

Returns a [`SlideOutElement`](#slideoutelement) representing the pushed slideout.

#### `pop(): void`

Pops the top [`SlideOutElement`](#slideoutelement) from the stack if exists. It will be dismissed with the `options` passed in the `push` method.
Pops the top [`SlideOutElement`](#slideoutelement) from the stack if exists. It will be dismissed with the `params.options` passed in the `push` method.

### Interfaces

#### `SlideOutStackOptions`

Options for the slideout element.
| Property | Type | Description |
| -- | -- | -- |
| `animationDuration` | number | (optional) Duration of the animation in milliseconds. Default is `400`. |
| `backdropDismiss` | boolean | (optional) Indicates whether clicking on the backdrop should dismiss the slideout. Default is `false`. |
| `backdropOpacity` | number | (optional) Opacity of the backdrop between `0` and `1`. Default is `0.3`. Note: backdrop color is black. |
| `fromEdge` | type | (optional) The edge from which the slideout should appear. Possible values are `left` and `right`. Default is `right`. |
| `width` | string | (optional) Width of the top slideout. Default is `80%` of the window total width. It can also be set in pixels (e.g. `250px`). |

- `animationDuration` (optional): Duration of the animation in milliseconds. Default is `400`.
- `backdropDismiss` (optional): Boolean indicating whether clicking on the backdrop should dismiss the slideout. Default is `false`.
- `backdropOpacity` (optional): Opacity of the backdrop. Default is `0.3` (backdrop color is black).
- `fromEdge` (optional): The edge from which the slideout should appear. Default is `right`.
- `width` (optional): Width of the top slideout. Default is `80%` of the window total width. It can also be set in pixels.
#### `SlideOutStackParams`

#### `SlideOutElement`
| Property | Type | Description |
| -- | -- | -- |
| `component` | ComponentType\<any> | The component to be presented into the slideout. |
| `properties` | { [key: string]: any } | (optional) Custom data to pass to the component. |
| `options` | [`SlideOutStackOptions`](#slideoutstackoptions) | (optional) Options for the slideout. |

Represents a slideout element.
#### `SlideOutElement`

- `component`: The component reference of the slideout.
- `onDismissed`: Returns a promise that resolves when the slideout dismisses.
| Property | Type | Description |
| -- | -- | -- |
| `component` | ComponentRef\<any> | The component reference of the slideout. |
| `onDismissed` | Promise\<void> | Returns a promise that resolves when the slideout dismisses. |

## Example

`app-example.component.ts`

```typescript
import { ComponentType } from '@angular/cdk/portal';
import { Component, OnInit } from '@angular/core';

import { SlideOutStackController } from '@molinet/slideout-stack';
import { MyComponent } from './my-component';

@Component({
selector: 'app-example',
Expand All @@ -105,7 +120,7 @@ import { SlideOutStackController } from '@molinet/slideout-stack';
export class ExampleComponent implements OnInit {

public constructor(
private slideOutStackController: SlideOutStackController
private slideOutStackCtrl: SlideOutStackController
) { }

public ngOnInit(): void {
Expand All @@ -118,11 +133,17 @@ export class ExampleComponent implements OnInit {

public pushSlideOut(): void {
// Push a new slideout onto the stack
this.slideOutStackController.push(MyComponent, {
animationDuration: 500, // Will override the global option
backdropOpacity: 0.5,
fromEdge: 'right',
width: '70%'
this.slideOutStackCtrl.push({
component: MyComponent,
properties: {
data: 'Custom data'
},
options: {
animationDuration: 500, // Will override the global option
backdropOpacity: 0.5,
fromEdge: 'right',
width: '70%'
}
}).onDismissed.then(() => {
// Occurs when the component has been popped
console.log('MyComponent dismissed');
Expand All @@ -131,7 +152,28 @@ export class ExampleComponent implements OnInit {

popSlideOut() {
// Pop the top slideout from the stack
this.slideOutStackController.pop();
this.slideOutStackCtrl.pop();
}
}
```

`my-component.component.ts`

```typescript
import { Component, OnInit } from '@angular/core';

@Component({
selector: 'my-component',
template: `
<p>My component works!</p>
`
})
export class MyComponent implements OnInit {

public data!: string;

public ngOnInit(): void {
console.log(this.data); // Outputs 'Custom data'
}
}
```
Expand Down
22 changes: 22 additions & 0 deletions projects/slideout-stack/src/lib/slideout-stack-params.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ComponentType } from "@angular/cdk/portal";

import { SlideOutStackOptions } from "./slideout-stack-options";

/**
* Parameters for a slideout to display in the stack.
* @author molinet
*/
export interface SlideOutStackParams {
/**
* The component to display in the slideout.
*/
component: ComponentType<any>;
/**
* The custom properties to pass to the component.
*/
properties?: { [key: string]: any };
/**
* The options for the slideout.
*/
options?: SlideOutStackOptions;
}
35 changes: 23 additions & 12 deletions projects/slideout-stack/src/lib/slideout-stack.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {

import { SlideOutElement } from "./slideout-element";
import { SlideOutStackOptions } from "./slideout-stack-options";
import { SlideOutStackParams } from "./slideout-stack-params";
import {
DEFAULT_ANIMATION_DURATION,
DEFAULT_BACKDROP_DISMISS,
Expand Down Expand Up @@ -74,28 +75,29 @@ export class SlideOutStackController {
/**
* Pushes and displays a new {@link SlideOutElement `SlideOutElement`} to the stack.
*
* The `SlideOutElement` will be presented with the `options` passed.
* Custom data can be passed to the component with the `params.properties` parameter.
*
* The `SlideOutElement` will be presented with the `params.options` passed.
* If an option is not passed, the global option configured with the {@link config `config`} method will be used.
* If no global option is configured, the default option will be used.
* @param {ComponentType<any>} component The component to be presented into the slideout.
* @param {SlideOutStackOptions} options The options for the slideout.
* @param {SlideOutStackParams} params The parameters for the slideout.
* @returns {SlideOutElement} The `SlideOutElement` pushed to the stack.
*/
public push(component: ComponentType<any>, options?: SlideOutStackOptions): SlideOutElement {
public push(params: SlideOutStackParams): SlideOutElement {
if (!this._domPortalOutlet) this._createDomPortalOutlet();

this._slideOutStack.push({
options: {
animationDuration: options?.animationDuration ?? this._globalOptions.animationDuration,
backdropDismiss: options?.backdropDismiss ?? this._globalOptions.backdropDismiss,
backdropOpacity: options?.backdropOpacity ?? this._globalOptions.backdropOpacity,
fromEdge: options?.fromEdge ?? this._globalOptions.fromEdge,
width: options?.width ?? this._globalOptions.width
animationDuration: params.options?.animationDuration ?? this._globalOptions.animationDuration,
backdropDismiss: params.options?.backdropDismiss ?? this._globalOptions.backdropDismiss,
backdropOpacity: params.options?.backdropOpacity ?? this._globalOptions.backdropOpacity,
fromEdge: params.options?.fromEdge ?? this._globalOptions.fromEdge,
width: params.options?.width ?? this._globalOptions.width
}
});

this._presentBackdrop();
const slideOutElement = this._presentSlideOut(component);
const slideOutElement = this._presentSlideOut(params.component, params.properties);
return slideOutElement;
}

Expand Down Expand Up @@ -166,15 +168,24 @@ export class SlideOutStackController {
}

/**
* Creates, shows and returns a new `SlideOutElement`.
* Shows a new `SlideOutElement`.
* @param {ComponentType<any>} component The component to be presented into the slideout.
* @returns {SlideOutElement} The `SlideOutElement` element.
*/
private _presentSlideOut(component: ComponentType<any>): SlideOutElement {
private _presentSlideOut(
component: ComponentType<any>,
properties?: { [key: string]: any }
): SlideOutElement {
const portal = new ComponentPortal(component);
const componentRef = this._domPortalOutlet!.attachComponentPortal(portal);
componentRef.location.nativeElement.classList.add("slideout");

if (properties) {
Object.keys(properties).forEach((key: string) => {
componentRef.instance[key] = properties[key];
});
}

const topSlideOut = this._slideOutStack[this._slideOutStack.length - 1];
topSlideOut.component = componentRef;

Expand Down

0 comments on commit 0eab5c0

Please sign in to comment.