@flusys/ng-ui
v9.1.0
Published
FLUSYS native UI component library
Readme
@flusys/ng-ui
Native Angular 22 UI component library for the FLUSYS platform — signal-based, standalone, zoneless-compatible, and Tailwind-friendly. No PrimeNG dependency; every component below is implemented natively in this package.
Installation
npm install @flusys/ng-ui @flusys/ng-coreAll components/directives are standalone — import them individually, or import UiModule for the full set (useful in non-standalone contexts or quick prototyping).
Setup
Register the theme initializer once in app.config.ts:
import { ApplicationConfig } from "@angular/core";
import { provideNgUI } from "@flusys/ng-ui";
export const appConfig: ApplicationConfig = {
providers: [
provideNgUI({
theme: {
preset: { preset: "violet", options: { darkModeSelector: ".app-dark" } },
},
translation: {
accept: "Yes",
reject: "No",
},
}),
],
};provideNgUI(options?: ProvideNgUIOptions) registers:
NgUIConfig— holds the translation/localization strings consumed internally by components (dialog buttons, date picker labels, upload labels, etc.). Override via thetranslationoption.- An
APP_INITIALIZERthat applies the CSS custom-property theme on bootstrap and re-applies dark/light semantics whenever.app-darkis toggled on<html>(viaMutationObserver).
ProvideNgUIOptions:
interface ProvideNgUIOptions {
theme?: {
preset?: ApplyThemeOptions | { preset: ApplyThemeOptions; options: { darkModeSelector?: string } };
options?: { darkModeSelector?: string };
};
translation?: NgUITranslationConfig;
ripple?: boolean;
}Two core services are provided at root and used implicitly by ToastComponent/ConfirmDialog:
import { MessageService, ConfirmationService } from "@flusys/ng-ui";
const messageService = inject(MessageService);
messageService.add({ severity: "success", summary: "Saved", detail: "Record updated." });
const confirmationService = inject(ConfirmationService);
confirmationService.confirm({
message: "Delete this record?",
header: "Confirm",
icon: "alert-triangle",
accept: () => doDelete(),
});Place <f-toast /> and <f-confirmdialog /> once near the root of your app shell to render messages/confirmations raised from anywhere via these services.
Theming
Theming is CSS-custom-property based (--f-* variables) — no SCSS recompilation needed to switch colors.
applyTheme
import { applyTheme } from "@flusys/ng-ui";
applyTheme({
preset: "Aura", // 'Aura' | 'Lara' | 'Nora'
primary: "violet", // any key of PRIMARY_PALETTES, or 'noir'
surface: "slate", // any key of SURFACE_PALETTES, or null for light/dark default
darkTheme: false,
});Lower-level appliers are also exported for partial updates: applyPrimaryPalette(palette, isDark?, root?), applySurfacePalette(palette, root?), applyPreset(preset, root?), applyLightSemantics(root?), applyDarkSemantics(root?).
Presets
import { PRESETS, PRESET_NAMES, AURA_PRESET, LARA_PRESET, NORA_PRESET } from "@flusys/ng-ui";
import type { PresetName, ThemePreset } from "@flusys/ng-ui";
PRESET_NAMES; // ['Aura', 'Lara', 'Nora']
PRESETS["Nora"]; // ThemePreset — border radius, shadows, focus ring, card + select-button tokensEach ThemePreset is a whole design language, not a palette. It controls the radius scale, border width, shadow scale, transition duration, focus ring, control density (field and button padding), button weight and tracking, overlay shape and elevation, card tokens, shell chrome (sidebar / topbar / active menu item), and select-button tokens.
| Preset | Language |
| ------ | --------------------------------------------------------------------------------------------------- |
| Aura | Soft and elevated — rounded controls, compact rows, diffuse shadows, hairline borders. The default. |
| Lara | Structural and flat — tighter corners, noticeably taller rows, shadows replaced by linework, bolder type. |
| Nora | Sharp and brutalist — zero radius, 2px borders, no motion, solid highlights, heaviest type. |
Preset tokens reach the UI through three routes, and a new token should use one of them rather than being read directly in a component:
- Tailwind's own scales —
@theme inlineinthemes/tailwind.scssmaps--radius-*,--shadow-*and--default-border-widthonto preset tokens, so every existingrounded-*,shadow-*andborderutility in the app is already preset-driven. - The
f-*control utilities —f-field/f-field-sm/f-field-lg/f-field-compact/f-field-shape,f-btn/f-btn-sm/f-btn-lg/f-btn-icon*/f-btn-round, andf-overlay/f-overlay-shape. Form fields and buttons use these instead of fixed padding and radius classes; that is what lets a preset change how dense the UI reads. Never hard-code a control's padding or radius. --f-*custom properties — read directly by the layout SCSS for shell chrome. The applier also stampsdata-f-preset="<name>"on<html>for the rare shell rule that has to know the design language as a whole rather than one token's value.
Palettes
import { PRIMARY_PALETTES, SURFACE_PALETTES, NOIR_PRIMARY } from "@flusys/ng-ui";
import type { ColorPalette, SurfacePalette } from "@flusys/ng-ui";
PRIMARY_PALETTES["emerald"]; // { '50': '#ecfdf5', ..., '950': '#022c22' }
SURFACE_PALETTES["zinc"]; // { 0: '#ffffff', '50': ..., '950': '#09090b' }PRIMARY_PALETTES ships all 16 Tailwind color ramps (emerald, green, lime, orange, amber, yellow, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose) plus the special NOIR_PRIMARY (grayscale primary that maps onto the active surface palette). SURFACE_PALETTES ships slate, gray, zinc, neutral, stone, soho, viva, ocean.
Bootstrap helper
import { buildBootstrapPreset } from "@flusys/ng-ui";
const options = buildBootstrapPreset({ preset: "Aura", primary: "violet", surface: null });
// Reads `flusys.layout.config` from localStorage when isMemorable !== falseUiModule
import { UiModule } from "@flusys/ng-ui";
@Component({
imports: [UiModule],
// ...
})
export class SomePage {}UiModule re-exports every component/directive documented below plus FormsModule. Prefer importing individual standalone components in new code; UiModule exists for bulk-import convenience.
Disabled State
Every component with a disabled input handles it the same way:
- Form controls (
select,multiselect,checkbox,radiobutton,toggleswitch,togglebutton,selectbutton,password,inputnumber,inputotp,datepicker,autocomplete,cascadeselect,treeselect,colorpicker,listbox,rating,knob,slider) exposeisDisabled(), which combines thedisabledinput withsetDisabledState(). That covers[formField],FormControl.disable()and[(ngModel)] [disabled]. - Host clicks are blocked while disabled. Buttons,
fButton, split buttons, speed dial, chips, tabs, accordion headers, inplace, file upload, tree, order list, pick list, organization chart and all of the form controls above swallow clicks and middle-clicks in the capture phase, so a consumer's(click)orrouterLinkon the host never fires while the component is disabled. fButtonon non-button hosts (e.g.<a fButton routerLink>) also drops out of the tab order while disabled or loading, and restores the consumer's owntabindexafterwards.- Disabled menu items in
menu,menubar,tieredmenu,contextmenu,megamenu,panelmenuandbreadcrumbrender with nohref, don't navigate, and don't runcommand.
Use (onChange) to react to value changes, not (click) on the host: a <label> click re-dispatches a second click to the inner input.
Buttons & Actions
ButtonComponent
Standard button with severity, icon, and loading states. Selector: f-button.
<f-button [label]="'shared.save' | translate" icon="check" severity="primary" [loading]="isSaving()" (onClick)="save()" />Key inputs: label, icon, iconPos, severity (primary | secondary | success | info | warn | danger | contrast | help), disabled, loading, text, link, outlined, raised, rounded, fluid, size (small | large | null). Output: onClick.
FButtonDirective
Attribute-directive version of the button — apply button styling to a native <button> or <a>. Selector: [fButton].
<a fButton severity="secondary" outlined label="Cancel"></a>Key inputs: severity, text, outlined, link, rounded, raised, fluid, disabled, loading, size, label, icon, iconPos, ariaLabel, plain.
icon and loadingIcon are Lucide names (same as ui-icon); the directive renders a real ui-icon before or after the label, and a spinning loader-circle while loading.
SplitButtonComponent
Primary action button with an attached dropdown menu. Selector: f-splitbutton.
<f-splitbutton [label]="'shared.export' | translate" icon="download" [model]="exportMenu" severity="primary" (onClick)="exportDefault()" />Key inputs: label, icon, model (MenuItem[]), severity, disabled, loading, appendTo. Outputs: onClick, onDropdownClick.
ButtonGroupComponent
Groups adjacent buttons with connected borders via content projection. Selector: f-buttongroup.
<f-buttongroup>
<f-button label="Left" />
<f-button label="Right" />
</f-buttongroup>SpeedDialComponent
Floating action button that expands into a radial/linear menu. Selector: f-speeddial.
<f-speeddial [model]="actions" icon="plus" direction="up" type="linear" [radius]="80" />Key inputs: model (MenuItem[]), icon, direction (up | down | left | right), rotate, type (linear | circle), radius.
Form Inputs
InputTextDirective
Applies text-input styling to native <input>. Selector: [fInputText].
<input fInputText type="text" [invalid]="form.controls.name.invalid && form.controls.name.touched" [placeholder]="'form.namePlaceholder' | translate" />Key inputs: invalid, touched (defaults true; gates red invalid styling on invalid && touched).
InputPasswordDirective
Password-input styling with optional native masking. Selector: [fInputPassword].
<input fInputPassword type="password" [mask]="true" />Key input: mask (default true).
TextareaDirective
Applies textarea styling. Selector: [fTextarea].
<textarea fTextarea rows="4" [invalid]="control.invalid"></textarea>Key inputs: invalid, touched.
SelectComponent
Native single-select dropdown with filtering. Selector: f-select.
<f-select [options]="countries" optionLabel="name" optionValue="code" [(ngModel)]="selectedCountry" [filter]="true" [placeholder]="'form.selectCountry' | translate" />Key inputs: options, optionLabel, optionValue, placeholder, disabled, filter, lazy, selectedObject, showClear, loading, invalid, touched, editable, appendTo (self | body). Outputs: onFilter, onChange, onShow, onHide, onBlur, onLazyLoad. Supports fTemplate="selectedItem" / fTemplate="item" content templates.
Lazy/search edit forms — selectedObject: when [lazy]="true" or [filter]="true" is combined with a server-paged/searched options() list, the page currently loaded may not contain the option matching the bound value (e.g. editing a record whose selected item isn't in the first lazy page). Pass the full entity being edited via [selectedObject] and the component pins it into the option pool (deduped by optionValue, only while it actually matches the current value) so the trigger label, checkmark and list row always resolve correctly:
<f-select [options]="users()" optionLabel="name" optionValue="id" [lazy]="true" (onLazyLoad)="loadUsers($event)" [selectedObject]="editingUser()" [(ngModel)]="managerId" />MultiSelectComponent
Multi-value select with chip/comma display. Selector: f-multiselect.
<f-multiselect [options]="roles" optionLabel="name" [(ngModel)]="selectedRoles" display="chip" [showToggleAll]="true" />Key inputs: options, optionLabel, optionValue, placeholder, filter, lazy, selectedObjects, display (comma | chip), maxSelectedLabels, selectionLimit, showToggleAll, invalid, touched, appendTo (self | body).
Lazy/search edit forms — selectedObjects: same problem as f-select but for every currently selected value — pass the full entities (e.g. the record's already-selected roles) via [selectedObjects] so chips never silently vanish when the lazy/filtered options() page doesn't include them:
<f-multiselect [options]="roles()" optionLabel="name" optionValue="id" [lazy]="true" (onLazyLoad)="loadRoles($event)" [selectedObjects]="editingUser().roles" [(ngModel)]="roleIds" />CheckboxComponent
Binary or value-bound checkbox. Selector: f-checkbox.
<f-checkbox [(checked)]="acceptedTerms" [label]="'auth.acceptTerms' | translate" [binary]="true" />Key inputs: label, binary, disabled, invalid, indeterminate, touched. Model: checked. Outputs: onChange (CheckboxChangeEvent), onBlur.
ToggleSwitchComponent
On/off switch with ControlValueAccessor support. Selector: f-toggleswitch.
<f-toggleswitch formControlName="isActive" [trueValue]="true" [falseValue]="false" />Key inputs: disabled, readonly, invalid, trueValue, falseValue, ariaLabel.
ToggleButtonComponent
Two-state button toggle with distinct on/off labels and icons. Selector: f-togglebutton.
<f-togglebutton [(ngModel)]="isPublic" [onLabel]="'shared.public' | translate" [offLabel]="'shared.private' | translate" />Key inputs: onLabel, offLabel, onIcon, offIcon, disabled, invalid.
SelectButtonComponent
Single/multi-choice segmented control. Selector: f-selectbutton.
<f-selectbutton [options]="viewModes" optionLabel="label" [(ngModel)]="currentView" />Key inputs: options, optionLabel, optionValue, multiple, disabled, allowEmpty, size. Output: onChange.
PasswordComponent
Password field with strength feedback and reveal toggle. Selector: f-password.
<f-password [(ngModel)]="password" [feedback]="true" [toggleMask]="true" [placeholder]="'auth.passwordPlaceholder' | translate" />Key inputs: toggleMask, feedback, disabled, placeholder, invalid, touched. Output: onBlur.
InputNumberComponent
Numeric input with optional increment/decrement buttons, prefix/suffix, and grouping. Selector: f-inputnumber.
<f-inputnumber [(ngModel)]="quantity" [min]="0" [max]="100" [showButtons]="true" suffix=" kg" />Key inputs: min, max, step, showButtons, disabled, invalid, prefix, suffix, useGrouping, buttonLayout (stacked | horizontal). Output: onBlur.
RadioButtonComponent
Single radio input within a shared name group. Selector: f-radiobutton.
<f-radiobutton name="plan" value="pro" [(ngModel)]="selectedPlan" [label]="'billing.proPlan' | translate" />Key inputs: name, value, label, disabled, invalid. Outputs: onClick (RadioButtonClickEvent), onBlur.
RatingComponent
Star rating input. Selector: f-rating.
<f-rating [(ngModel)]="rating" [stars]="5" [cancel]="true" (onRate)="onRatingChange($event)" />Key inputs: stars, cancel, readonly, disabled, invalid, iconOn, iconOff. Outputs: onRate, onBlur.
DatePickerComponent
Calendar/date input with single, range, and multiple selection modes. Selector: f-datepicker.
<f-datepicker [(ngModel)]="eventDate" selectionMode="single" [showIcon]="true" [minDate]="today" [placeholder]="'form.selectDate' | translate" />Key inputs: placeholder, dateFormat, disabled, showTime, selectionMode (single | range | multiple), minDate, maxDate, invalid, touched, showClear, showIcon, showButtonBar, appendTo. Output: onBlur.
FileUploadComponent
File upload with drag-drop, auto-upload, and progress. Selector: f-fileupload.
<f-fileupload accept="image/*" [maxFileSize]="2000000" [multiple]="true" (onSelect)="onFilesSelected($event)" (onError)="onUploadError($event)" />Key inputs: name, accept, multiple, auto, maxFileSize, fileLimit, disabled, url, customUpload, mode (advanced | basic). Outputs: onSelect (FileSelectEvent), onRemove (FileRemoveEvent), onClear, onError (FileErrorEvent[]).
Text inputs (English defaults — bind translated strings): chooseLabel, uploadLabel, cancelLabel, removeLabel (per-file remove button's accessible name), dragDropLabel, dragDropHintLabel.
Pass <ng-template #content> (or fTemplate="content") to replace the default drop zone and file list in advanced mode. Drag-and-drop still works on the wrapper. Context (FileUploadContentContext): $implicit/files, items, disabled, removeFile(file), clear().
<f-fileupload [chooseLabel]="'storage.button.choose.file' | translate">
<ng-template #content let-files let-removeFile="removeFile">
@for (file of files; track file.name) {
<button fButton [text]="true" [ariaLabel]="'shared.remove' | translate" (click)="removeFile(file)">{{ file.name }}</button>
}
</ng-template>
</f-fileupload>AutoCompleteComponent
Type-ahead input backed by an async or static suggestion list. Selector: f-autocomplete.
<f-autocomplete [suggestions]="filteredUsers()" field="name" [(ngModel)]="selectedUser" (completeMethod)="search($event.query)" />Key inputs: suggestions, field, placeholder, ariaLabel, disabled, dropdown, forceSelection, multiple, delay, minLength, completeOnFocus, freeText, filterLocally, invalid, touched, appendTo (self | body). Outputs: completeMethod (AutoCompleteCompleteEvent), onSelect (AutoCompleteSelectEvent), onUnselect, onClear, onChange.
Editable combobox (free text + suggestions). By default only a picked suggestion reaches the model; typed text stays in the input. freeText writes every keystroke to the model (single mode), so the value can be anything the user types, with the suggestions as shortcuts. filterLocally filters a static suggestions list case-insensitively by the typed text, with no completeMethod handler needed (grouped lists are filtered per group, empty groups dropped). Focusing the input or pressing the dropdown button shows the full list again. In freeText mode the panel stays closed rather than showing the empty message when nothing matches, and clearing sets '' instead of null.
<f-autocomplete
freeText
filterLocally
completeOnFocus
dropdown
[minLength]="0"
[delay]="0"
[suggestions]="['input.email', 'loop.item', 'user.id']"
[ariaLabel]="'app.field' | translate"
[(ngModel)]="path"
/>ColorPickerComponent
Inline or overlay color picker. Selector: f-colorpicker.
<f-colorpicker [(ngModel)]="brandColor" format="hex" [inline]="false" (onChange)="onColorChange($event)" />Key inputs: format (hex | rgb | hsb), inline, disabled, invalid. Output: onChange (ColorPickerChangeEvent).
ListboxComponent
Scrollable option list with optional filter and multi-select. Selector: f-listbox.
<f-listbox [options]="statuses" optionLabel="label" [(ngModel)]="selectedStatus" [filter]="true" />Key inputs: options, optionLabel, optionValue, multiple, filter, filterPlaceholder, disabled, metaKeySelection, emptyMessage. Output: onChange (ListboxChangeEvent).
InputMaskDirective
Applies a slotted input mask to a native <input>. Selector: [fInputMask].
<input fInputMask="(999) 999-9999" slotChar="_" [placeholder]="'form.phonePlaceholder' | translate" />Key inputs: fInputMask (mask pattern), slotChar.
InputOtpComponent
Segmented one-time-passcode input. Selector: f-inputotp.
<f-inputotp [(ngModel)]="otpCode" [length]="6" [integerOnly]="true" [mask]="false" />Key inputs: length, mask, disabled, integerOnly, invalid.
SliderComponent
Range slider input, single or dual-handle. Selector: f-slider.
<f-slider [(ngModel)]="priceRange" [min]="0" [max]="1000" [range]="true" />Key inputs: min, max, step, range, disabled.
KnobComponent
Circular dial numeric input. Selector: f-knob.
<f-knob [(ngModel)]="volume" [min]="0" [max]="100" [size]="100" valueColor="var(--f-primary-500)" />Key inputs: size, min, max, step, strokeWidth, showValue, disabled, readonly, valueColor, rangeColor, textColor.
CascadeSelectComponent
Hierarchical dependent-option selector (e.g. country → state → city). Selector: f-cascadeselect.
<f-cascadeselect [options]="locations" optionLabel="label" optionChildren="children" [(ngModel)]="selectedLocation" />Key inputs: options, optionLabel, optionValue, optionChildren, placeholder, disabled, invalid, touched, appendTo (self | body).
KeyFilterDirective
Restricts keystrokes on a native input to a preset or custom pattern. Selector: [fKeyFilter].
<input fInputText [fKeyFilter]="'num'" />Key input: fKeyFilter ('int' | 'pint' | 'num' | 'pnum' | 'money' | 'alpha' | 'alphanum' | 'email' | RegExp | null).
TreeSelectComponent
Select input backed by a hierarchical tree of options. Selector: f-treeselect.
<f-treeselect [options]="orgTree" [(ngModel)]="selectedNode" selectionMode="checkbox" [filter]="true" />Key inputs: options (TreeNode[]), placeholder, inputId (id of the trigger, for <label for>), disabled, filter, filterBy, selectionMode (single | multiple | checkbox), propagateSelectionDown / propagateSelectionUp (checkbox cascading), invalid, touched, appendTo (self | body). A node with selectable: false is a heading: clicking it expands or collapses it, and it never becomes part of the value.
IconFieldComponent / InputIconComponent
Positions an icon inside a text input (search boxes, etc.). Selectors: f-iconfield, f-inputicon.
<f-iconfield>
<f-inputicon icon="search" />
<input fInputText [placeholder]="'shared.search' | translate" />
</f-iconfield>f-inputicon's icon input renders the icon at a fixed 17px regardless of ambient font-size, so it always aligns with the field — prefer it over projecting a manually-sized <ui-icon> as content. Content projection (<f-inputicon><ui-icon .../></f-inputicon>) still works for cases needing a non-Lucide icon or custom template.
FloatLabelComponent
Floats a <label> above the input on focus/fill. Selector: f-floatlabel.
<f-floatlabel variant="over">
<input fInputText id="email" />
<label for="email">{{ 'form.email' | translate }}</label>
</f-floatlabel>Key input: variant (over | in | on).
IftaLabelComponent
"In-the-field" label layout, pairing a persistent inline label with the input. Selector: f-iftalabel.
<f-iftalabel>
<input fInputText id="username" />
<label for="username">{{ 'form.username' | translate }}</label>
</f-iftalabel>InputGroupComponent / InputGroupAddonComponent
Groups an input with leading/trailing addons (currency symbols, buttons). Selectors: f-inputgroup, f-inputgroupaddon.
<f-inputgroup>
<f-inputgroupaddon>$</f-inputgroupaddon>
<input fInputText type="number" />
</f-inputgroup>FluidComponent
Stretches all descendant form controls to full width. Selector: f-fluid.
<f-fluid>
<f-select [options]="items" />
</f-fluid>Data Display & Tables
TableComponent
Full-featured data table — sorting, pagination, lazy loading, scrollable body. Selector: f-table.
<f-table [value]="rows()" [lazy]="true" [loading]="loading()" [totalRecords]="total()" [rows]="pageSize" [paginator]="true" (onLazyLoad)="loadPage($event)">
<ng-template fTemplate="header">
<th fSortableColumn="name">{{ 'shared.name' | translate }} <f-sorticon field="name" /></th>
</ng-template>
<ng-template fTemplate="body" let-row>
<td>{{ row.name }}</td>
</ng-template>
</f-table>Key inputs: value, lazy, loading, rows, totalRecords, rowHover, dataKey, scrollable, paginator, first, rowsPerPageOptions, tableStyle, globalFilterFields. Models: sortField, sortOrder. Outputs: onLazyLoad (TableLazyLoadEvent), onSort (TableSortEvent). Supports fTemplate="header" | "body" | "emptymessage".
SortIconComponent / SortableColumnDirective
Sort indicator and clickable sortable-column host, used inside f-table headers. Selectors: f-sorticon, [fSortableColumn].
<th fSortableColumn="createdAt">{{ 'shared.createdAt' | translate }} <f-sorticon field="createdAt" /></th>Key input: fSortableColumn / field — the field name to sort by.
PaginatorComponent
Standalone pagination control (also used internally by f-table/f-dataview). Selector: f-paginator.
<f-paginator [first]="first" [rows]="10" [totalRecords]="total" (onPageChange)="onPage($event)" />Key inputs: first, rows, totalRecords, rowsPerPageOptions, showCurrentPageReport, currentPageReportTemplate. Output: onPageChange (PaginatorState).
TreeTableComponent
Hierarchical table combining tree expand/collapse with tabular columns. Selector: f-treetable.
<f-treetable [value]="orgNodes" [loading]="loading()" dataKey="id">
<ng-template fTemplate="header">
<th>{{ 'shared.name' | translate }}</th>
</ng-template>
<ng-template fTemplate="body" let-rowNode>
<td><f-treetabletoggler [rowNode]="rowNode" /> {{ rowNode.node.label }}</td>
</ng-template>
</f-treetable>Key inputs: value (TreeNode[]), loading, dataKey, scrollable, tableStyle. TreeTableTogglerComponent (f-treetabletoggler) requires rowNode: input.required<TreeTableNode>(). TreeTableService exposes an expanded signal and toggle(key, node) for custom expand/collapse UIs.
TreeComponent
Hierarchical tree view with selection and filtering. Selector: f-tree.
<f-tree [value]="categoryTree" selectionMode="checkbox" [filter]="true" (selectionChange)="onSelect($event)" />Key inputs: value (TreeNode[]), selectionMode (single | multiple | checkbox | null), filter, loading, emptyMessage. Outputs: selectionChange, nodeExpand, nodeCollapse.
DataViewComponent
List/grid toggleable data view with built-in pagination. Selector: f-dataview.
<f-dataview [value]="products()" [paginator]="true" [rows]="12" [(layout)]="viewLayout" (onPageChange)="onPage($event)">
<ng-template let-item>
<div>{{ item.name }}</div>
</ng-template>
</f-dataview>Key inputs: value, showLayoutToggle, paginator, rows, totalRecords, first, loading. Model: layout ('list' | 'grid'). Output: onPageChange.
OrganizationChartComponent
Renders a TreeNode hierarchy as a top-down org chart. Selector: f-organizationchart.
<f-organizationchart [value]="ceoNode">
<ng-template let-node>{{ node.label }}</ng-template>
</f-organizationchart>Key input: value (TreeNode | null).
PickListComponent
Dual-list source/target transfer control. Selector: f-picklist.
<f-picklist [(source)]="available" [(target)]="assigned" [sourceHeader]="'shared.available' | translate" [targetHeader]="'shared.assigned' | translate" />Key inputs/models: source, target (models), sourceHeader, targetHeader. Outputs: onMoveToTarget, onMoveToSource.
OrderListComponent
Reorderable single-list control with up/down/top/bottom controls. Selector: f-orderlist.
<f-orderlist [(value)]="steps" [header]="'shared.steps' | translate" (onReorder)="onReorder($event)" />Key inputs: value (model), header, selected (model). Output: onReorder.
ScrollerComponent
Virtual scroller for large flat lists. Selector: f-scroller.
<f-scroller [items]="bigList()" [itemSize]="40" scrollHeight="20rem">
<ng-template let-item>{{ item.label }}</ng-template>
</f-scroller>Key inputs: items, itemSize, scrollHeight.
TimelineComponent
Vertical/horizontal timeline of events. Selector: f-timeline.
<f-timeline [value]="events()" align="alternate" layout="vertical">
<ng-template let-event>{{ event.status }}</ng-template>
</f-timeline>Key inputs: value, align (left | right | alternate), layout (vertical | horizontal).
ChartComponent
Canvas-based chart wrapper (bar/line/pie/etc.). Selector: f-chart.
<f-chart type="bar" [data]="chartData" [options]="chartOptions" height="300" />Key inputs: type, data, options, width, height.
MeterGroupComponent
Segmented meter/progress bar for showing proportional values. Selector: f-metergroup.
<f-metergroup [values]="[{ label: 'Used', value: 65, color: 'var(--f-primary-500)' }]" [max]="100" />Key inputs: values (MeterItem[]), min, max.
Overlays & Dialogs
DialogComponent
Modal dialog with header, footer template, and resizing. Selector: f-dialog.
<f-dialog [(visible)]="showDialog" [header]="'shared.editUser' | translate" [modal]="true" [closable]="true">
<p>Content</p>
<ng-template #footer>
<f-button [label]="'shared.close' | translate" (onClick)="showDialog.set(false)" />
</ng-template>
</f-dialog>Key inputs: header, modal, closable, dismissableMask, resizable, style, breakpoints. Model: visible. Outputs: onShow, onHide. Supports #footer template ref and fTemplate content children.
DrawerComponent
Slide-in panel from any edge of the viewport. Selector: f-drawer.
<f-drawer [(visible)]="showDrawer" position="right" [header]="'shared.filters' | translate">
<p>Filter controls</p>
</f-drawer>Key inputs: header, position (left | right | top | bottom), fullScreen, modal, closable, closeOnEscape. Model: visible. Output: onHide.
PopoverComponent
Anchored overlay panel triggered programmatically. Selector: f-popover.
<f-popover #op [dismissable]="true">
<p>Popover content</p>
</f-popover>
<f-button label="Show" (onClick)="op.toggle($event)" />Key input: dismissable.
ConfirmDialog
Global confirmation modal driven by ConfirmationService.confirm(). Selector: f-confirmdialog. Place once in the app shell; supports multiple independent instances via the key input matched against ConfirmationService.confirm({ key }).
<f-confirmdialog />ConfirmPopupComponent
Anchored (non-modal) confirmation popup, also driven by ConfirmationService. Selector: f-confirmpopup.
<f-confirmpopup /> <f-button label="Delete" (onClick)="confirmationService.confirm({ target: $event.target, message: 'Sure?', accept: onDelete })" />Key input: key.
DynamicDialogComponent / DynamicDialogService
Renders arbitrary components inside a dialog shell opened imperatively. Selector: f-dynamicdialog.
<f-dynamicdialog />import { DynamicDialogService, DYNAMIC_DIALOG_DATA, DYNAMIC_DIALOG_REF } from "@flusys/ng-ui";
const dialogService = inject(DynamicDialogService);
const ref = dialogService.open(UserFormComponent, { header: "Edit User", width: "32rem", data: { id: userId } });
ref.onClose.subscribe((result) => reloadList());
// Inside UserFormComponent:
private readonly data = inject(DYNAMIC_DIALOG_DATA);
private readonly ref = inject(DYNAMIC_DIALOG_REF);
this.ref.close(updatedUser);DynamicDialogConfig: header, width, height, closable, closeOnEscape, dismissableMask, footer, data.
BlockUiComponent
Overlays a blocking mask + spinner over its projected content. Selector: f-blockui.
<f-blockui [blocked]="isSaving()">
<form>...</form>
</f-blockui>Key inputs: blocked, hasCustomTemplate (set true when projecting a custom [block-template] node instead of the default spinner).
ToastComponent
Renders queued messages from MessageService. Selector: f-toast.
<f-toast position="top-right" key="main" />Key inputs: key, position (top-right | top-left | top-center | bottom-right | bottom-left | bottom-center | center).
Navigation & Menus
MenuComponent
Flat or popup vertical menu. Selector: f-menu.
<f-menu #menu [model]="actions" [popup]="true" /> <f-button icon="ellipsis" (onClick)="menu.toggle($event)" />Key inputs: model (MenuItem[]), popup.
MenubarComponent
Horizontal top-level navigation bar with nested submenus. Selector: f-menubar.
<f-menubar [model]="navItems" />Key input: model (MenuItem[]).
TieredMenuComponent
Multi-level flyout menu (hover/click cascading submenus). Selector: f-tieredmenu.
<f-tieredmenu [model]="menuItems" [popup]="false" />Key inputs: model, popup.
ContextMenuComponent
Right-click context menu bound to a target selector. Selector: f-contextmenu.
<f-contextmenu [model]="rowActions" target=".table-row" />Key inputs: model, target.
MegaMenuComponent
Multi-column dropdown navigation (site-wide mega menus). Selector: f-megamenu.
<f-megamenu [model]="megaMenuItems" />Key input: model (MenuItem[], each top item's items render as columns).
PanelMenuComponent
Accordion-style vertical menu with nested expand/collapse. Selector: f-panelmenu.
<f-panelmenu [model]="sidebarItems" [multiple]="true" />Key inputs: model, multiple (allow more than one root panel expanded at once, default true).
BreadcrumbComponent
Horizontal breadcrumb trail. Selector: f-breadcrumb.
<f-breadcrumb [model]="crumbs" [home]="{ icon: 'home', routerLink: '/' }" />Key inputs: model (MenuItem[]), home.
DockComponent
macOS-dock-style icon launcher with magnification. Selector: f-dock.
<f-dock [model]="appShortcuts" position="bottom" />Key inputs: model (MenuItem[]), position (DockPosition).
StepsComponent
Linear step/wizard indicator. Selector: f-steps.
<f-steps [model]="wizardSteps" [activeIndex]="currentStep()" (onActiveIndexChange)="currentStep.set($event)" />Key inputs: model (StepsMenuItem[], alias of MenuItem[]), activeIndex, readonly. Output: onActiveIndexChange.
TabsComponent family
Composable tabs: TabsComponent (f-tabs), TabListComponent (f-tablist), TabComponent (f-tab), TabPanelsComponent (f-tabpanels), TabPanelComponent (f-tabpanel).
<f-tabs [(value)]="activeTab">
<f-tablist>
<f-tab value="general">{{ 'shared.general' | translate }}</f-tab>
<f-tab value="security">{{ 'shared.security' | translate }}</f-tab>
</f-tablist>
<f-tabpanels>
<f-tabpanel value="general">General content</f-tabpanel>
<f-tabpanel value="security">Security content</f-tabpanel>
</f-tabpanels>
</f-tabs>f-tabs model: value; input scrollable; output onTabChange. f-tab inputs: value, disabled. TabsContext is the internal @Injectable() DI context f-tabs provides for its children to read active/scrollable state — not instantiated directly by consumers.
Media
ImageComponent
Image with optional full-screen preview overlay. Selector: f-image.
<f-image [src]="avatarUrl()" [alt]="user.name" [preview]="true" width="120" />Key inputs: src, alt, width, height, preview. Outputs: onShow, onHide.
GalleriaComponent
Image gallery with thumbnail strip. Selector: f-galleria.
<f-galleria [value]="photos" [showThumbnails]="true" height="24rem" />Key inputs: value (GalleriaItem[] — itemImageSrc, thumbnailImageSrc?, alt?), showThumbnails, height.
CarouselComponent
Sliding item carousel with configurable visible-item count and autoplay. Selector: f-carousel.
<f-carousel [value]="banners()" [numVisible]="1" [autoplayInterval]="5000" (onPage)="onPageChange($event)">
<ng-template let-item>{{ item.title }}</ng-template>
</f-carousel>Key inputs: value, numVisible, showIndicators, circular, autoplayInterval. Output: onPage.
ImageCompareComponent
Before/after image slider comparison. Selector: f-imagecompare.
<f-imagecompare [imageBeforeSrc]="before" [imageAfterSrc]="after" height="20rem" />Key inputs: imageBeforeSrc, imageAfterSrc, altBefore, altAfter, height.
AvatarComponent / AvatarGroupComponent
User avatar (image, initials, or icon) and stacked group wrapper. Selectors: f-avatar, f-avatar-group.
<f-avatar-group>
<f-avatar image="/user1.png" shape="circle" size="large" />
<f-avatar label="JD" shape="circle" />
</f-avatar-group>Key inputs (f-avatar): label, icon, image, shape (square | circle), size (normal | large | xlarge), color, styleClass.
Feedback & Status
TagComponent
Small inline status label. Selector: f-tag.
<f-tag [value]="'shared.active' | translate" severity="success" icon="check" [rounded]="true" />Key inputs: value, severity (success | info | warn | danger | secondary | contrast | null), icon, rounded, color.
BadgeComponent
Small numeric/status indicator, standalone or attached to an element. Selector: f-badge.
<f-badge [value]="unreadCount()" severity="danger" size="small" />Key inputs: value, severity (BadgeSeverity), size (small | large | xlarge | null).
OverlayBadgeComponent
Positions a badge in the corner of its projected content (e.g. bell icon with unread count). Selector: f-overlaybadge.
<f-overlaybadge [value]="notificationCount()" severity="danger">
<ui-icon name="bell" />
</f-overlaybadge>Key inputs: value, severity, size.
MessageComponent
Inline severity-styled message banner. Selector: f-message.
<f-message severity="warn" [text]="'form.unsavedChanges' | translate" icon="alert-triangle" />Key inputs: severity (success | info | warn | error), text, icon.
ProgressbarComponent
Horizontal progress indicator. Selector: f-progressbar.
<f-progressbar [value]="uploadProgress()" mode="determinate" [showValue]="true" />Key inputs: value, mode (determinate | indeterminate), showValue.
ProgressSpinnerComponent
Circular loading spinner. Selector: f-progressspinner.
<f-progressspinner [size]="40" [strokeWidth]="4" />Key inputs: size, strokeWidth.
SkeletonComponent
Loading placeholder block. Selector: f-skeleton.
<f-skeleton width="100%" height="1.5rem" shape="rectangle" />Key inputs: width, height, borderRadius, shape (rectangle | circle).
ChipComponent
Removable label chip. Selector: f-chip.
<f-chip [label]="tag.name" [removable]="true" (onRemove)="removeTag(tag)" />Key inputs: label, icon, removable. Output: onRemove.
Layout
CardComponent
Content card with optional header/footer templates. Selector: f-card.
<f-card [header]="'shared.summary' | translate" styleClass="mb-4">
<p>Body content</p>
<ng-template #footer><f-button label="Details" text /></ng-template>
</f-card>Key inputs: header, subheader, styleClass. Content templates: #header, #footer.
PanelComponent
Collapsible titled panel. Selector: f-panel.
<f-panel [header]="'shared.advanced' | translate" [toggleable]="true" [(collapsed)]="advancedCollapsed">
<p>Advanced settings</p>
</f-panel>Key inputs: header, toggleable. Model: collapsed.
FieldsetComponent
Bordered/legend-labeled grouping, optionally collapsible. Selector: f-fieldset.
<f-fieldset [legend]="'shared.contactInfo' | translate" [toggleable]="true" [(collapsed)]="contactCollapsed">
<p>Fields</p>
</f-fieldset>Key inputs: legend, toggleable. Model: collapsed.
AccordionComponent family
Composable accordion: AccordionComponent (f-accordion), AccordionPanelComponent (f-accordion-panel), AccordionHeaderComponent (f-accordion-header), AccordionContentComponent (f-accordion-content).
<f-accordion [multiple]="false" [(value)]="activePanel">
<f-accordion-panel value="0">
<f-accordion-header>{{ 'shared.section1' | translate }}</f-accordion-header>
<f-accordion-content>Content 1</f-accordion-content>
</f-accordion-panel>
</f-accordion>f-accordion input: multiple; model: value; outputs: onOpen, onClose. f-accordion-panel inputs: value, disabled. AccordionContext is the internal @Injectable() DI context f-accordion provides for its panels — not instantiated directly by consumers.
SplitterComponent
Resizable multi-pane layout via draggable gutters. SplitterComponent selector: f-splitter; panels use SplitterPanelComponent, selector: f-splitter-panel.
<f-splitter layout="horizontal" [panelSizes]="[30, 70]">
<f-splitter-panel>Sidebar</f-splitter-panel>
<f-splitter-panel>Content</f-splitter-panel>
</f-splitter>Key inputs: layout (horizontal | vertical), panelSizes, minSizes, styleClass.
ToolbarComponent
Header/action toolbar with start/center/end projection slots. Selector: f-toolbar.
<f-toolbar>
<ng-template fTemplate="start"><h2>{{ 'shared.title' | translate }}</h2></ng-template>
<ng-template fTemplate="end"><f-button label="New" /></ng-template>
</f-toolbar>Key input: styleClass.
DividerComponent
Horizontal/vertical separator, optionally with centered content/label. Selector: f-divider.
<f-divider layout="horizontal" type="dashed" align="center">{{ 'shared.or' | translate }}</f-divider>Key inputs: layout (horizontal | vertical), type (solid | dashed | dotted), align (left | center | right).
ScrollPanelComponent
Custom-styled scrollable container. Selector: f-scrollpanel.
<f-scrollpanel maxHeight="20rem">
<p>Long content...</p>
</f-scrollpanel>Key inputs: maxHeight, maxWidth.
ScrollTopComponent
Floating "scroll to top" button, appears after a scroll threshold. Selector: f-scrolltop.
<f-scrolltop [threshold]="400" target="window" [buttonAriaLabel]="'shared.scrollToTop' | translate" />Key inputs: threshold, behavior (ScrollBehavior), target (window | parent), buttonAriaLabel.
InplaceComponent
Toggles between a display view and an editable/expanded view in place. Selector: f-inplace.
<f-inplace [(active)]="isEditing">
<ng-template #display>{{ value() }}</ng-template>
<ng-template #content><input fInputText [(ngModel)]="value" /></ng-template>
</f-inplace>Key input: disabled. Model: active. Outputs: onActivate, onDeactivate.
Directives & Utilities
TooltipDirective
Attaches a hover/focus tooltip to any element. Selector: [fTooltip].
<button [fTooltip]="'shared.deleteHint' | translate" tooltipPosition="top"></button>Key inputs: fTooltip (text), tooltipPosition (top | bottom | left | right), tooltipStyleClass, disabled, tooltipEvent (hover | focus | both), showDelay, hideDelay.
StyleClassDirective
Toggles CSS classes on a target element with enter/leave transition class support (accordion/dropdown-style show/hide). Selector: [fStyleClass].
<button [fStyleClass]="'#panel'" enterFromClass="hidden" enterActiveClass="animate-fade-in" leaveToClass="hidden"></button>Key inputs: fStyleClass (target selector), enterFromClass, enterActiveClass, enterToClass, leaveFromClass, leaveActiveClass, leaveToClass, hideOnOutsideClick, toggleClass.
AnimateOnScrollDirective
Adds an enter animation class when the host scrolls into the viewport. Selector: [fAnimateOnScroll].
<div fAnimateOnScroll enterClass="animate-fade-in" [once]="true" [threshold]="0.15">Content</div>Key inputs: enterClass, leaveClass, once, threshold.
AutoFocusDirective
Focuses the host element on init when enabled. Selector: [fAutoFocus].
<input fInputText [fAutoFocus]="true" />Key input: fAutoFocus.
RippleDirective
Adds a Material-style ripple feedback effect on click. Selector: [fRipple].
<button fButton fRipple label="Click me"></button>KeyFilterDirective and InputMaskDirective are documented under Form Inputs above.
FTemplateDirective
Marks an ng-template as a named content slot consumed by host components (table headers/body, toolbar start/end, dialog footer, etc.). Selector: ng-template[fTemplate].
<ng-template fTemplate="body" let-row>{{ row.name }}</ng-template>Key input: fTemplate (slot name).
UiIconComponent
Renders a Lucide icon by name, with PrimeIcons-style aliases mapped internally for drop-in compatibility. Selector: ui-icon.
<ui-icon name="check-circle" [size]="20" [spin]="false" />Key inputs: name, size (unset by default — renders at 1em, scaling with whatever font-size context, e.g. a Tailwind text-* class, surrounds it; pass a number to pin an exact pixel size instead), spin, fill.
EditorComponent
Rich-text editor with ControlValueAccessor support. Selector: f-editor.
<f-editor [(ngModel)]="htmlContent" [placeholder]="'form.writeHere' | translate" />Key input: placeholder.
TerminalComponent
Interactive command-line-style output panel. Selector: f-terminal.
<f-terminal [welcomeMessage]="'Welcome to FLUSYS CLI'" prompt="$" (onCommand)="runCommand($event.command)" />Key inputs: welcomeMessage, prompt, height. Output: onCommand (TerminalCommandEvent).
Interfaces
import type { MenuItem, MenuItemCommandEvent, TreeNode } from "@flusys/ng-ui";
interface MenuItem {
label?: string;
icon?: string;
command?: (event: MenuItemCommandEvent) => void;
url?: string;
routerLink?: string | string[];
items?: MenuItem[];
disabled?: boolean;
visible?: boolean;
separator?: boolean;
selected?: boolean;
badge?: string;
// ...
}
interface TreeNode<T = unknown> {
data?: T;
children?: TreeNode<T>[];
expanded?: boolean;
leaf?: boolean;
label?: string;
icon?: string;
key?: string;
selectable?: boolean;
// ...
}MenuItem drives every menu-family component (f-menu, f-menubar, f-tieredmenu, f-contextmenu, f-megamenu, f-panelmenu, f-breadcrumb, f-dock, f-steps, f-speeddial, f-splitbutton). TreeNode drives f-tree, f-treeselect, f-treetable, and f-organizationchart.
License
MIT © FLUSYS
