Adding a Widget to upp-wdgt
This guide describes how to add a new reusable component to the upp-wdgt library.
Process Overview
Step 1 — Create the Component Files
Create a folder under libs/upp-wdgt/src/components/ with the naming convention upp-<name>/:
libs/upp-wdgt/src/components/upp-<name>/
├── upp-<name>.ts ← Component class(es)
├── upp-<name>.html ← Template
└── upp-<name>.scss ← Styles
Component class template
import { Component } from '@angular/core';
import { Input } from '@angular/core';
@Component({
selector: 'upp-<name>',
templateUrl: './upp-<name>.html',
styleUrls: ['./upp-<name>.scss'],
})
export class Upp<Name>Component {
@Input() title: string | null = null;
}
Follow existing conventions:
- Use
selector: 'upp-<name>'with theupp-prefix. - Reference the template and styles using relative paths.
- If the component uses sub-components (e.g.
upp-<name>-header), define them in the same.tsfile and export them individually.
Step 2 — Declare in the Module
Open libs/upp-wdgt/src/lib/upp-wdgt.module.ts and:
- Import the component:
import { Upp<Name>Component } from '../components/upp-<name>/upp-<name>';
- Add to
declarations:
declarations: [
// ... existing components
Upp<Name>Component,
],
- Add to
exports(if the component should be publicly usable):
exports: [
// ... existing exports
Upp<Name>Component,
],
Step 3 — Export from index.ts
Add a re-export line to libs/upp-wdgt/src/index.ts:
export * from './components/upp-<name>/upp-<name>';
This makes the component available to consumers via:
import { Upp<Name>Component } from '@unpispas/upp-wdgt';
Step 4 — Styling
Component styles
Each component has its own .scss file. Use the component's selector as a :host context:
:host {
display: block;
}
Theme integration
If the component introduces new CSS custom properties or needs global theme tokens, add them to libs/upp-wdgt/src/styles/theme.scss. Reference existing variables from this file for colours, spacing, and typography.
Ionic integration
The module imports IonicModule, so you can freely use Ionic components (ion-button, ion-icon, ion-item, etc.) in your templates. Use the CUSTOM_ELEMENTS_SCHEMA (already registered in the module) to suppress unknown-element warnings for Ionic web components.
Step 5 — Multiple Components in One File
The library convention is to keep related components (parent + children for content projection) in a single .ts file. For example, upp-panel.ts exports UppPanelComponent, UppPanelHeaderComponent, UppPanelContentComponent, and UppPanelFooterComponent.
When doing this:
- Export each class individually.
- Import each one separately in the module file.
Step 6 — ControlValueAccessor (for form widgets)
If the new widget needs form integration, implement ControlValueAccessor:
import { forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'upp-<name>',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => Upp<Name>Component),
multi: true,
},
],
})
export class Upp<Name>Component implements ControlValueAccessor {
writeValue(value: any) { /* ... */ }
registerOnChange(fn: any) { /* ... */ }
registerOnTouched(fn: any) { /* ... */ }
}
See UppInputComponent or UppSelectComponent for complete examples.
Checklist
- Component files created under
libs/upp-wdgt/src/components/upp-<name>/ - Component declared and exported in
UppWdgtModule - Re-exported from
libs/upp-wdgt/src/index.ts - Styles follow the theme conventions
- JSDoc/TSDoc documentation on the class and inputs
- If form-integrated:
ControlValueAccessorimplemented