Skip to content

iXsystems/truenas-ui-components

Repository files navigation

TrueNAS-UI Components

An Angular UI component library for TrueNAS and related software. Includes reusable components, comprehensive theming, and automatic icon sprite generation.

Installation

For Consumers

# Install latest version
npm install @truenas/ui-components

# Or with yarn
yarn add @truenas/ui-components

# Install specific version
npm install @truenas/[email protected]

For Contributors

git clone [email protected]:iXsystems/truenas-ui-components.git
cd truenas-ui-components
yarn install

Quick Start

Using Components

Import components in your Angular application:

import { TnButtonComponent, TnInputComponent } from '@truenas/ui-components';

@Component({
  selector: 'app-example',
  standalone: true,
  imports: [TnButtonComponent, TnInputComponent],
  template: `
    <tn-button variant="primary">Click me</tn-button>
    <tn-input label="Username" placeholder="Enter username"></tn-input>
  `
})
export class ExampleComponent {}

Including Themes

Add the theme CSS to your angular.json:

{
  "styles": [
    "node_modules/@truenas/ui-components/src/styles/themes.css",
    "src/styles.css"
  ]
}

Apply a theme by adding the theme class to your document root:

document.documentElement.classList.add('tn-dark');

Available themes: tn-dark, tn-blue, dracula, nord, paper, solarized-dark, midnight, high-contrast

Development

Prerequisites

  • Node.js >= 18.19.1
  • Yarn >= 4.10.3 (Yarn Berry)
  • Angular 20

Development Commands

yarn run sb           # Start Storybook (localhost:6006)
yarn build            # Build the library
yarn test             # Run Jest tests
yarn test-coverage    # Run tests with coverage
yarn icons            # Generate icon sprite

Building the Library

# Build the library
ng build truenas-ui

# Create distributable package
cd dist/truenas-ui && npm pack

The build output is located in dist/truenas-ui/ and includes compiled modules, TypeScript declarations, styles, and assets.

Icon System

The library includes an automatic sprite generation system. Mark icons in your code and they'll be automatically included in the sprite:

import { tnIconMarker } from '@truenas/ui-components';

// MDI icons
tnIconMarker('folder', 'mdi');

// Material icons
tnIconMarker('home', 'material');

// Custom icons
tnIconMarker('dataset', 'custom');

Use icons in templates:

<tn-icon name="folder" library="mdi"></tn-icon>
<tn-icon name="dataset" library="custom"></tn-icon>

Generate the sprite in your application:

yarn icons

Storybook

View component documentation and examples:

yarn run sb

Storybook provides:

  • Interactive component playground
  • Complete design system documentation
  • Accessibility testing (via @storybook/addon-a11y)
  • Code examples and usage guidelines

Testing

yarn test              # Run all Jest tests
yarn test-cc           # Clear cache and run tests
yarn test-coverage     # Generate coverage report
yarn test-sb           # Run Storybook interaction tests

Testing Components with Icons

When testing components that use TnIconComponent, use TnIconTesting.jest.providers() to avoid manual mocking:

import { TnIconTesting } from '@truenas/ui-components';

await TestBed.configureTestingModule({
  imports: [YourComponent],
  providers: [
    TnIconTesting.jest.providers()
  ]
}).compileComponents();

This replaces the need for manual mocking like:

// ❌ Don't do this anymore
mockProvider(TnSpriteLoaderService, {
  ensureSpriteLoaded: jest.fn(() => Promise.resolve(true)),
  getIconUrl: jest.fn(),
  // ... more boilerplate
}),

For advanced testing scenarios, you can customize the mocks by passing overrides:

import { TnIconTesting } from '@truenas/ui-components';

await TestBed.configureTestingModule({
  imports: [YourComponent],
  providers: [
    TnIconTesting.jest.providers({
      spriteLoader: {
        getIconUrl: jest.fn(() => '#custom-icon')
      },
      iconRegistry: {
        resolveIcon: jest.fn(() => ({
          source: 'sprite',
          spriteUrl: '#my-icon'
        }))
      }
    })
  ]
}).compileComponents();

Benefits:

  • Creates fresh mock instances on each call (no test pollution)
  • Icons render as SVG (no fallback text interfering with assertions)
  • Simple API for the common case, flexible for advanced needs

Note: The API is designed to support other testing frameworks in the future (e.g., TnIconTesting.vitest.providers()).

Contributing

See CONTRIBUTE.md for detailed development guidelines, including:

  • Icon system documentation
  • Component development workflow
  • Testing best practices
  • Code style conventions

Peer Dependencies

This library requires Angular 20:

{
  "@angular/animations": "^20.0.0",
  "@angular/cdk": "^20.0.0",
  "@angular/common": "^20.0.0",
  "@angular/core": "^20.0.0",
  "@angular/forms": "^20.0.0",
  "@angular/platform-browser": "^20.0.0",
  "@angular/platform-browser-dynamic": "^20.0.0",
  "@angular/router": "^20.0.0",
  "rxjs": "^7.5.0",
  "zone.js": "^0.15.0"
}

Distribution

The library is published to npm:

  • Releases are automated — merging a PR to main with library code changes triggers a new npm publish
  • Version bumps are determined by conventional commit types in PR titles (e.g., feat:, fix:)
  • GitHub Releases with release notes are created automatically via Semantic Release
  • Consumers install via npm install @truenas/ui-components
  • See CONTRIBUTE.md for the full commit message guide

License

TBD

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors