@arpudhabotupload/fn-button
v1.0.13
Published
Angular standalone button component with built-in SVG icon support and Tailwind CSS styling
Maintainers
Readme
@arpudhabotupload/fn-button
A standalone Angular button component with built-in SVG icon support and Tailwind CSS styling.
Features
- ✅ Standalone Component - Built with Angular standalone component (no modules required)
- 🎨 Tailwind CSS Styling - Pre-configured with Tailwind CSS utility classes
- 🔘 Multiple Button Sizes - Small, Medium, Large, and Docked variants
- 🎯 Severity Variants - Primary, Secondary, and Tertiary styles
- 🚨 State Management - Default, Disabled, and Destructive states
- 🔄 Loading State - Built-in loading indicator support
- 🖼️ Built-in Icon Support - Integrated SVG icon loading and rendering
- 🌐 i18n Ready - Uses
@ngx-translate/corefor label translation - 📱 Accessibility - Full ARIA support and keyboard navigation
- 📦 Single Component - Everything you need in one component
Installation
npm install @arpudhabotupload/fn-button @ngx-translate/coreThis component library uses Tailwind utility classes in its template. Tailwind CSS must be configured in the consuming Angular app for styles to render correctly.
Install Tailwind in your app:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss initPeer Dependencies
This library requires the following peer dependencies:
{
"@angular/common": ">=18.0.0",
"@angular/core": ">=18.0.0",
"@ngx-translate/core": "^15.0.0 || ^16.0.0"
}Note: The button component renders icons from your local assets folder when icon is set. Make sure your icon assets follow this structure:
assets/icons/Line/16px/icon-name.svgassets/icons/Line/20px/icon-name--20.svgassets/icons/Line/24px/icon-name--24.svg
Setup
1. Import the Component
Since this is a standalone component, you can import it directly in your component:
import { Component } from '@angular/core';
import { FNButton } from '@arpudhabotupload/fn-button';
@Component({
selector: 'app-root',
standalone: true,
imports: [FNButton],
template: `
<fn-button
label="Click me"
(buttonClick)="handleClick($event)">
</fn-button>
`,
})
export class AppComponent {
handleClick(event: MouseEvent) {
console.log('Button clicked!', event);
}
}2. Configure Tailwind CSS (Required)
Add the library path to your tailwind.config.js:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src/**/*.{html,ts}",
"./node_modules/@arpudhabotupload/fn-button/**/*.{html,ts,js,mjs}",
],
theme: {
extend: {},
},
plugins: [],
}Ensure your global stylesheet includes Tailwind directives:
@tailwind base;
@tailwind components;
@tailwind utilities;3. Import Component Styles
The library ships a pre-built CSS file containing all the CSS custom property (variable) definitions required for button colors, borders, and states.
Important: Use the exported subpath
@arpudhabotupload/fn-button/styles.css. Do not use@arpudhabotupload/fn-button/src/styles.css— that path is not exported and will cause a bundler error.
Option A — CSS global stylesheet (src/styles.css)
/* src/styles.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
@import '@arpudhabotupload/fn-button/styles.css';Place the
@importafter Tailwind directives to avoid any ordering issues.
Option B — SCSS global stylesheet (src/styles.scss)
// src/styles.scss
@use 'tailwindcss/base';
@use 'tailwindcss/components';
@use 'tailwindcss/utilities';
@import '@arpudhabotupload/fn-button/styles.css';Option C — Via angular.json styles array
If you prefer not to use @import in your stylesheet, register the file in angular.json:
"projects": {
"your-app": {
"architect": {
"build": {
"options": {
"styles": [
"src/styles.css",
"node_modules/@arpudhabotupload/fn-button/src/styles.css"
]
}
}
}
}
}Option D — Define your own CSS variables (skip the import entirely)
If you have a custom design system, skip the import and define the variables yourself:
:root {
/* Base Colors */
--Base-0: #ffffff;
--Base-10: #eef0f2;
--Base-30: #c4cdd2;
--Base-50: #818c95;
/* Primary Blue */
--RHB-Blue-100: #0067b1;
--RHB-Blue-200: #0158a0;
--RHB-Light-Blue-10: #eff9fd;
/* Destructive Red */
--RHB-Red-100: #ef3e42;
--RHB-Red-200: #d72f32;
--RHB-Red-10: #ffeeee;
}The component reads these CSS variables at runtime, so any values you set here will be reflected automatically in all button variants and states.
4. Setup Translation Module (Optional)
If you want to use the label input with translations:
import { ApplicationConfig, importProvidersFrom } from '@angular/core';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { HttpClient, provideHttpClient } from '@angular/common/http';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http);
}
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(),
importProvidersFrom(
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient],
},
})
),
],
};5. Setup Icon Assets
The button resolves icons from your app assets. Set up your icon files like this:
public/
assets/
icons/
Line/
16px/
icon-name.svg
20px/
icon-name--20.svg
24px/
icon-name--24.svgThe component maps sizes as follows:
small->16px->icon-name.svgmedium->20px->icon-name--20.svglargeanddocked->24px->icon-name--24.svg
Usage Examples
Basic Button
<!-- Plain text button -->
<fn-button label="Click me"></fn-button>
<!-- Using projected content (no ngx-translate needed) -->
<fn-button>Click me</fn-button>Note on
label: Thelabelinput is passed throughngx-translate'stranslatepipe, so it works as a translation key. If@ngx-translate/coreis not configured in your app, the value is rendered as-is (plain text). For apps without i18n, you can also use Angular content projection:<fn-button>Save</fn-button>
Button with Icon
<fn-button
label="Save"
icon="check"
iconPos="left">
</fn-button>Icon Only Button
<fn-button
icon="settings"
ariaLabel="Settings">
</fn-button>Different Sizes
<fn-button label="Small" size="small"></fn-button>
<fn-button label="Medium" size="medium"></fn-button>
<fn-button label="Large" size="large"></fn-button>
<fn-button label="Docked" size="docked"></fn-button>Severity Variants
<fn-button label="Primary" severity="primary"></fn-button>
<fn-button label="Secondary" severity="secondary"></fn-button>
<fn-button label="Tertiary" severity="tertiary"></fn-button>States
<fn-button label="Default" state="default"></fn-button>
<fn-button label="Disabled" state="disabled"></fn-button>
<fn-button label="Destructive" state="destructive"></fn-button>Loading State
<fn-button
label="Save"
[loading]="isLoading"
(buttonClick)="save()">
</fn-button>Custom Styling
<fn-button
label="Custom"
class="my-custom-class"
[style]="getCustomStyle">
</fn-button>getCustomStyle = (target: string) => {
if (target === 'button') {
return { boxShadow: '0 4px 6px rgba(0,0,0,0.1)' };
}
return {};
};Using Content Template
<fn-button [contentTemplate]="customContent"></fn-button>
<ng-template #customContent>
<span>Custom Content</span>
</ng-template>API Reference
FNButton Component
Inputs
| Input | Type | Default | Description |
|-------|------|---------|-------------|
| type | 'button' \| 'submit' \| 'reset' | 'button' | HTML button type |
| icon | string | undefined | Icon name (without extension) |
| iconPos | 'left' \| 'right' | 'left' | Icon position |
| iconColor | string | undefined | Custom icon color (CSS color value or variable name) |
| label | string | undefined | Button label (will be translated) |
| disabled | boolean | false | Disable the button |
| loading | boolean | false | Show loading state |
| loadingIcon | string | undefined | Custom loading icon class |
| tabindex | number \| null | null | Tab index for keyboard navigation |
| size | 'small' \| 'medium' \| 'large' \| 'docked' | 'medium' | Button size |
| severity | 'primary' \| 'secondary' \| 'tertiary' | 'primary' | Button style variant |
| state | 'default' \| 'disabled' \| 'destructive' | 'default' | Button state |
| style | (target: string) => object | undefined | Custom style function |
| class | string | '' | Additional CSS classes |
| ariaLabel | string | undefined | ARIA label for accessibility |
| autofocus | boolean | false | Auto focus on mount |
| contentTemplate | TemplateRef<any> | undefined | Custom content template |
| iconTemplate | TemplateRef<any> | undefined | Custom icon template |
| loadingIconTemplate | TemplateRef<any> | undefined | Custom loading icon template |
Outputs
| Output | Type | Description |
|--------|------|-------------|
| buttonClick | EventEmitter<MouseEvent> | Emitted when button is clicked |
| buttonFocus | EventEmitter<FocusEvent> | Emitted when button receives focus |
| buttonBlur | EventEmitter<FocusEvent> | Emitted when button loses focus |
Built-in Icon Support
The button component renders icons using a native <img> element resolved from your app's local assets folder. No additional icon package is required.
How Icon Paths Are Resolved
When you set the icon input, the component builds a path based on the button size:
| Size | Resolved path |
|------|---------------|
| small | assets/icons/Line/16px/{icon}.svg |
| medium | assets/icons/Line/20px/{icon}--20.svg |
| large / docked | assets/icons/Line/24px/{icon}--24.svg |
Icon Assets Directory Structure
Place your SVG icon files under public/assets/icons/ (Angular 17+) or src/assets/icons/ (Angular 16 and below):
assets/
icons/
Line/
16px/
arrow-right.svg
20px/
arrow-right--20.svg
24px/
arrow-right--24.svgIcon Features
The component automatically handles:
- Icon sizing: Maps button
sizeto the correct pixel folder (16 / 20 / 24px) - Icon color: Determined by
severity+state, or overridden withiconColoron tertiary buttons - Icon position: Left or right of the label via
iconPos; icon-only buttons render in a circular container - Custom icon template: Supply your own icon markup via
[iconTemplate]to replace the default<img>render
Icon Color Behaviour
| Severity | State | Icon color |
|----------|-------|------------|
| primary | any | --Base-0 (white) |
| secondary / tertiary | default | --RHB-Blue-100 |
| secondary / tertiary | disabled | --Base-50 |
| secondary / tertiary | destructive | --RHB-Red-100 |
To override the icon color on a tertiary button, use the iconColor input:
<!-- CSS variable name (var() wrapper is added automatically) -->
<fn-button severity="tertiary" icon="star" iconColor="RHB-Blue-100"></fn-button>
<!-- Explicit CSS value -->
<fn-button severity="tertiary" icon="star" iconColor="#0067b1"></fn-button>
<!-- Full var() expression -->
<fn-button severity="tertiary" icon="star" iconColor="var(--RHB-Red-100)"></fn-button>
iconColoris ignored forprimaryandsecondaryseverities.
Development
Build the Library
npm install
npm run buildPack for Testing
npm run packThis creates a .tgz file in the dist folder that you can install in another project:
npm install /path/to/arpudhabotupload-fn-button-1.0.10.tgzPublish to NPM
Build and publish in one step:
npm run releaseOr separately:
npm run build
npm run publish:distLicense
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Support
For issues and questions, please open an issue on the GitHub repository.
