diff --git a/projects/demo/src/app/app.component.scss b/projects/demo/src/app/app.component.scss
index 588afb4..03249ed 100644
--- a/projects/demo/src/app/app.component.scss
+++ b/projects/demo/src/app/app.component.scss
@@ -4,4 +4,8 @@
.content {
text-align: center;
+}
+
+.green {
+ color: blue;
}
\ No newline at end of file
diff --git a/projects/demo/src/app/app.component.spec.ts b/projects/demo/src/app/app.component.spec.ts
index 127bbea..05ad4c6 100644
--- a/projects/demo/src/app/app.component.spec.ts
+++ b/projects/demo/src/app/app.component.spec.ts
@@ -4,9 +4,7 @@ import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
- declarations: [
- AppComponent
- ],
+ imports: [AppComponent],
}).compileComponents();
});
@@ -16,7 +14,7 @@ describe('AppComponent', () => {
expect(app).toBeTruthy();
});
- it(`should have as title 'demo'`, () => {
+ it(`should have the 'demo' title`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('demo');
diff --git a/projects/demo/src/app/app.component.ts b/projects/demo/src/app/app.component.ts
index a4c3919..8bcb98c 100644
--- a/projects/demo/src/app/app.component.ts
+++ b/projects/demo/src/app/app.component.ts
@@ -1,10 +1,49 @@
-import { Component } from '@angular/core';
-import { FormControl, FormGroup, Validators } from '@angular/forms';
+import { Component, Input } from '@angular/core';
+import { FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
+import { NgxInputCounterComponent, PlusContentDirective, NgxInputCounterService } from '../../../ngx-input-counter/src/public-api';
+import { CommonModule, JsonPipe } from '@angular/common';
+import { AppCounterComponent } from "./app-counter/app-counter.component";
+
+@Component({
+ selector: 'app-minus',
+ standalone: true,
+ template: `@if (value !== min + step) {
+
+ } @else {
+
+ }
+ `,
+})
+export class MinusTemplateComponent {
+ @Input() value = 0;
+ @Input() min!: number;
+ @Input() max!: number;
+ @Input() step = 1;
+}
+@Component({
+ selector: 'app-plus',
+ standalone: true,
+ template: ``,
+})
+export class PlusTemplateComponent {
+ @Input() value = 0;
+ @Input() min!: number;
+ @Input() max!: number;
+ @Input() step = 1;
+}
@Component({
selector: 'app-root',
+ standalone: true,
templateUrl: './app.component.html',
- styleUrls: ['./app.component.scss']
+ styleUrls: ['./app.component.scss'],
+ imports: [NgxInputCounterComponent, JsonPipe, ReactiveFormsModule, FormsModule, CommonModule, PlusContentDirective, AppCounterComponent]
})
export class AppComponent {
title = 'demo';
@@ -15,6 +54,11 @@ export class AppComponent {
age: new FormControl(2, [Validators.min(18)])
})
+ constructor (private config: NgxInputCounterService) {
+ this.config.minusComponent = MinusTemplateComponent
+ this.config.plusComponent = PlusTemplateComponent
+ }
+
onChange(e: any) {
console.log(e, 'onChange called');
}
diff --git a/projects/demo/src/app/app.config.ts b/projects/demo/src/app/app.config.ts
new file mode 100644
index 0000000..d03bbbc
--- /dev/null
+++ b/projects/demo/src/app/app.config.ts
@@ -0,0 +1,5 @@
+import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
+
+export const appConfig: ApplicationConfig = {
+ providers: [provideZoneChangeDetection({ eventCoalescing: true })]
+};
diff --git a/projects/demo/src/app/app.module.ts b/projects/demo/src/app/app.module.ts
deleted file mode 100644
index a4a5b83..0000000
--- a/projects/demo/src/app/app.module.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { NgModule } from '@angular/core';
-import { FormsModule, ReactiveFormsModule } from '@angular/forms';
-import { BrowserModule } from '@angular/platform-browser';
-import { NgxInputCounterModule } from 'projects/ngx-input-counter/src/public-api';
-
-import { AppComponent } from './app.component';
-
-@NgModule({
- declarations: [
- AppComponent
- ],
- imports: [
- BrowserModule,
- NgxInputCounterModule,
- FormsModule,
- ReactiveFormsModule,
- ],
- providers: [],
- bootstrap: [AppComponent]
-})
-export class AppModule { }
diff --git a/projects/demo/src/app/app.routes.ts b/projects/demo/src/app/app.routes.ts
new file mode 100644
index 0000000..dc39edb
--- /dev/null
+++ b/projects/demo/src/app/app.routes.ts
@@ -0,0 +1,3 @@
+import { Routes } from '@angular/router';
+
+export const routes: Routes = [];
diff --git a/projects/demo/src/favicon.ico b/projects/demo/src/favicon.ico
deleted file mode 100644
index 997406a..0000000
Binary files a/projects/demo/src/favicon.ico and /dev/null differ
diff --git a/projects/demo/src/main.ts b/projects/demo/src/main.ts
index c58dc05..35b00f3 100644
--- a/projects/demo/src/main.ts
+++ b/projects/demo/src/main.ts
@@ -1,7 +1,6 @@
-import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+import { bootstrapApplication } from '@angular/platform-browser';
+import { appConfig } from './app/app.config';
+import { AppComponent } from './app/app.component';
-import { AppModule } from './app/app.module';
-
-
-platformBrowserDynamic().bootstrapModule(AppModule)
- .catch(err => console.error(err));
+bootstrapApplication(AppComponent, appConfig)
+ .catch((err) => console.error(err));
diff --git a/projects/demo/tsconfig.app.json b/projects/demo/tsconfig.app.json
index e4e0762..e40712b 100644
--- a/projects/demo/tsconfig.app.json
+++ b/projects/demo/tsconfig.app.json
@@ -1,4 +1,5 @@
-/* To learn more about this file see: https://angular.io/config/tsconfig. */
+/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
+/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
{
"extends": "../../tsconfig.json",
"compilerOptions": {
diff --git a/projects/demo/tsconfig.spec.json b/projects/demo/tsconfig.spec.json
index a9c0752..0a43b83 100644
--- a/projects/demo/tsconfig.spec.json
+++ b/projects/demo/tsconfig.spec.json
@@ -1,4 +1,5 @@
-/* To learn more about this file see: https://angular.io/config/tsconfig. */
+/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
+/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
{
"extends": "../../tsconfig.json",
"compilerOptions": {
diff --git a/projects/ngx-input-counter/README.md b/projects/ngx-input-counter/README.md
index 3bbba76..37bdf75 100644
--- a/projects/ngx-input-counter/README.md
+++ b/projects/ngx-input-counter/README.md
@@ -1,5 +1,14 @@
# NgxInputCounter
+
+
+
+
+[][npm-url]
+[][npm-url]
+
+[npm-url]: https://www.npmjs.com/package/ngx-input-counter
+
The input number with counter for Angular
## Getting Started
@@ -8,6 +17,7 @@ The input number with counter for Angular
| Angular | ngx-input-counter |
| -------- |:------:|
+| >=16.0.0 | v1.0.x |
| >=15.0.0 | v0.0.x |
### Instalation
@@ -18,7 +28,7 @@ npm i ngx-input-counter
## Usage
-Import the module
+NgModule: Import the module
```typescript
import { NgxInputCounterModule } from 'ngx-input-counter';
@@ -31,6 +41,21 @@ import { NgxInputCounterModule } from 'ngx-input-counter';
})
```
+Standalone: Import the component, optional: if you are using the directives
+
+```ts
+import { NgxInputCounterComponent } from 'ngx-input-counter';
+@NgModule({
+ ...
+ imports: [
+ ...,
+ NgxInputCounterComponent,
+ PlusContentDirective,
+ MinusContentDirective,
+ ],
+})
+```
+
Use in your components
```html
@@ -40,13 +65,15 @@ Use in your components
### Props
| Name | Type | Default | Description |
-|-------------|--------------------|-------------|-------------|
+|-------------|--------------------|-------------|------------------------------------------|
| value | `number` | `0` | Initial state of the toggle button |
| min | `number` | `-Infinity` | Transition time for the animation |
| max | `number` | `Infinity` | Transition time for the animation |
| step | `number` | `1` | Transition time for the animation |
| minusTemplate | `TemplateRef` | `-` | Pass a TemplateRef to replace the minus button content |
| plusTemplate | `TemplateRef` | `+` | Pass a TemplateRef to replace the plus button content |
+| minusComponent | `Type` | `undefined` | Pass a Component to replace the minus button content |
+| plusComponent | `Type` | `undefined` | Pass a Component to replace the plus button content |
| minusClass | `string` | `'ngx-input-counter-button'` | Classes of the minus button |
| plusClass | `string` | `'ngx-input-counter-button'` | Classes of the plus button |
| valueClass | `string` | `'ngx-input-counter-value'` | Classes of value text |
@@ -57,3 +84,231 @@ Use in your components
| Name | Payload | Description |
| --- | ------ | ------- |
| change | value | Triggered when state of the component changes. Contains: `value` - state of the component |
+
+## Styling
+
+You can use the default classes and add your own styles or using a custom class:
+
+The classes in the component are:
+
+- `ngx-input-counter-container`: The container element.
+- `ngx-input-counter-button`: The buttons element.
+- `ngx-input-counter-value`: The value element .
+
+```scss
+ngx-input-counter.custom {
+ .ngx-input-counter-container {
+ border-radius: 50px;
+ text-align: center;
+ .ngx-input-counter-value {
+ width: 30px;
+ font-weight: bold;
+ font-size: 18px;
+ }
+ }
+ .ngx-input-counter-button {
+ border: 1px solid #999;
+ border-radius: 100%;
+ background-color: white;
+ width: 36px;
+ height: 36px;
+ text-align: center;
+ font-weight: 600;
+ font-size: 20px;
+ cursor: pointer;
+ transition: all 0.5s ease;
+ &:hover {
+ background-color: #ddd;
+ box-shadow: 1px 1px 2px 1px #ccc;
+ }
+ }
+}
+```
+
+Then in your component:
+
+```html
+
+```
+
+You can use the Input props `minusClass`, `plusClass` and `valueClass` to override the default value class and use your own classes, this is usefull if you are using CSS frameworks.
+
+```html
+
+```
+
+If you want to use custom icons in the counter buttons use the `minusTemplate` and `plusTemplate` passing a TemplateRef with the content you want to show
+
+```html
+
+
+
+
+
+
+
+
+```
+
+You can use the slot, using `minus` for the `minusTemplate` and `plus` for the `plusTemplate` slot
+
+```html
+
+
+
+
+
+
+
+
+```
+
+When you use the slot template you can pass classes to override the button class:
+
+```html
+
+
+
+```
+
+## Global Configuration
+
+You can configure all `ngx-input-counter` components in your app using the `NgxInputCounterService` provider.
+This allows you to set default values for all instances of `ngx-input-counter` throughout your application.
+
+```ts
+constructor (private config: NgxInputCounterService) {
+ this.config.min = 0
+ this.config.valueClass = 'p-2 border border-gray-400 font-monospace'
+ this.config.minusClass = 'btn border-gray-400 rounded-l-md opacity-50 hover:opacity-40'
+ this.config.plusClass = 'btn border-gray-400 rounded-r-md opacity-50 hover:opacity-40'
+}
+```
+
+These settings will apply to all `ngx-input-counter` components in your application. However, you can still override individual values
+directly through their input properties in your templates.
+
+### Advanced Customization
+
+For more advanced use cases, you can use the plusComponent and minusComponent properties to define custom components for the plus and minus buttons:
+
+```ts
+constructor (private config: NgxInputCounterService) {
+ ...
+ this.config.minusComponent = MinusTemplateComponent;
+ this.config.plusComponent = PlusTemplateComponent;
+}
+```
+
+This is useful when you have dynamic or reusable templates for your button content and want to configure them globally via the service.
+
+### Extending the Component
+
+Another powerful way to customize `ngx-input-counter` is by extending the `NgxInputCounterComponent` itself.
+This allows you to create your own custom input counter component, add new properties, and directly modify the button content templates within your extended component.
+
+```ts
+@Component({
+ selector: 'app-input-counter',
+ standalone: true,
+ imports: [NgxInputCounterComponent],
+ template: `
+
+
+
+
+ @if (value !== min + step) {
+
+ } @else {
+
+ }
+
+
+
+ `,
+ providers: [
+ {
+ provide: NG_VALUE_ACCESSOR,
+ useExisting: forwardRef(() => AppCounterComponent),
+ multi: true
+ }
+ ]
+})
+export class AppCounterComponent extends NgxInputCounterComponent {}
+```
+
+By creating your own component that extends the original, you can:
+
+- Add custom inputs and behavior
+- Override the button content templates
+- Fully customize the appearance and functionality
+
+You can then use `` instead of `` in your templates.
+
+> ![NOTE]
+> If you plan to use your extended component with Angular Forms, don't forget to provide the `NG_VALUE_ACCESSOR`
+
+```ts
+ providers: [
+ {
+ provide: NG_VALUE_ACCESSOR,
+ useExisting: forwardRef(() => AppCounterComponent),
+ multi: true
+ }
+ ]
+```
+
+This ensures your custom counter component works properly with ngModel or reactive forms.
+
+## Development
+
+Clone this repo and install the dependencies. Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.
+
+### Running unit tests
+
+Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
+
+### Running end-to-end tests
+
+Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
+
+## Contributing
+
+See Contributing Guide.
+
+## License
+
+MIT
diff --git a/projects/ngx-input-counter/package.json b/projects/ngx-input-counter/package.json
index ed319a1..5182d09 100644
--- a/projects/ngx-input-counter/package.json
+++ b/projects/ngx-input-counter/package.json
@@ -1,26 +1,9 @@
{
"name": "ngx-input-counter",
- "description": "Input counter component for Angular",
- "version": "0.0.3",
- "keywords": [
- "frontend",
- "input",
- "component",
- "input-number",
- "counter"
- ],
- "license": "MIT",
- "homepage": "https://github.com/Codenity-team/ngx-input-counter#readme",
- "repository": {
- "type": "git",
- "url": "https://github.com/Codenity-team/ngx-input-counter.git"
- },
- "bugs": {
- "url": "https://github.com/Codenity-team/ngx-input-counter/issues"
- },
+ "version": "1.0.0",
"peerDependencies": {
- "@angular/common": "^15.0.0",
- "@angular/core": "^15.0.0"
+ "@angular/common": ">=16.0.0",
+ "@angular/core": ">=16.0.0"
},
"dependencies": {
"tslib": "^2.3.0"
diff --git a/projects/ngx-input-counter/src/lib/ngx-input-counter.component.html b/projects/ngx-input-counter/src/lib/ngx-input-counter.component.html
index ff46bb2..5d6d750 100644
--- a/projects/ngx-input-counter/src/lib/ngx-input-counter.component.html
+++ b/projects/ngx-input-counter/src/lib/ngx-input-counter.component.html
@@ -1,11 +1,33 @@
-+
+
+ @if (plusComponent) {
+
+ }
+
+
+ @if (minusComponent) {
+
+ }
+