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

gascox-component-library

v0.0.6-p

Published

Design system for Gasco

Downloads

20

Readme

GASCO COMPONENTS LIBRARY README

Esta creado con StencilJs https://stenciljs.com/

Para clonar el repo y echar a andar todo:

  1. Clonar el repo con git clone
  2. cd a la carpeta donde se clono el repo, en mi caso gascox-component-library
  3. la primera vez necesitaras instalar los node_modules con: npm install
  4. para correr el app: npm run start

Para crear un nuevo componente

  1. Tienes que estar con la consola apuntando a la carpeta donde esta el proyecto: npm run generatecompletas el nombre del componente y le das yes
  2. Vas a la carpeta src/components y ya esta tu componente listo para trabajarlo

Para publicar cambios en la libreria:

  1. (solo 1 vez) En la consola dentro del proyecto npm login, ingresar password, id, email
  2. Ir al package.json y cambiar el "version" a la siguiente version
  3. En la consola dentro del proyecto npm run build
  4. En la consola dentro del proyecto npm publish

Carpetas de src

  1. assets: es donde iran las imagenes, videos, etc. necesarios para los componentes
  2. components: donde estan los componentes creados
  3. globals: para dejar archivos globales de scss como variables, mixins etc...
  4. utils: lo trae por default el stencil

Para agregarlo a un Proyecto Angular

  1. En la consola dentro del proyecto: npm i --save gascox-component-library o si quieres actualizar la version npm i --save [email protected] donde despues del @ sera la version, o le das npm uninstall gascox-component-library y luego npm i --save gascox-component-library

  2. En el AppModule.ts (y en el modulo mas cercano donde se espamea algun componente) agregar schemas: [CUSTOM_ELEMENTS_SCHEMA], desde @angular/core, esto es para permitir elementos custom dentro de angualr

  3. En el Main.ts agregar: import { defineCustomElements } from 'gascox-component-library/loader'; y lineas ,as abajo defineCustomElements(window);

  4. ya solo queda llamar en el componente de angular el selector del componente de la libreria de gasco ejm: <gasco-button></gasco-button>, recuerden el paso 2 en su modulo mas cercano

Forma de enviarle las props

  1. las Variables que son booleanas puedes no enviarle valor ya que tienen valor por default, ejm en el caso de disabled ppuedes enviar disabled='true' o puedes solo enviarle disabled, tambien puedes enviarle disabled={{myVar}} o [disabled]="myVar" de esta forma bindeas una variable desde el .ts

  2. las variables array o tipo Json (objetos) [steps]="myArray" donde [steps] es la variable dentro del componente y myArray un array en el .ts donde se esta implementando el componente de la libreria

  3. variables desde el .ts para que sean diamicos o cambien segun lo necesitemos: [steps]="myVarFromTs" donde steps es el var dentro del componente de la libreria y myVarFromTs es la variable en el .ts donde se implemente el componente de la libreria

  4. la variables de tipo string puedes enviarlas con prop='Hola mundo' o prop={myVar} o [prop]='myVar' o si no te resulta con prop={{myVar}} donde my var es la variable en el .ts donde se esta implementando em componente

Forma de utilizar Funciones del componente (stencil) desde angular

Si tu componente de Stencil (para este caso <modalGasco/>) tiene un @Method o un metodo como close o open, puedes llamarlo desde el angular de la siguiente forma:

  1. en tu .Html <modalGasco #miCustomModal/>
  2. en tu .ts @ViewChild('miCustomModal') modal!: ElementRef;
  3. en tu .ts donde colocaste el @ViewChild this.modal.nativeElement.openModal();

Forma de enviarle una Funcion al componente (stencil) desde angular para que se ejecute

Si tu componente de Stencil (para este caso <modalGasco/>) tiene una @Prop de tipo Function, le puedes enviar de esta forma tu funcion a ejecutar desde angular de la siguiente forma:

  1. en tu .Html <modalGasco [propStencilComponent]='myFunctuonAngular.bind(this)'/> el .bind(this) es necestario que se lo agreges despues del nombre d tu fincion sin las () de la funcion
  2. en tu .ts myFunctuonAngular(){console.log('hola mundo')
  3. en tu componente stencil ya puedes ocupar esa funcion

---------------------BUTTON GASCO------------------------------------------------

Selector:

<gasco-button></gasco-button>

Recibe varios properties (props)

<gasco-button
type="primary"
text="Texto muestra"
left="add"
disabled={{myDisabledVar}}
outline
right="mail"
></gasco-button>
  1. type: es el tipo de boton, se le puede enviar 'primary' para azul o 'secondary' para rojo. Si no se le envia nada por default sera primary

  2. text: Es el value que tendra el button, si no se le envia nada por defaul sera 'Aceptar'. Si solo es texto se alineara al centro, si tiene un icono a la izquierda se alinieada con flex-start o al comienzo

  3. left= es un parametro opcional, este sera para spamear un icono a la izquierda. Por ahora solo se puede pasar el valor de 'add' para spamear un icono de una cruz con redondo azul

  4. disabled= es un parametro opcional, si se pasa como true se spamea el style para el button disabled y elimina los eventos del mouse sobre el, myDisabledVar es una variable en el .ts

  5. outline= es un parametro opcional, es para cambiar el tipo de button a outline, o sin relleno en el medio

  6. right= permite spamear un icono a la derecha, al momento de este readme solo se permite el mail

IMPORTANTE: en el repo fe_pagoEnLinea-sinLoginen el archivo styles.scss que esta a la par del main.ts se encuentra una clase .containerButtons la cual la agregas en el div que contendra los buttons y de forma automatica spamea los styles colocando los botones a los costados y en mobile spameandolos en toda la pantalla, se recomienda agregarlos en el styles.scssde tu proyecto y desde el componente donde estas trabajando darle un @import a esos stylos de esa forma tendras styles globales para todo tu proyecto

---------------------INPUT GASCO------------------------------------------------

Selector:

<gasco-input></gasco-input>

Recibe varios properties (props)

<gasco-input
   placeholder="Soy una etiqueta"
   value="Soy el texto del input"
   required={{myVariable}}
   validator="number"
   min-length="9"
   max-length="9"
   counter
   searchicon
   error="Mensaje de error"
   haserror={{true}}
   appAccessor
   formControlName="myInput"
></gasco-input>
  1. placeholder: es el texto que tendra la etiqueta, si el input no tiene value la etiqueta se espamea dentro del input, si tiene el input value la etiqueta se espamea ensima del input

  2. value: es el texto que contiene el input

  3. required: para convertir este input en requerido, el usuario tiene que completarlo. Si el usuario da click en el y se sale, el borde y el place holder se cambia a rojo y se spamea un default message error de 'Este campo es requerido', si no le envias nada asume que es true

  4. validator: es para aplicarle al input que acepte solo: letras, numeros u otro validador. los parametos aceptados son se encuentan en ValidatorTypes y al momento de hacer este readme pueden ser: [ number letters rut]. Si no se le pasa uno o no coincide con esos no le aplica ningun validador

  5. min-length: minimo de caracteres para que el input sea valido, si el usuario no completa los caracteres se le mostrara un mensaje d error de que necesita completar este campo

  6. max-length: maximo de caracteres para que el input sea valido, si el usuario no completa los caracteres se le mostrara un mensaje d error de que necesita completar este campo. Si le agregas este valor, el input no dejara ingresar un mayor numero de caracteres, es decir, si agregas max-length en 5 el input no permite agregar mas de 5 caracteres

  7. counter: para spamear del lado derecho-abajo un contador que muestra el total de caracteres ingresados y el total necesario, si no le envias nada asume que es true

  8. error: mensaje de error que quiere que se pinte en el input, marca al input como invalid hasta q el usuario modifique el value

  9. searchicon: para poder spamear un icono de lupa a la izquierda del input, si no le envias nada asume que es true

  10. haserror: para forzar al input a error, osea que se muestre en rojo el borde

  11. appAccessor: es una directiva que se tiene que crear en Angular para que lo tome los formularios reactivos (buscar seccion "DIRECTIVA FORMULARIO REACTIVO")

  12. formControlName: es el controlname para insertarlo en el formulario reactivo de la forma tradicional, pero se necesita la directiva del paso 11

TIP: el width del input lo puedes dar con la propiedad de css de width o con flex-basic tanto en px, vw, %, rem. Ya que se comporta como una etiqueta HTML

---------------------STEPPER GASCO------------------------------------------------

Selector:

<gasco-stepper></gasco-stepper>

Nota: Este componente sirve para 3,4 y 5 pasos, la cantidad de caracteres del titulo pueden ir de 1 a 13 (lo recomendable segun maquetacion), la cantidad del subtitulo puede ser de 1 a 19 (lo recomendable segun maquetacion), Este componente es responsive por ende segun la cantidad de pasos y la medida de pantalla (diferentes mediaQuery) pasara de tener circulo,titulo,subtitulo y linea a solo tener circulo y linea

Recibe dos Prop:

<gasco-stepper
   [steps]="steps"
   [active]="stepActive"
></gasco-stepper>
  1. steps: es el array de pasos, este se declara en el .ts y se llama en el html donde este el steper

  2. active: es el paso activo o paso actual como quieras llamarlo. Se puede pasar del paso 1 al 5, del 5 al 1 de una vez indicandole el valor del paso que quieres colocar activo, el steper si estas en el paso 1 y le indicas al paso 5 coloca al paso 5 como activo y los otros como done, si estas en el 5 y le indicas 1 coloca al 1 como activo y los otros como disabled, si estas en el paso 1 y le indicas 2 coloca al 1 como disabled y al 2 como activo

mySteps es un array de elementos tipo string

	{
		number: '1',  //Este es el numero dentro del circulo
		title: 'Cliente', //este es el texto del titulo
		subTitle: 'Búsqueda de cliente', //este es el texto del subtitulo
	}

Este es un Objeto para 5 pasos el cual debes declarar en tu .ts donde se este implementando el steper, por default colocara como activo el primer elemento del array

 mySteps = [
               {
                  number: '1',
                  title: 'Cliente',
                  subTitle: 'Búsqueda de cliente',
               },
               {
                  number: '2',
                  title: 'Cuentas',
                  subTitle: 'Cuentas por pagar',
               },
               {
                  number: '3',
                  title: 'Medio de pago',
                  subTitle: 'Información de pago',
               },
               {
                  number: '4',
                  title: 'Comprobante',
                  subTitle: 'Finalizar pago',
               },
               {
                  number: '5',
                  title: 'Medio de pago',
                  subTitle: 'Informacion de pago',
               },
            ];

---------------------MODAL GASCO------------------------------------------------

Selector:

En el .html

<gasco-modal #myModal></gasco-modal>

En el .ts hacer un @ViewChild('myModal') modal!: ElementRef;

Recibe properties (props)

  1. closeBackgroud: (es Opcional) esta propiedad permite que el modal se cierre dando click fuera de el, por defecto es true (ya que es opcional), por ende se cierra al darle click fuera. Si no quieres eso tendras que pasarle esta propertie en false
<gasco-modal [closeBackgroud]='false'></gasco-modal>
  1. Abrir y Cerrar: despues de ocupar el @viewChild myModal.nativeElement.open() myModal.nativeElement.close()

MODAL CUSTOM (info error success) Funcion para setear los parametros a los modales info error success. Recomiendo crear una constante o enum con estos parametros

  1. tipo de modal a spamear ('info' 'error' 'success'): Recuerca crear el enum o const con los tipos de modal que le puedes pasar, por q si no le pasas exactamente cualquier de estos valores, no se va a ver nada const type:string = 'success';

  2. titleModal: es un parametro opcional, es un texto que si lo envias se coloca a la altura donde esta la x de cerrar el modal con una linea debajo del texto const modalTitle:string = 'Soy el titulo';

  3. array de botones: Puedes parametrizar cada boton ya que es un gascoButton y acepta todas sus props, ademas acepta una funcion que se ejecuta cuando le dan click. Si le envias 1 solo button se centra, si le envias 2 (es lo maximo maquetado) se colocan en los bordes

    const buttons = [ { text: 'Regresar', type="secondary" outline onClickFunction: this.myCustomFunction.bind(this) { text: 'Aceptar', type="primary" outline onClickFunction: this.myNewCustomFunctionWithParams.bind(this) ];
  4. Body del modal: titleBodyModal: es el texto en color debajo del icono text1: es un parrafo sin palabras a color, es opcional, si no lo envias no se spamea y no modifca styles text2: Es un parrafo donde su ultima parte o el strongText termina en color elejido color. Es opcional, si no se envia no se spamea ni modifica styles color: puede ser green red blue yellow

    const body = {
       titleBodyModal: 'Titulo Body',
       text1: 'Soy un parrafo de tipo uno sin palabra strong',
       text2: { normalText: 'Soy un parrafo de tipo 2 ', strongText: 'y yo la palabra strong', color: 'red', },
       };
  5. Forma en como pasarle estos parametos al modal y abrirlo desde el angular

    myModal.nativeElement.setValuesModalCustom( type, buttons, body,modalTitle );
    myModal.nativeElement.openModal();

---------------------TOAST GASCO------------------------------------------------

Selector

En el .html

<gasco-toast></gasco-toast>

Recibe tres Prop:

<gasco-toast [display]="true" [type]="primary" [text]="Texto de prueba"></gasco-toast>
  1. display: true | false : indica si el toast debe o no mostrarse, en caso de colocar false, este se remueve del dom.

  2. type: "primary" | "warning" : indica el tipo de toast y con ello las clases css especificas para cada uno, hasta el momento soporta primary para tipo informativo azul y warning tipo alerta amarillo.

  3. text: string : permite agregar una cadena de texto al toast.

---------------------Loading------------------------------------------------

Selector:

<gasco-loading></gasco-loading>
  1. Agregas en .html
<gasco-loading #loadingGasco></gasco-loading>
  1. en el .ts
  @ViewChild('loadingGasco') gsLoading!: ElementRef;
  1. En el mismo .ts en la llamada http
 this.gsLoading.nativeElement.open();

para cerrarlo (puedes cerrarlo en el siguiente componente o step si lo necesitas)

 this.gsLoading.nativeElement.close();

Nota: es responsive, solo espamealo y el mismo se adapta

---------------------DIRECTIVA FORMULARIO REACTIVO------------------------------------------------

Esta directiva t permite obtener el value de los inputs mediante los formularios reactivos.

Creas una directiva e insertas este codigo (recuerda registrarla en el module del app o el mas cercano)

import {
  Directive,
  forwardRef,
  HostBinding,
  HostListener,
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Directive({
  selector: '[appAccessor]',
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => FormDirective),
      multi: true,
    },
  ],
})
export class FormDirective implements ControlValueAccessor {
  @HostBinding('value') hostValue: any;

  lastValue: any;
  private onChange = (value: any) => {};
  private onTouched = () => {};

  writeValue(value: any) {
    this.hostValue = this.lastValue = value == null ? '' : value;
  }

  registerOnChange(fn: (value: any) => void) {
    this.onChange = fn;
  }

  registerOnTouched(fn: () => void) {
    this.onTouched = fn;
  }

  @HostListener('valueChanged', ['$event.detail'])
  _handleInputEvent(value: any) {
    if (JSON.stringify(value) !== JSON.stringify(this.lastValue)) {
      this.lastValue = value;
      this.onChange(value);
      this.onTouched();
    }
  }
}

Este es el archivo de test para subir el coverage

import { FormDirective } from './form-directive.directive';

describe('FormDirectiveDirective', () => {
  let directive: FormDirective;

  beforeEach(() => {
    directive = new FormDirective();
  });

  it('should create an instance', () => {
    expect(directive).toBeTruthy();
  });

  it('Test onChange', () => {
    const toBe = 'algo';
    spyOn<any>(directive, 'onChange').and.callThrough();
    directive['onChange']('algo');
    expect(directive['onChange']).toHaveBeenCalledWith('algo');
  });

  it('Test onTouched', () => {
    spyOn<any>(directive, 'onTouched').and.callThrough();
    directive['onTouched']();
    expect(directive['onTouched']).toHaveBeenCalled();
  });

  it('Test writeValue sin parametro', () => {
    directive.lastValue = 'ultimo';
    directive.writeValue(null);
    expect(directive.lastValue).toEqual('');
  });

  it('Test writeValue con parametro', () => {
    const newParam = 'algo nuevo';
    directive.lastValue = 'ultimo';
    directive.writeValue(newParam);
    expect(directive.lastValue).toEqual(newParam);
  });

  it('registerOnChange test', () => {
    spyOn<any>(directive, 'registerOnChange').and.callThrough();
    directive['onChange'] = () => console.log(`Hola Mundo`);
    const newFunction = () => {};
    directive.registerOnChange(newFunction);
    expect(directive.registerOnChange).toHaveBeenCalled();
    expect(directive['onChange']).toEqual(newFunction);
  });

  it('registerOnTouched test', () => {
    spyOn<any>(directive, 'registerOnTouched').and.callThrough();
    directive['onTouched'] = () => console.log(`Hola Mundo`);
    const newFunction = () => {};
    directive.registerOnTouched(newFunction);
    expect(directive.registerOnTouched).toHaveBeenCalled();
    expect(directive['onTouched']).toEqual(newFunction);
  });

  it('_handleInputEvent Bad request ', () => {
    spyOn<any>(directive, 'onChange').and.callThrough();
    spyOn<any>(directive, 'onTouched').and.callThrough();
    const valor = 'fake';
    const newValor = 'new';
    directive.lastValue = valor;
    directive._handleInputEvent(valor);
    expect(directive.lastValue).not.toEqual(newValor);
    expect(directive['onChange']).not.toHaveBeenCalled();
    expect(directive['onTouched']).not.toHaveBeenCalled();
  });

  it('_handleInputEvent OK', () => {
    spyOn<any>(directive, 'onChange').and.callThrough();
    spyOn<any>(directive, 'onTouched').and.callThrough();
    const valor = 'fake';
    const newValor = 'new';
    directive.lastValue = valor;
    directive._handleInputEvent(newValor);
    expect(directive.lastValue).toEqual(newValor);
    expect(directive['onChange']).toHaveBeenCalled();
    expect(directive['onTouched']).toHaveBeenCalled();
  });
});