diff --git a/apps/docs/docs/components/badge/_dismissable.component.html b/apps/docs/docs/components/badge/_dismissable.component.html new file mode 100644 index 00000000..01dc07bb --- /dev/null +++ b/apps/docs/docs/components/badge/_dismissable.component.html @@ -0,0 +1,53 @@ + + Default + + + Primary + + + Blue + + + Red + + + Green + + + Yellow + + + Indigo + + + Purple + + + Pink + diff --git a/apps/docs/docs/components/badge/_dismissable.component.ts b/apps/docs/docs/components/badge/_dismissable.component.ts new file mode 100644 index 00000000..7cf50744 --- /dev/null +++ b/apps/docs/docs/components/badge/_dismissable.component.ts @@ -0,0 +1,15 @@ +import { BadgeComponent } from 'flowbite-angular/badge'; + +import { Component } from '@angular/core'; + +@Component({ + selector: 'flowbite-demo-badge-dismissable', + imports: [BadgeComponent], + templateUrl: './_dismissable.component.html', + host: { + class: 'flex flex-wrap flex-row gap-3', + }, +}) +export class FlowbiteDismissableComponent { + onDismiss = () => alert('Badge have been dismissed'); +} diff --git a/apps/docs/docs/components/badge/index.md b/apps/docs/docs/components/badge/index.md index 7f456e43..4dcecb25 100644 --- a/apps/docs/docs/components/badge/index.md +++ b/apps/docs/docs/components/badge/index.md @@ -73,3 +73,19 @@ keyword: BadgePage ```angular-ts file="./_icon-only.component.ts"#L1-L2 group="icon-only" name="typescript" ``` + +## Dismissable badge + +{{ NgDocActions.demo('flowbiteDismissableComponent', {container: false}) }} + +```angular-html file="./_dismissable.component.html" group="dismissable" name="html" + +``` + +```angular-ts file="./_dismissable.component.ts"#L1-L1 group="dismissable" name="typescript" + +``` + +```angular-ts file="./_dismissable.component.ts"#L14 group="dismissable" name="typescript" + +``` diff --git a/apps/docs/docs/components/badge/ng-doc.page.ts b/apps/docs/docs/components/badge/ng-doc.page.ts index 24a9eb74..7b3188e5 100644 --- a/apps/docs/docs/components/badge/ng-doc.page.ts +++ b/apps/docs/docs/components/badge/ng-doc.page.ts @@ -1,6 +1,7 @@ import ComponentCategory from '../ng-doc.category'; import { FlowbiteBorderedComponent } from './_bordered.component'; import { FlowbiteDefaultComponent } from './_default.component'; +import { FlowbiteDismissableComponent } from './_dismissable.component'; import { FlowbiteIconOnlyComponent } from './_icon-only.component'; import { FlowbiteIconComponent } from './_icon.component'; import { FlowbiteLargeComponent } from './_large.component'; @@ -25,6 +26,7 @@ const badge: NgDocPage = { flowbiteIconComponent: FlowbiteIconComponent, flowbiteLargeComponent: FlowbiteLargeComponent, flowbiteLinkComponent: FlowbiteLinkComponent, + flowbiteDismissableComponent: FlowbiteDismissableComponent, }, }; diff --git a/libs/flowbite-angular/badge/badge.component.ts b/libs/flowbite-angular/badge/badge.component.ts index 9ef5b4c7..375d0cfb 100644 --- a/libs/flowbite-angular/badge/badge.component.ts +++ b/libs/flowbite-angular/badge/badge.component.ts @@ -3,7 +3,9 @@ import { BadgeThemeService } from './badge.theme.service'; import type { DeepPartial } from 'flowbite-angular'; import { BaseComponent, booleanToFlowbiteBoolean } from 'flowbite-angular'; +import { IconComponent, IconRegistry } from 'flowbite-angular/icon'; import { FlowbiteRouterLinkDirective } from 'flowbite-angular/router-link'; +import { CLOSE_SVG_ICON } from 'flowbite-angular/utils'; import { ChangeDetectionStrategy, @@ -14,6 +16,7 @@ import { model, ViewEncapsulation, } from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser'; export const FLOWBITE_BADGE_COLOR_DEFAULT_VALUE = new InjectionToken( 'FLOWBITE_BADGE_COLOR_DEFAULT_VALUE' @@ -39,6 +42,14 @@ export const FLOWBITE_BADGE_CUSTOM_STYLE_DEFAULT_VALUE = new InjectionToken< DeepPartial >('FLOWBITE_BADGE_CUSTOM_STYLE_DEFAULT_VALUE'); +export const FLOWBITE_BADGE_IS_DISMISSABLE_DEFAULT_VALUE = new InjectionToken( + 'FLOWBITE_BADGE_IS_DISMISSABLE_DEFAULT_VALUE' +); + +export const FLOWBITE_BADGE_ON_DISMISS_DEFAULT_VALUE = new InjectionToken<(() => void) | undefined>( + 'FLOWBITE_BADGE_ON_DISMISS_DEFAULT_VALUE' +); + export const badgeDefaultValueProvider = makeEnvironmentProviders([ { provide: FLOWBITE_BADGE_COLOR_DEFAULT_VALUE, @@ -64,6 +75,14 @@ export const badgeDefaultValueProvider = makeEnvironmentProviders([ provide: FLOWBITE_BADGE_CUSTOM_STYLE_DEFAULT_VALUE, useValue: {}, }, + { + provide: FLOWBITE_BADGE_IS_DISMISSABLE_DEFAULT_VALUE, + useValue: false, + }, + { + provide: FLOWBITE_BADGE_ON_DISMISS_DEFAULT_VALUE, + useValue: undefined, + }, ]); /** @@ -71,8 +90,23 @@ export const badgeDefaultValueProvider = makeEnvironmentProviders([ */ @Component({ standalone: true, + imports: [IconComponent], selector: 'flowbite-badge', - template: ``, + template: ` + + @if (isDismissable()) { + + } + `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, }) @@ -85,6 +119,14 @@ export class BadgeComponent extends BaseComponent { * Service injected used to generate class */ public readonly themeService = inject(BadgeThemeService); + /** + * `IcoRegistry` service + */ + public readonly iconRegistry = inject(IconRegistry); + /** + * `DomSanitizer` service + */ + public readonly domSanitizer = inject(DomSanitizer); //#region properties /** @@ -95,6 +137,8 @@ export class BadgeComponent extends BaseComponent { public color = model(inject(FLOWBITE_BADGE_COLOR_DEFAULT_VALUE)); /** * Set if the badge has border + * + * @default false */ public hasBorder = model(inject(FLOWBITE_BADGE_HAS_BORDER_DEFAULT_VALUE)); /** @@ -119,6 +163,18 @@ export class BadgeComponent extends BaseComponent { * Set the custom style for this badge */ public customStyle = model(inject(FLOWBITE_BADGE_CUSTOM_STYLE_DEFAULT_VALUE)); + /** + * Set if the badge is dismissable + * + * @default false + */ + public isDismissable = model(inject(FLOWBITE_BADGE_IS_DISMISSABLE_DEFAULT_VALUE)); + /** + * Set the function called when the badge is dismissed + * + * @default undefined + */ + public onDismiss = model(inject(FLOWBITE_BADGE_ON_DISMISS_DEFAULT_VALUE)); //#endregion //#region BaseComponent implementation @@ -133,5 +189,22 @@ export class BadgeComponent extends BaseComponent { customStyle: this.customStyle(), }); } + + public override init(): void { + this.iconRegistry.addRawSvgIconInNamepsace( + 'flowbite-angular', + 'close', + this.domSanitizer.bypassSecurityTrustHtml(CLOSE_SVG_ICON) + ); + } //#endregion + + /** + * Call the onDismiss function if it's not undefined + */ + public onDismissClick() { + const func = this.onDismiss(); + + if (func) func(); + } } diff --git a/libs/flowbite-angular/badge/badge.theme.service.ts b/libs/flowbite-angular/badge/badge.theme.service.ts index 8870781b..092244a9 100644 --- a/libs/flowbite-angular/badge/badge.theme.service.ts +++ b/libs/flowbite-angular/badge/badge.theme.service.ts @@ -41,6 +41,7 @@ export class BadgeThemeService implements FlowbiteThemeService theme.root.isIconOnly[properties.isIconOnly], theme.root.link[properties.link ? 'enabled' : 'disabled'] ), + closeButtonClass: twMerge(theme.closeButton.base, theme.closeButton.color[properties.color]), }; return output; diff --git a/libs/flowbite-angular/badge/badge.theme.ts b/libs/flowbite-angular/badge/badge.theme.ts index ee6dc1c3..bb4babbb 100644 --- a/libs/flowbite-angular/badge/badge.theme.ts +++ b/libs/flowbite-angular/badge/badge.theme.ts @@ -54,6 +54,10 @@ export interface BadgeTheme { isIconOnly: FlowbiteBoolean; link: FlowbiteBoolean; }; + closeButton: { + base: string; + color: BadgeColors; + }; } /** @@ -99,9 +103,26 @@ export const badgeTheme: BadgeTheme = createTheme({ disabled: 'px-2 py-0.5', }, }, + closeButton: { + base: 'ms-1 inline-flex items-center rounded-sm p-1 focus:ring-2', + color: { + primary: + 'text-primary-500 dark:text-primary-600 hover:bg-primary-200 dark:hover:bg-primary-300', + dark: 'text-gray-500 dark:text-gray-600 hover:bg-gray-200 dark:hover:bg-gray-300', + blue: 'text-blue-500 dark:text-blue-600 hover:bg-blue-200 dark:hover:bg-blue-300', + red: 'text-red-500 dark:text-red-600 hover:bg-red-200 dark:hover:bg-red-300', + green: 'text-green-500 dark:text-green-600 hover:bg-green-200 dark:hover:bg-green-300', + yellow: 'text-yellow-500 dark:text-yellow-600 hover:bg-yellow-200 dark:hover:bg-yellow-300', + indigo: 'text-indigo-500 dark:text-indigo-600 hover:bg-indigo-200 dark:hover:bg-indigo-300', + purple: 'text-purple-500 dark:text-purple-600 hover:bg-purple-200 dark:hover:bg-purple-300', + pink: 'text-pink-500 dark:text-pink-600 hover:bg-pink-200 dark:hover:bg-pink-300', + }, + }, }); /** * Generated class definition for `BadgeComponent` */ -export type BadgeClass = FlowbiteClass; +export interface BadgeClass extends FlowbiteClass { + closeButtonClass: string; +}