Skip to content

Commit

Permalink
doc(README.md): installation and usage
Browse files Browse the repository at this point in the history
  • Loading branch information
aegenet committed Mar 30, 2024
1 parent 7d51ffc commit 2a77ed5
Show file tree
Hide file tree
Showing 8 changed files with 319 additions and 134 deletions.
224 changes: 197 additions & 27 deletions packages/au2-base-component/README.md
Original file line number Diff line number Diff line change
@@ -1,57 +1,227 @@
[![npm version](https://img.shields.io/npm/v/@aegenet/au2-base-component.svg)](https://www.npmjs.com/package/@aegenet/au2-base-component)
<br>

# @aegenet/au2-base-component

> `BaseComponent` with `EventAggregator`, `I18N`, `Aware Event` and `AntiBounce`
> `BasePage` with `EventAggregator`, `I18N`, `Aware Event` and `AntiBounce`

This project is bootstrapped by [aurelia/new](https://github.com/aurelia/new).
# Installation

## Start dev web server
```shell
npm install @aegenet/au2-base-component@^1.6.1
# or
yarn add @aegenet/au2-base-component@^1.6.1
```

npm start
# Usage

Note this plugin project comes with a dev-app. The above command starts the dev app in `dev-app/` folder. The plugin source code is in `src/` folder.
## Register the plugin

## Build the plugin in production modern
```js
import * as myPlugin from '@aegenet/au2-base-component';
Aurelia
// Load all exports from the plugin
.register(myPlugin)
.app(MyApp)
.start();
```

npm run build
## Components & services

### BaseComponent

A base component adds the following features to a component:
- `EventAggregator` to send and receive events.
- `I18N` to translate the page.
- `Aware` to listen to events from other components.
- `AntiBounce` to prevent multiple clicks on a button.
- `Store` to store data in memory.
- `Slots` informations to manage slots.

```typescript
import { customElement, IContainer, inject } from 'aurelia';
import { BaseComponent } from '@aegenet/au2-base-component';

import template from './demo-component.html';
@customElement({
name: 'demo-component',
template,
})
@inject(Element, IContainer)
export class DemoComponent extends BaseComponent {
//
}
```

It builds plugin into `dist/index.mjs` file.
### BasePage

A base page adds the following features to a page component:
- `Router` to navigate between pages.
- `EventAggregator` to send and receive events.
- `I18N` to translate the page.
- `Aware` to listen to events from other components.
- `AntiBounce` to prevent multiple clicks on a button.
- `Store` to store data in memory.

```typescript
import { IContainer, customElement, inject } from 'aurelia';
import { BasePage } from '@aegenet/au2-base-component';

import template from './demo-page.html';
@customElement({
name: 'demo-page',
template,
})
@inject(IContainer)
export class DemoPage extends BasePage {
//
}
```

Note when you do `npm publish` or `npm pack` to prepare the plugin package, it automatically run the above build command by the `prepare` script defined in your package.json `"scripts"` section.
### Aware

## Consume the plugin
When a component inherits from `BaseComponent`, it can be controlled by events.

If your plugin is published to npm or a private registry, just install the plugin package.json
From TypeScript: with a simple `IEventAggregator`, you can send events to the component.

npm install @aegenet/au2-base-component@^1.6.0
```typescript
import { IEventAggregator } from 'aurelia';
// [...]

If you want to directly use plugin's git repo.
const ev: IEventAggregator = container.get(IEventAggregator);
ev.publish('demo-component:tab1', { property: 'select', value: ['two'] });
```

npm install [email protected]:username/@aegenet/au2-base-component.git
From HTML: with the `aware-component` custom element, you can send events to the component.

or
```html
<demo-component component.ref="demoComponent" event-name="tab1">
<span slot="one" title="French">
<h5>Second slide label</h5>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</span>
<span slot="two" title="English">
<h5>Third slide label</h5>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur.</p>
</span>
</demo-component>

npm install https://some.git.server/username/@aegenet/au2-base-component.git
<aware-component component.ref="awareBtnRef" events.bind="[{ name: 'demo-component:tab1', options: { property: 'select', value: ['two'] } }]"></aware-component>

If you want to install from local folder, don't do "npm install ../local/@aegenet/au2-base-component/" as the folder's `node_modules/` will cause webpack to complain about duplicated dependency like "@aurelia/metadata".
<button click.trigger="awareBtnRef.publish()">Send event</button>
```

In this plugin's folder, do
### Store

npm pack
This basic store is more like a cache system. It allows you to store data in memory and refresh it when needed.

This will pack the plugin into @aegenet/au2-base-component
In an application project's main file.
```typescript
import { DIStoreService, IStoreService } from '@aegenet/au2-base-component';

```js
import * as myPlugin from '@aegenet/au2-base-component';
Aurelia
// Load all exports from the plugin
.register(myPlugin)
.app(MyApp)
.start();
const storeService = container.get<IStoreService>(DIStoreService);

// Setup
storeService.setStore({
key: 'user',
async load(container) {
return JSON.parse(localStorage.getItem('user') || '[]');
},
}, {
key: 'user_index',
async load(container) {
return arrayToObject((await storeService.getStore('user')) as unknown[], 'id');
},
});

// [...]

// Get
await storeService.getStore('user'); // []

// Set
localStorage.setItem('user', JSON.stringify([{ id: 1, name: 'John' }]));
// Refresh
await storeService.refreshStore('user');

// Get
await storeService.getStore('user'); // [{ id: 1, name: 'John' }];
```

### Container stats & debug

```typescript
import { debugContainer } from '@aegenet/au2-base-component';
debugContainer(null);
/* {
instance: [],
singleton: [],
transient: [],
callback: [],
array: [],
alias: [],
} */

// container: IContainer;
debugContainer(container);
```

### Default capture

```html
<button
...$attrs
type="button"
click.trigger="doAction()"
<au-slot>
</au-slot>
</button>
```

```typescript
import { customElement, IContainer, inject } from 'aurelia';
import { defaultCapture, BaseComponent } from '../src';
import template from './demo-default-capture.html';

/**
* Demo default capture
*/
@customElement({
name: 'demo-default-capture',
template,
capture: defaultCapture,
})
@inject(Element, IContainer)
export class DemoDefaultCapture extends BaseComponent {
public clickCount: number = 0;

constructor(element: Element, container: IContainer) {
super(element, container);
}

public doAction(): void {
this.clickCount++;
}
}
````

# Development

## Start dev web server

npm start

Note this plugin project comes with a dev-app. The above command starts the dev app in `dev-app/` folder. The plugin source code is in `src/` folder.

## Build the plugin in production modern

npm run build

It builds plugin into `dist/index.mjs` file.

Note when you do `npm publish` or `npm pack` to prepare the plugin package, it automatically run the above build command by the `prepare` script defined in your package.json `"scripts"` section.

## Unit Tests

npm run test
Expand Down
6 changes: 3 additions & 3 deletions packages/au2-base-component/dev-app/demo-au-slot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import template from './demo-au-slot.html';
})
@inject(Element, IContainer)
export class DemoAuSlot extends BaseComponent {
/** Tab actuel */
/** Current tab */
@bindable()
public tabSlot?: string;

Expand All @@ -17,15 +17,15 @@ export class DemoAuSlot extends BaseComponent {
}

protected async _init(): Promise<void> {
// Si pas de tab par défaut, nous sélectionnons le premier
// If any tab by default, we select the first one
if (!this.tabSlot) {
this.tabSlot = this.auSlotNames.length ? this.auSlotNames[0] : undefined;
}
await super._init();
}

/**
* Sélectionne un tab
* Select a tab
* @param tabSlot
*/
public select(tabSlot: string): void {
Expand Down
10 changes: 5 additions & 5 deletions packages/au2-base-component/dev-app/demo-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import template from './demo-component.html';
})
@inject(Element, IContainer)
export class DemoComponent extends BaseComponent {
/** Tab actuel */
/** Current tab */
@bindable()
public tabSlot?: string;

/** Else (for test) */
/** Else (test) */
public something: string = '';

constructor(element: Element, container: IContainer) {
Expand All @@ -24,23 +24,23 @@ export class DemoComponent extends BaseComponent {

/** @inheritdoc */
protected async _init(): Promise<void> {
// Si pas de tab par défaut, nous sélectionnons le premier
// If any tab by default, we select the first one
if (!this.tabSlot) {
this.tabSlot = this.slotNames.length ? this.slotNames[0] : undefined;
}
await super._init();
}

/**
* Sélectionne un tab
* Select a tab
* @param tabSlot
*/
public select(tabSlot: string): void {
this.tabSlot = tabSlot;
}

/**
* Sélectionne un tab
* (alt) Select a tab
* @param tabSlot
*/
public selectAlt = (tabSlot: string): void => {
Expand Down
8 changes: 4 additions & 4 deletions packages/au2-base-component/dev-app/store-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import template from './store-component.html';
})
@inject(Element, IContainer)
export class StoreComponent extends BaseComponent {
/** Tab actuel */
/** Current tab */
@bindable()
public tabSlot?: string;

Expand All @@ -31,7 +31,7 @@ export class StoreComponent extends BaseComponent {

/** @inheritdoc */
protected async _init(): Promise<void> {
// Si pas de tab par défaut, nous sélectionnons le premier
// If any tab by default, we select the first one
if (!this.tabSlot) {
this.tabSlot = this.slotNames.length ? this.slotNames[0] : undefined;
}
Expand All @@ -40,15 +40,15 @@ export class StoreComponent extends BaseComponent {
}

/**
* Sélectionne un tab
* Select a tab
* @param tabSlot
*/
public select(tabSlot: string): void {
this.tabSlot = tabSlot;
}

/**
* Sélectionne un tab
* Select a tab (alt)
* @param tabSlot
*/
public selectAlt = (tabSlot: string): void => {
Expand Down
1 change: 0 additions & 1 deletion packages/au2-base-component/src/aware/aware-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import type { IAwareEvent } from './i-aware-event';
* events.bind="[{ name: 'ra-checkbox:my-box', options: { property: 'value', value: !isChecked } }]"
* next.bind="() => nextHasBeenCalled = true"
* >
* Toggled via event
* </aware-component>
*
* <button
Expand Down
Loading

0 comments on commit 2a77ed5

Please sign in to comment.