npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ngx-tagify

v18.0.0

Published

Angular library that wraps @yaireo/tagify

Downloads

7,769

Readme

ngx-tagify

Proper Angular library that wraps @yaireo/tagify. It allows multiple instances of tagify, implements ControlValueAccessor (for use with ngModel and reactive forms), and includes proper type declarations.

Demo

Install

Install via npm:

npm install ngx-tagify

Import module:

import { TagifyModule } from 'ngx-tagify'; 

@NgModule({
  imports: [
    ...
    TagifyModule,
    ...
  ]
})
export class AppModule {}

Include styling (see below).

Component

You can use the <tagify> component either with ngModel or with reactive forms. Either way, it takes a string or an array of TagData, i.e. an Object that contains a unique property value:

interface TagData {
  value: string;
  [key: string]: any;
}

If a string is passed, it gets parsed for tags by Tagify. The returned string is the stringified tags array or, if mode: 'mix', the mixed text and tags string.

Usage with ngModel

Import FormsModule to your module.

<tagify
  [(ngModel)]="tags"
  inputClass="form-control"
  [settings]="settings"
  [whitelist]="whitelist$"
  [readonly]="readonly"
  [disabled]="disabled"
  (add)="onAdd($event)"
  (remove)="onRemove($event)"
></tagify>
import { Component } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { TagData, TagifySettings } from 'ngx-tagify';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
    
  tags: TagData[] = [{ value: 'foo' }];
  // tags = 'foo'; -> if you want to pass as string
    
  settings: TagifySettings = {
    placeholder: 'Start typing...',
    blacklist: ['fucking', 'shit'],
    callbacks: {
      click: (e) => { console.log(e.detail); }
    }
  };
  
  whitelist$ = new BehaviorSubject<string[]>(['hello', 'world']);
  
  readonly = false;
  
  disabled = false;
  
  onAdd(tagify) {
    console.log('added a tag', tagify);  
  }
  
  onRemove(tags) {
    console.log('removed a tag', tags);
  }
  
}

Note: The component only recognizes reference changes, it won't deep check for changes within the array. this.tags.push({value: 'bar'}); won't do anything. Instead, use this.tags = this.tags.concat([{value: 'bar'}]); (or similar) to update changes.

Usage with Reactive Forms

Import ReactiveFormsModule to your module.

<form [formGroup]="form">
  <tagify formControlName="tags"></tagify>
</form>
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  
  form = new FormGroup({
    tags: new FormControl([{ value: 'Reactive' }])
  });
    
  ngOnInit(): void {
      
    this.form.valueChanges.subscribe(value => {
      console.log('form value changed', value);
    });
      
  }
  
}

Predefined values

Use ngModel or reactive forms with an initial string value that gets parsed by Tagify.

If you want to pass predefined tags as text, but receive a tags array as output, pass the value as text between <tagify></tagify>. Mixed text & tags are also supported.

<tagify>tag 1, tag 2</tagify>
<tagify [settings]="{ mode: 'mix' }">
  [[Eric Cartman]] and [[kyle]] do not know [[homer simpson]] because he's a relic.
</tagify>

Angular has problems with hard-coded single curly braces. Use property binding to add predefined tags with json syntax.

originalText = '[[{"id":200, "value":"cartman", "title":"Eric Cartman"}]] and [[kyle]] do not know [[{"value":"homer simpson", "readonly":true}]] because he\'s a relic.';
<tagify [settings]="{ mode: 'mix' }">
  {{ originalText }}
</tagify>

Inputs

| | | |--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | settings | Type: TagifySettingsSee tagify/Settings. | | inputClass | Type: stringApply one or more CSS classes to the input field (e.g. Bootstrap's form-control). | | whitelist | Type: Observable<string[]\|TagData[]>Execution of the observable updates the whitelist of tagify. You can listen to user's inputs and update the whitelist respectively using this observable. | | readonly | Type: booleanDynamically change readonly status. | | disabled | Type: booleanDynamically change disabled status. | | name | Type: stringUse the name attribute if you want to access the tagify component via the service. This name should be unique. |

Outputs

| | | |---|---| |add|Fires when a tag has been added.| |remove|Fires when a tag has been removed.| |tInput|Listen to the input event of the tagify input element.|

Listen to all other events by defining respective callbacks (tagify/Events).

Service

You can also gain access to the full tagify API via a service. Provide a name, such that the tagify instance will be available via the service.

<tagify name="example"></tagify>
<button (click)="addTags()">Add tags</button>
import { Component } from '@angular/core';
import { TagifyService } from 'ngx-tagify';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  
  constructor(
    private tagifyService: TagifyService
  ) {}
  
  addTags() {
    this.tagifyService.get('example').addTags(['this', 'is', 'cool']);
  }
  
}

The original Tagify class is also exposed and can be used for type declarations or custom implementations.

import { Tagify } from 'ngx-tagify';

const tagify: Tagify = new Tagify(inputElement);

Styling

You have two options to include the styling of Tagify.

Option 1: Modify your angular.json by adding the .scss file to the styles property.

"options": {
  "styles": [
    "node_modules/ngx-tagify/styles/tagify.scss",
    "src/styles.scss"
  ]
}

Option 2: If you want to override some of the styling, import it to a sass file. Have a look at tagify/CSS Variables and respective demo page for details.

// src/styles.scss
@import "ngx-tagify/styles/tagify";

.tagify
  --tags-border-color: #ff0000;

Usage with Bootstrap

If you are using Bootstrap as CSS framework (as used in the demo), you might need to tweak some styles in order that Tagify looks pretty:

.tagify {
  --tag-pad: 0 0.5rem;
  line-height: 1.5;
}
.tagify__input:empty::before {
  line-height: inherit;
}
.tagify.form-control {
  height: unset;
}

FAQ

I'm getting TS compilation error!

You are getting TypeScript compilation error with an error output like this:

 node_modules/@types/yaireo__tagify/index.d.ts:475:1
    475 export = Tagify;
        ~~~~~~~~~~~~~~~~
    This module is declared with using 'export =', and can only be used with a default import when using the 'allowSyntheticDefaultImports' flag.

To resolve this issue, set allowSyntheticDefaultImports within compilerOptions in your tsconfig.json:

{
  "compilerOptions": {
    
    "allowSyntheticDefaultImports": true,
    
  }
}

I'm getting build error because stylesheet could not be found!

Module build failed (from ./node_modules/@angular-devkit/build-angular/node_modules/sass-loader/dist/cjs.js):
Can't find stylesheet to import.
  ╷
1 │ @import "@yaireo/tagify/src/tagify";
  │         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  ╵
  node_modules/ngx-tagify/styles/tagify.scss 1:9  root stylesheet

Make sure you include node_modules in the stylePreprocessorOptions within your angular.json:

"stylePreprocessorOptions": {
  "includePaths": ["node_modules"]
},