Christian Michelle Torres Martínez
EstudianteMidduar Arturo Matheus Tapia
EstudianteEdward Rodríguez
EstudianteRafael Bautista
EstudianteGenix Xavier Granados Elias
EstudianteCarlos Benitez
Estudiantekolab Linkear
EstudianteLuis Jose Marquez Gonzalez
EstudianteHéctor Danilo Sebastián Salinas Ugalde
EstudianteCesar González Caballero
EstudiantePlatzi Team
EstudianteMidduar Arturo Matheus Tapia
EstudianteDavid Cubilos
EstudianteAmado León
EstudianteDaniel Arturo Dominguez Lopez
EstudiantePlatzi
EstudianteGustavo Medina Limon
EstudianteManuel Alberto Goicochea Medina
EstudianteNieles Yhosmel Flores Vargas
EstudianteMax Andy Diaz Neyra
EstudianteBonnier Nilss Mamani Larico
EstudianteManuel Alberto Goicochea Medina
EstudianteCamilo Del Valle Ledesma
EstudianteJOHN MELENDEZ
EstudianteArlin Holguin
EstudianteGabriel Oswaldo Montoya Huamani
EstudianteSoy más del gusto de no trabajar con frameworks para css, pero sinceramente estas bondades o pros que te da tailwind sobre bootstrap, foundation, etc. lo hace atractivo, practico y un puntito a favor, gran curso :)
Lo más útil que decidí hacer, por mi parte, fue evitar la necesidad de aprender y depender de frameworks de CSS externos y de sus posibles cambios. En su lugar, opté por crear mi propio framework, integrándolo directamente en los estilos principales del proyecto.
De esta manera, todo el CSS se encuentra centralizado en un solo lugar, y además conozco perfectamente cada clase y cada regla, ya que fui yo mismo quien las diseñó e implementó.
Para los que estén utilizando la versión 17 de Angular, el ngClass se debe importar en el componente:
import { NgClass } from '@angular/common' @Component({ selector: 'app-button', standalone: true, imports: [NgClass], templateUrl: './button.component.html' }) export class ButtonComponent { @Input() btnType: 'button' | 'reset' | 'submit' = 'button' @Input() btnColor: string = 'success' get colors (): string { // get color } }
Si tienes el CommonModule no deberias de importar el NgClass
export class BtnComponent implements OnInit { @Input() typeBtn: 'button' | 'submit' | 'reset' | 'submit' = 'button'; @Input() color: string = 'primary'; constructor() {} ngOnInit(): void {} get colors() { const colorsList: { [key: string]: string } = { success: 'bg-success-700 hover:bg-success-800 focus:ring-success-300', danger: 'bg-red-700 hover:bg-red-800 focus:ring-red-300', primary: 'bg-primary-700 hover:bg-primary-800 focus:ring-primary-300', }; return colorsList[this.color]; } }
De esta forma el getter es mas legible y evitas tener muchas lineas de codigo:
get colors() { return { 'bg-success-700 hover:bg-success-800 focus:ring-success-300': this.colorBtn === 'success', 'bg-primary-700 hover:bg-primary-800 focus:ring-primary-300': this.colorBtn === 'primary', 'bg-red-700 hover:bg-red-800 focus:ring-red-300': this.colorBtn === 'red', } }
Por donde lo veo esto es bueno y malo
Malo
Porque si querías algo dinámico no vale como tal, a menos que este definido
Bueno
Porque me permite tener una paleta de colores establecida para la app
No se que opine Nico, pero aquí dejo una opción un poco más limpia:
export class BtnComponent { @Input() type: 'submit' | 'button' | 'reset' = 'button'; @Input() color: 'primary' | 'success' | 'danger' = 'primary'; colorClass = { primary: 'bg-primary-500 hover:bg-primary-800 focus:ring-primary-300', success: 'bg-success-500 hover:bg-success-800 focus:ring-success-300', danger: 'bg-red-500 hover:bg-red-800 focus:ring-red-300' } get colors() { return this.colorClass[this.color]; } ```export class BtnComponent { @Input() type: 'submit' | 'button' | 'reset' = 'button'; @Input() color: 'primary' | 'success' | 'danger' = 'primary'; colorClass = { primary: 'bg-primary-500 hover:bg-primary-500 focus:ring-primary-500', success: 'bg-success-500 hover:bg-success-500 focus:ring-success-500', danger: 'bg-danger-500 hover:bg-danger-500 focus:ring-danger-500' }   get colors() { return this.colorClass\[this.color]; }}
Si tienen problemas en la aplicación del tema de colores o plugins del forms en el css añadir
@config "./tailwind.config.js";
@import "tailwindcss";
y en la raiz del src añadir el tailwind.config.js les dejo el codigo si les sirve const colors = require('tailwindcss/colors');
module.exports = {
content: [
"./src/**/*.{html,ts}",
],
theme: {
extend: {
colors: {
success: colors.green,
primary: colors.blue,
danger: colors.red,
}
},
},
plugins: [
require('@tailwindcss/forms'),
],
}
Mi propuesta:
<button
class="w-full font-medium rounded text-sm p-2 text-white"
[type]="type"
[ngClass]="{
'bg-green-600 hover:bg-green-700 ' : varyant === 'success',
'bg-red-700 hover:bg-red-800' : varyant === 'error',
'bg-yellow-600 hover:bg-yellow-700' : varyant === 'alert'
}"
>
<ng-content></ng-content>
</button>
import { Component, Input } from '@angular/core';
import { NgClass } from '@angular/common';
@Component({
selector: 'app-btn',
standalone: true,
templateUrl: './btn.html',
styleUrl: './btn.css',
imports: [NgClass],
})
export class Btn {
@Input() type?: 'button' | 'submit' | 'reset' = 'button';
@Input() varyant?: 'success' | 'error' | 'alert' = 'success';
}
<app-btn
class="block w-full"
type="submit"
varyant="success"
>
Login
</app-btn>
No seria mejor por ejemplo algo como esto: :root { --color-fondo: #007bff; /* Azul por defecto */ }
.primary, .success { background-color: var(--color-fondo); color: white; }
.success { --color-fondo: #28a745; /* Verde para el botón éxito */ } Donde solo llamamos a una clase y reasignamos el valor ?
claro eso sería lo más fácil para un solo elemento, pero como queremos cambiar sus propiedades según se necesite más adelante he allí la complicación y la necesidad de declarar múltiples estilos para un solo componente, en donde solo se le cambiara el tipo de botón y el color; ósea se hizo todo eso para más adelante no volver a hacer todo el botón.
También puedes lograr esto sin Tailwind, al igual que en la clase debemos crear un get con nuestras clases de css.
Button.css
button { transition: transform 300ms ease-out, background-color 300ms ease-in; font-weight: 600; } button:active { transform: scale(.95); } .primary.full { background-color: var(--primary); color: var(--primary-foreground); &:hover { background-color: var(--primary-hover); } } .primary.outline { outline-color: var(--primary); } .red.full { background-color: var(--color-red-700); color: var(--color-white); } .red.outline { outline-color: var(--color-red-700); }
Button.ts
import { CommonModule } from '@angular/common'; import { Component, Input } from '@angular/core'; export type TypeButton = 'submit' | 'button' | 'reset'; // las variantes y los colores deben coincidir con lo que tenemos en nuestro css export type VariantButton = 'full' | 'outline'; export type ColorsButton = 'primary' | 'red'; @Component({ selector: 'component-button', imports: [CommonModule], templateUrl: './button.html', styleUrl: './button.css', }) export class Button { @Input({ required: false }) type: TypeButton = 'button'; @Input({ required: false }) class: string = ''; @Input({ required: false }) variant: VariantButton = 'full'; @Input({ required: false }) color: ColorsButton = 'primary'; get buttonClasses() { return { [this.class]: true, [this.variant]: true, [this.color]: true, }; } }
Button.html
<button [type]="type" [ngClass]="buttonClasses"> <ng-content></ng-content> </button>
import { NgClass } from '@angular/common'; import { Component, computed, input } from '@angular/core'; @Component({ selector: 'app-btn', imports: [NgClass], templateUrl: './btn.html' }) export class Btn { readonly type = input.required<'button' | 'submit' | 'reset'>(); readonly color = input<'success' | 'warning' | 'error' | 'primary' | 'secondary'>('primary'); clases = computed(() => { const color = this.color(); if (!color) return; return { 'bg-success-700': color === 'success', 'bg-warning-700': color === 'warning', 'bg-error-700': color === 'error', 'bg-primary-700': color === 'primary', 'bg-secondary-700': color === 'secondary', 'hover:bg-success-800': color === 'success', 'hover:bg-warning-800': color === 'warning', 'hover:bg-error-800': color === 'error', 'hover:bg-primary-800': color === 'primary', 'hover:bg-secondary-800': color === 'secondary', 'focus:ring-success-300': color === 'success', 'focus:ring-warning-300': color === 'warning', 'focus:ring-error-300': color === 'error', 'focus:ring-primary-300': color === 'primary', 'focus:ring-secondary-300': color === 'secondary' }; }); }
no seria mejor manejar var()?
No, no sería mejor manejar var(). El uso de var sin paréntesis es la forma correcta de declarar variables implícitamente en C#. Var() no es una sintaxis válida.
Por alguna razón no se renderizan los colores y quizás también el tipo submit. Lo extraño es que en la consola si aparecen las propiedades. Intente con los 3 colores, hasta intente utilizar otro color en la consola y no funciona. Alguna idea de como puedo solucionar este extraño fallo?
/** @type {import('tailwindcss').Config} */ const colors = require('tailwindcss/colors'); module.exports = { purge: { content: ["./src/**/*.{html,js}"], options: { safelist: [ 'bg-success-700', 'hover:bg-success-800', 'focus:ring-success-300', 'bg-primary-700', 'hover:bg-primary-800', 'focus:ring-primary-300', 'bg-red-700', 'hover:bg-red-800', 'focus:ring-red-300', 'text-white' ] } }, theme: { extend: { colors:{ success: colors.green, primary: colors.blue, red: colors.red, } }, }, plugins: [ require('@tailwindcss/forms'), ], }
Hola a todos, Habra alguna forma de retornar mapa de colores personalizados quizas poniendo un alias a las clases de tailwindcss...
Para los que vengan de Angular 19, esta seria mi solución adaptada a la forma moderna:
no se si es por la versión en la que esta tailwindcss pero si no uso las clases que declaramos en get colors antees de llamar al button estpan no se aplican
hola , use esto en en el archivo tailwind.config.js y se soluciono :
/** @type {import('tailwindcss').Config} */ const colors = require('tailwindcss/colors'); module.exports = { purge: { content: ["./src/**/*.{html,js}"], options: { safelist: [ 'bg-success-700', 'hover:bg-success-800', 'focus:ring-success-300', 'bg-primary-700', 'hover:bg-primary-800', 'focus:ring-primary-300', 'bg-red-700', 'hover:bg-red-800', 'focus:ring-red-300', 'text-white' ] } }, theme: { extend: { colors:{ success: colors.green, primary: colors.blue, red: colors.red, } }, }, plugins: [ require('@tailwindcss/forms'), ], }
Recuerden importar el módulo CommonModule en btn.component.ts para que les pueda traer de ángular los módulos propios para que en el inspector se pueda revisar
voy a probar este framework css y les cuento como me va... no me parece eso que no le pueda pasar el nombre por parámetro... tal vez volviendo a construir el html se pueda.. nunca me ha pasado pero me gustan los retos ya les cuento..
dejé asi mi componente btn
<button [type]="typeBtn" class="w-full">
<ng-content></ng-content>
</button>
y en mi componente login así.
<div class="w-full"> <app-btn [typeBtn]="'submit'" class="bg-success text-white rounded font-medium text-sm py-2"> Log In </app-btn> </div>
Tambien podemos usar ngClass en el html, en mi opinión se ve más ordenado:
<button class="w-full text-center py-3 text-white font-medium rounded-md" [disabled]="this.isDisabled" [ngClass]="{ 'bg-primary': this.moodButton == 'main', 'bg-red-500 cursor-not-allowed': this.moodButton == 'dangerous', 'bg-slate-500 cursor-not-allowed': this.moodButton === 'disabled'}" [type]="this.typeButton"> <ng-content></ng-content> </button> ```y en nuestro componente: ```js import { Component, Input, OnInit } from '@angular/core'; type typeBtn = 'submit' | 'button' | 'reset'; type moodBtn = 'dangerous' | 'main' |'disabled'; @Component({ selector: 'app-button', templateUrl: './button.component.html', }) export class ButtonComponent implements OnInit{ // typeButton para saber que tipo de boton es @Input() typeButton: typeBtn = 'button'; // moodButton es un input para saber que estilos debemos agregar a nuestro boton, usamos los type para tener un buen tipado. @Input() moodButton: moodBtn = 'main'; // isDisabled para cuando el boton tiene el mood "disabled". public isDisabled!: boolean; ngOnInit(): void { this.moodButton == 'disabled' ? this.isDisabled = true : this.isDisabled = false; } }