Skip to content

@gravionlabs/helix-shell — Component API Reference ​

All inputs use the Angular 17+ input() signal API and ship with defaults, so adding a new input is never a breaking change for consumers.


Table of Contents ​

  1. Installation
  2. Quick Start
  3. Layout Components
  4. Routing Utilities
  5. Layout Store
  6. Auth Pages
  7. Other Pages
  8. Landing Page Components
  9. UI Components
  10. Form Infrastructure
  11. Interfaces

Installation ​

bash
npm install @gravionlabs/helix-shell

Peer dependencies: @angular/core >=22, @angular/router >=22, @ngrx/signals >=21, @gravionlabs/helix-ui >=0.1.0 (and its own peers, @angular/cdk and @angular/forms), primeicons >=7.

The shell draws its buttons, fields, breadcrumb and tooltips with @gravionlabs/helix-ui, so the app loads its styles and tokens next to the shell styles:

css
@import "@gravionlabs/helix-ui/styles.css";
@import "@gravionlabs/helix-ui/tokens.css";

The shell stylesheet sets no rules on html and body. The Helix page look (14 px root font size, body font, text colour and ground background) is opt-in:

css
@import "@gravionlabs/helix-shell/styles.css";
/* optional: html/body rules of the Helix page look */
@import "@gravionlabs/helix-shell/globals.css";

Breaking change: earlier versions of styles.css contained these rules. An app that relied on them must now load @gravionlabs/helix-shell/globals.css after styles.css; apps that did not want them need nothing. styles.css still reads [class*="app-dark"] or [data-theme="dark"] for dark mode, see Theming.

Dark mode, the primary colour and the surface are switched by the theme service of helix-ui, which the layout store and the configurator use. Provide it once in the application config:

ts
// app.config.ts
import { provideHxTheme } from '@gravionlabs/helix-ui';

export const appConfig: ApplicationConfig = {
  providers: [provideHxTheme({ storageKey: 'my-app-theme', viewTransition: true })],
};

Without provideHxTheme the service still works with its defaults (light or the system setting, nothing remembered); the options are described in Theming. The configurator offers the primary colours and surfaces of that service and the menu mode; there is no longer a choice between Aura, Lara and Nora presets.


Quick Start ​

ts
// app.component.ts
import { Component } from '@angular/core';
import { HelixAppLayout, type HelixRouteMenuItem } from '@gravionlabs/helix-shell';

const MENU: HelixRouteMenuItem[] = [
  { label: 'Dashboard', icon: 'pi pi-home', routerLink: ['/dashboard'] },
  { label: 'Settings', icon: 'pi pi-cog', routerLink: ['/settings'] },
];

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [HelixAppLayout],
  template: `<helix-app-layout appTitle="My App" [menu]="menu" />`,
})
export class AppComponent {
  menu = MENU;
}

Layout Components ​

HelixAppLayout ​

Selector: <helix-app-layout>
File: projects/shell/src/lib/layout/components/app-layout/app-layout.ts

Top-level shell that composes the topbar, nav rail, footer, and router outlet into a full application layout. Forwards appTitle to HelixTopbar.

Inputs ​

NameTypeDefaultDescription
appTitlestring'Helix'Application title forwarded to HelixTopbar
menuHelixRouteMenuItem[][]Navigation menu model. Overrides route data when provided
topbarItemsHelixTopbarItem[]darkmode, configurator, mobileTopbar config items. Overrides the default items when provided
topbarActionsHelixTopbarAction[]calendar, inbox, profileTopbar dropdown action buttons. Provide command callbacks to handle clicks
brandIconstring—Nav-rail brand icon: inline SVG (<svg>…</svg>) or URL to an SVG file. Falls back to the default helix icon
navStyle'sections' | 'tree''sections'How menu maps onto the rail: top-level items with children as always-open section headings ('sections'), or as expandable folders ('tree'). See helixNavGroupsFromMenu
navGroupsHelixNavGroup[]—Explicit nav groups; win over the mapped menu

Content slots ​

SelectorDescription
[helixTopbarEnd]Forwarded into the HelixTopbar end slot (attribute selector, no directive needed). See the topbar section for placement and narrow-width behaviour
[hxStatusBarEnd]Projected at the right end of the status bar. See status bar

Example ​

html
<helix-app-layout
  appTitle="Gravion Portal"
  [menu]="myMenu"
  [topbarItems]="myItems"
  [topbarActions]="myActions"
  brandIcon="/assets/logo.svg"
>
  <input helixTopbarEnd type="search" aria-label="Filter" placeholder="Filter" />
  <button hxStatusBarEnd type="button">Reload</button>
</helix-app-layout>

HelixTopbar ​

Selector: <helix-topbar>
File: projects/shell/src/lib/layout/components/topbar/topbar.ts

Application header bar. Renders a menu toggle and breadcrumb trail on the left, and on the right the projected [helixTopbarEnd] content (in a layout-topbar-slot wrapper), the config items and the action buttons.

Inputs ​

NameTypeDefaultDescription
appTitlestring'Helix'Application name
topbarActionsHelixTopbarAction[]3 icon buttons (calendar, inbox, profile)Action buttons rendered in the right-side dropdown
breadcrumbsHxMenuItem[]Derived from route dataBreadcrumb trail. Falls back to route data['breadcrumb'] resolution
itemsHelixTopbarItem[]darkmode, configurator, mobileConfiguration items rendered in the right action cluster

Content Slots ​

SlotSelectorDescription
End[helixTopbarEnd]Always-visible content at the start of the right cluster, e.g. a global filter

Behaviour of the End slot:

  • Rendered in a layout-topbar-slot wrapper inside layout-topbar-end, before the config items and the ellipsis button and outside the collapsible menu, so it is visible at every width.
  • Shrinks or scrolls horizontally before the breadcrumbs lose their minimum width (12rem above 992px); it never wraps and the topbar height stays fixed. The config and action buttons keep their size.
  • The wrapper is collapsed when it contains no element, so unused layouts get no extra gap.
  • Focus order follows DOM order: slot content, config items, ellipsis button, menu actions.

Behaviour change for direct <helix-topbar> users: [helixTopbarEnd] content used to sit after the actions and, on narrow widths, behind the ellipsis menu. It now renders before the config items and stays visible. The ellipsis menu switches at the shell breakpoint (992px), not Tailwind lg (1024px).

Layout ​

The topbar is split into two sections:

  • Left (layout-topbar-start): Menu toggle button followed by the breadcrumb with a home icon
  • Right (layout-topbar-end): [helixTopbarEnd] slot wrapper (layout-topbar-slot), then the config menu (dark mode, configurator, alerts), the ellipsis button and the collapsible action menu

Example ​

html
<helix-topbar appTitle="My App" [topbarActions]="myActions" />
ts
myActions: HelixTopbarAction[] = [
  { icon: 'pi pi-bell', label: 'Notifications', command: () => this.openNotifications() },
  { icon: 'pi pi-user', label: 'Profile',        command: () => this.openProfile() },
];

HelixStatusBar ​

Selector: <helix-status-bar>
File: projects/shell/src/lib/layout/components/status-bar/status-bar.ts

Thin full-bleed status bar at the bottom of the application layout. Displays brand, environment badge, note, and version labels. Background color is determined by the tone input.

Inputs ​

NameTypeDefaultDescription
brandstring''Brand name displayed on the left
environmentEnvironment | CustomEnvironment | string | undefinedundefined'development', 'testing', 'staging', 'production' or a custom { label, severity }. Unknown strings render as "Unknown"
notestring | TemplateRef<unknown> | undefinedundefinedOptional note: plain text (e.g. "Build #1234") or a template for rich content such as a link. Links inherit the bar color and underline on hover
versionsHelixStatusBarVersion[][]Version labels displayed on the right: { label: string, value: string }
toneHelixStatusBarTone'neutral'Background tone: 'staging' (amber), 'production' (dark), 'success' (green), 'danger' (red), 'neutral' (gray)
heightstring'var(--helix-status-bar-height, 3rem)'Bar height

Content slots ​

SelectorDescription
[hxStatusBarEnd]Projected at the right end of the bar, after the versions. Hidden when empty

Example ​

html
<helix-status-bar
  brand="MyApp"
  environment="staging"
  [note]="buildNote"
  tone="staging"
  [versions]="[
    { label: 'UI', value: '2.1.0' },
    { label: 'API', value: '3.0.1' },
  ]"
>
  <button hxStatusBarEnd type="button" (click)="reload()">Reload</button>
</helix-status-bar>

<ng-template #buildNote>
  <a href="https://ci.example.com/builds/456">Build #456</a>
</ng-template>

With <helix-app-layout>, pass the template through statusBarNote (string | TemplateRef<unknown>) and project the end control with the same hxStatusBarEnd attribute:

html
<helix-app-layout statusBarBrand="MyApp" [statusBarNote]="buildNote">
  <button hxStatusBarEnd type="button">Reload</button>
</helix-app-layout>

Tones ​

ToneBackgroundUse case
stagingAmberStaging / QA environment
productionDark (surface-800)Production environment
successGreenAll-clear status
dangerRedAlert / error status
neutralGrayDefault / unknown

HelixFooter ​

Selector: <helix-footer>
File: projects/shell/src/lib/layout/components/footer/footer.ts

Application footer with optional multi-column link layout and a branded copyright line.

Inputs ​

NameTypeDefaultDescription
brandNamestring'SAKAI'Brand name shown in the copyright line
brandUrlstring'https://gravionlabs.github.io/helix/'URL the brand name links to
columnsHelixFooterColumn[][]Optional link columns rendered side-by-side. Uses the same HelixFooterColumn model

Content Slots ​

SlotSelectorDescription
Start[gvFooterStart]Custom content rendered before the link columns

Example ​

html
<helix-footer
  brandName="Gravion"
  brandUrl="https://gravion.io"
  [columns]="footerColumns">
  <span gvFooterStart>© 2024 Gravion GmbH</span>
</helix-footer>
ts
footerColumns: HelixFooterColumn[] = [
  {
    title: 'Product',
    links: [
      { label: 'Features', url: '/features' },
      { label: 'Pricing',  url: '/pricing' },
    ],
  },
];

HelixNavRail ​

Selector: <helix-nav-rail>
File: projects/shell/src/lib/layout/components/nav-rail/nav-rail.ts

Branded side-navigation rail: gradient surface (theme-aware — "Harbor Tint" light / a neutral dark gradient that aliases the app's own dark-mode surface tokens (--surface-card/--surface-ground), so the rail matches the panels and body around it instead of an invented hue), a pill active state with a teal accent bar, expandable submenus, and collapse-to-icons. Wired into HelixAppLayout in place of the old HelixSidebar/HelixMenu. Items reuse HelixRouteMenuItem (the same shape consumed by helixMenuLinksFrom/helixRoutesFrom) — route-driven active state and breadcrumbs keep working unchanged.

Expandable items (any item with children that is not lifted into a section — every top-level folder in navStyle="tree", deeper levels in 'sections') render as a clickable row with a chevron (right when closed, down when open) and a subtle indent guide for the children. Several items can be open at once (LayoutStore.expandedKeys()); the group holding the active route opens automatically on navigation and can still be collapsed by the user.

Keyboard: Tab reaches every link; ArrowDown/ArrowUp move between visible links; Enter/Space toggle an expandable item (also ArrowRight to open, ArrowLeft to close). Expandable items expose aria-expanded; the active link has aria-current="page".

Collapsing. On desktop (> 991px) the rail's own toggle (bottom of the rail) collapses it to icons and back — it is the only collapse control; the topbar hamburger is hidden there in static menu mode. At ≤ 991px the rail is a drawer: the hamburger opens it with a mask, and a click outside or a navigation closes it (the drawer always shows labels). The collapsed state is remembered in localStorage (reads/writes are guarded, so it works without storage).

Collapsed rail. Links show a tooltip with their label. A section that has an icon (helixNavGroupsFromMenu copies it from the top-level item) becomes a single icon, and any expandable item opens its children in a flyout on hover and on keyboard focus (also Enter, Space or ArrowRight); Escape, leaving the item, or navigating closes it, and it is kept inside the viewport. Sections without an icon list their items directly.

The rail's brand icon is customizable via the brandIcon input — pass an inline SVG (<svg>…</svg>) or a URL to an SVG file. Falls back to the default helix icon when not provided. The app title (appTitle) renders alongside regardless.

Inputs ​

NameTypeDefaultDescription
modelHelixNavGroup[][]Grouped navigation model — each group has an optional uppercase section label and a HelixRouteMenuItem[] of items
appTitlestring'Helix'Application title shown in the brand area. Hidden when nav is collapsed
brandIconstring—Brand icon: inline SVG (<svg>…</svg>) or URL to an SVG file. Falls back to the default hardcoded icon

HelixNavGroup ​

ts
interface HelixNavGroup {
  section?: string;             // uppercase group label; omit for an unlabeled group
  items: HelixRouteMenuItem[];
}

Use helixNavGroupsFromMenu(items: HelixRouteMenuItem[], style: 'sections' | 'tree' = 'sections'): HelixNavGroup[] to adapt an existing flat HelixRouteMenuItem[] tree (as used by HelixAppLayout's menu input) into the shape HelixNavRail expects:

  • 'sections' (default) — every top-level item with children becomes an uppercase section heading (its icon is not shown) with its children listed directly beneath it, always visible. Consecutive top-level items without children form one unlabeled group. Deeper levels (a child that itself has children) still expand inline.
  • 'tree' — the whole list is one unlabeled group, so each top-level item with children renders as an expandable folder.

Changed default: menus with nested items used to render as collapsed folders. Pass navStyle="tree" to keep that look.

Construct HelixNavGroup[] by hand (and pass it as navGroups) for full control.

Example ​

ts
import { helixNavGroupsFromMenu, type HelixRouteMenuItem } from '@gravionlabs/helix-shell';

const menu: HelixRouteMenuItem[] = [
  {
    label: 'Overview',
    items: [
      { label: 'Dashboard', icon: 'pi pi-fw pi-home', routerLink: ['/'] },
      { label: 'Analytics', icon: 'pi pi-fw pi-chart-bar', routerLink: ['/analytics'] },
    ],
  },
];

const navGroups = helixNavGroupsFromMenu(menu); // 'sections': OVERVIEW → Dashboard, Analytics
const treeGroups = helixNavGroupsFromMenu(menu, 'tree'); // Overview folder
html
<helix-app-layout [menu]="menu" navStyle="sections" brandIcon="/assets/logo.svg" />

Internal Layout Components ​

The following components are exported for completeness but have no public inputs beyond what's listed here. They are orchestrated internally by HelixAppLayout.

ComponentSelectorPurpose
HelixNavRailItem[helix-nav-rail-item]Recursive item renderer used by HelixNavRail
HelixConfigurator<helix-configurator>Theme/layout configuration panel
HelixFloatingConfigurator<helix-floating-configurator>Floating toggle button for the configurator

Routing Utilities ​

Built-in helpers for deriving Angular routes, menu link models, and breadcrumbs from a single HelixRouteMenuItem[] tree — keeping route configuration and navigation menus in sync.

helixRoutesFrom ​

File: projects/shell/src/lib/layout/route-menu.model.ts

Converts a HelixRouteMenuItem tree into Angular Routes for use with the Router.

ts
import { helixRoutesFrom, type HelixRouteMenuItem } from '@gravionlabs/helix-shell';

const menu: HelixRouteMenuItem[] = [
  {
    label: 'Dashboard',
    icon: 'pi pi-home',
    path: 'dashboard',
    component: DashboardComponent,
  },
  {
    label: 'Settings',
    icon: 'pi pi-cog',
    path: 'settings',
    breadcrumb: 'Settings',
    component: SettingsComponent,
  },
];

export const appRoutes: Routes = helixRoutesFrom(menu);

Behaviour:

  • Items with path + component or loadChildren generate a route entry.
  • Items without path (visual-only section headers) are skipped, but their children are still recursed.
  • The breadcrumb value is injected into route.data['breadcrumb'].
  • Nested items under a routable item become child routes.
  • Route guards (canActivate) and lazy loading (loadChildren) are carried through.

Returns: Routes


helixMenuLinksFrom ​

File: projects/shell/src/lib/layout/route-menu.model.ts

Recursively copies a HelixRouteMenuItem[] tree and auto-populates routerLink from each item's path, relative to a basePath.

ts
import { helixMenuLinksFrom, type HelixRouteMenuItem } from '@gravionlabs/helix-shell';

const menu: HelixRouteMenuItem[] = [
  { label: 'Form Layout', icon: 'pi pi-fw pi-id-card', path: 'formlayout' },
  { label: 'Input',       icon: 'pi pi-fw pi-check-square', path: 'input' },
];

const links = helixMenuLinksFrom(menu, '/uikit');
// → routerLink: ['/uikit/formlayout'], routerLink: ['/uikit/input']

Parameters:

ParamTypeDescription
itemsHelixRouteMenuItem[]Source menu items
basePathstringAbsolute base path prefix

Returns: HelixRouteMenuItem[]


helixBreadcrumbsFromRoutes ​

File: projects/shell/src/lib/layout/breadcrumb-utils.ts

Builds a breadcrumb trail from the current Angular ActivatedRoute tree. Reads the breadcrumb key from each route's data and accumulates URL segments.

ts
import { inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { helixBreadcrumbsFromRoutes } from '@gravionlabs/helix-shell';

const route = inject(ActivatedRoute);
const crumbs = helixBreadcrumbsFromRoutes(route);

Where breadcrumb can be a static string or a function:

ts
{
  path: 'users/:id',
  data: { breadcrumb: (snapshot) => `User #${snapshot.params['id']}` },
}

Returns: HxMenuItem[]


Layout Store ​

LayoutStore is an NgRx Signal Store that manages all layout UI state. It is not provided globally — you must add it to the providers of your layout component.

State shape ​

PropertyTypeDescription
menuVisiblebooleanWhether the menu is shown
staticMenuDesktopInactivebooleanLegacy "hide the rail completely" flag. Still honoured by HelixAppLayout, but no longer reachable from the default UI
sidebarCollapsedbooleanDesktop rail collapsed to icons; persisted in localStorage (helix.nav-rail.collapsed)
overlayMenuActivebooleanOverlay menu open state
profileSidebarVisiblebooleanProfile sidebar open state
configSidebarVisiblebooleanConfig sidebar open state
staticMenuMobileActivebooleanStatic menu expanded on mobile
menuHoverActivebooleanMenu hover state (slim mode)
darkTheme()booleanDark mode: the value of HxTheme.dark() (read-only here)
primary(), surface()HxPrimaryColor | null, HxSurface | nullThe chosen colours: the values of HxTheme
menuMode'static' | 'overlay'Menu mode

Setup ​

ts
import { LayoutStore } from '@gravionlabs/helix-shell';

@Component({
  standalone: true,
  providers: [LayoutStore], // scoped to this component tree
  ...
})
export class MyLayoutComponent {
  private layoutStore = inject(LayoutStore);

  toggleDark() {
    this.layoutStore.toggleDarkMode(); // switches HxTheme; the class on <html> follows
  }
}

Auth Pages ​

HelixLogin ​

Selector: <helix-login>
File: projects/shell/src/lib/pages/auth/login/login.ts

Fully styled login page with email/password form. Emits credentials on submit; handles no server communication itself.

Inputs ​

NameTypeDefaultDescription
logoUrlstring''URL of the brand logo image. Empty string hides the logo
logoAltstring'Logo'Alt text for the logo image
headlinestring'Welcome back!'Main heading text
subheadlinestring'Sign in to continue'Sub-heading below the headline
emailPlaceholderstring'Email address'Placeholder text for the email field
passwordPlaceholderstring'Password'Placeholder text for the password field
submitLabelstring'Sign In'Label for the submit button
forgotPasswordLabelstring'Forgot password?'Label for the forgot-password link
forgotPasswordRoutestring'/auth/forgot'Router path for the forgot-password link
registerLabelstring"Don't have an account?"Label for the register prompt
registerRoutestring'/auth/register'Router path for the registration link

Outputs ​

NamePayloadDescription
loginSubmitHelixLoginCredentialsEmitted when the user submits the login form

Example ​

html
<helix-login
  logoUrl="/assets/logo.svg"
  headline="Sign in to Gravion"
  (loginSubmit)="onLogin($event)"
/>
ts
onLogin(credentials: HelixLoginCredentials) {
  this.authService.login(credentials.email, credentials.password).subscribe(...);
}

HelixError ​

Selector: <helix-error>

Generic error page (e.g. 500 Internal Server Error).

Inputs ​

NameTypeDefaultDescription
titlestring'Error'Main error heading
subtitlestring'Something went wrong'Supporting message below the title
homeLabelstring'Go to Dashboard'Label for the home navigation button
homeRoutestring'/'Router path for the home navigation button

Example ​

html
<helix-error
  title="500 — Server Error"
  subtitle="Our team has been notified. Please try again later."
  homeRoute="/dashboard"
/>

HelixAccess ​

Selector: <helix-access>

Access-denied / forbidden page (e.g. 403).

Inputs ​

NameTypeDefaultDescription
titlestring'Access Denied'Main heading
subtitlestring'You do not have permission to access this page'Supporting message
homeLabelstring'Go to Dashboard'Label for the home navigation button
homeRoutestring'/'Router path for the home navigation button

authRoutes ​

Pre-configured lazy route definitions for all auth pages. Import into your router config to automatically register /auth/login, /auth/error, and /auth/access.

ts
import { authRoutes } from '@gravionlabs/helix-shell';

export const appRoutes: Routes = [
  {
    path: 'auth',
    children: authRoutes,
  },
  { path: '**', redirectTo: 'auth/login' },
];

Other Pages ​

HelixEmpty ​

Selector: <helix-empty>
File: projects/shell/src/lib/pages/empty/empty.ts

Blank page template with a title, optional subtitle, and a default content slot. Use as a starting point for new pages.

Inputs ​

NameTypeDefaultDescription
titlestring'Empty Page'Page heading
subtitlestring''Optional supporting text below the heading

Content Slots ​

SlotSelectorDescription
Default(none)Any projected content rendered inside the page body

Example ​

html
<helix-empty title="Reports" subtitle="No reports available yet.">
  <h-button label="Create Report" icon="pi pi-plus" />
</helix-empty>

HelixNotfound ​

Selector: <helix-notfound>

404 Not Found page with configurable suggestions list.

Inputs ​

NameTypeDefaultDescription
titlestring'404 — Not Found'Main heading
descriptionstring'The page you are looking for does not exist.'Description text
homeLabelstring'Go to Dashboard'Label for the home navigation button
homeRoutestring'/'Router path for the home navigation button
suggestionsHelixNotfoundSuggestion[]Several default suggestionsList of quick-navigation suggestion links

Example ​

html
<helix-notfound
  homeRoute="/dashboard"
  [suggestions]="[
    { label: 'Dashboard', route: '/dashboard' },
    { label: 'Settings',  route: '/settings' },
  ]"
/>

Landing Page Components ​

Use these components to build a public marketing / landing page. The recommended composition is:

html
<helix-landing>
  <helix-topbar-widget />
  <helix-hero-widget (buttonClick)="scrollToFeatures()" />
  <helix-features-widget />
  <helix-highlights-widget />
  <helix-pricing-widget (planSelect)="onPlanSelect($event)" />
  <helix-footer-widget />
</helix-landing>

HelixLanding ​

Selector: <helix-landing>

Page wrapper / container for all landing widgets. Provides consistent max-width, spacing, and scroll-anchor support. No public inputs.


HelixTopbarWidget ​

Selector: <helix-topbar-widget>

Marketing topbar with navigation links and login/register buttons.

Inputs ​

NameTypeDefaultDescription
navLinksHelixNavLink[]4 links (home, features, pricing, contact)Fragment-based anchor links for single-page scrolling
loginLabelstring'Login'Label for the login button
loginRoutestring'/auth/login'Router path for the login button
registerLabelstring'Register'Label for the register button
registerRoutestring'/auth/login'Router path for the register button

Example ​

html
<helix-topbar-widget
  loginRoute="/auth/login"
  registerRoute="/auth/register"
  [navLinks]="[
    { label: 'Home',     fragment: 'hero' },
    { label: 'Features', fragment: 'features' },
    { label: 'Pricing',  fragment: 'pricing' },
  ]"
/>

HelixHeroWidget ​

Selector: <helix-hero-widget>

Full-width hero section with a two-part headline, description, call-to-action button, and hero image.

Inputs ​

NameTypeDefaultDescription
headlineLightstring(library default)Light-weight (thin font) portion of the headline
headlinestring(library default)Bold portion of the headline
descriptionstring(library default)Paragraph text below the headline
buttonLabelstring'Get Started'Label for the CTA button
imageUrlstring(library default)URL of the hero image
imageAltstring'Hero Image'Alt text for the hero image

Outputs ​

NamePayloadDescription
buttonClickvoidEmitted when the CTA button is clicked

Example ​

html
<helix-hero-widget
  headlineLight="Build faster with"
  headline="Gravion UI"
  description="The Angular component library that gets you to production in days."
  buttonLabel="Start for free"
  imageUrl="/assets/hero.png"
  (buttonClick)="router.navigate(['/auth/register'])"
/>

HelixFeaturesWidget ​

Selector: <helix-features-widget>

Feature highlight grid with optional customer testimonial card.

Inputs ​

NameTypeDefaultDescription
sectionTitlestring'Marvelous Features'Section heading
sectionSubtitlestring(library default)Section sub-heading
featuresHelixFeature[]9 default feature cardsArray of feature cards to display in the grid
testimonialHelixTestimonial | null(library default)Optional testimonial block. Pass null to hide

Example ​

html
<helix-features-widget
  sectionTitle="Why choose Gravion?"
  [features]="myFeatures"
  [testimonial]="myTestimonial"
/>
ts
myFeatures: HelixFeature[] = [
  {
    icon: 'pi pi-bolt',
    iconBgClass: 'bg-yellow-200',
    iconColorClass: 'text-yellow-700',
    title: 'Blazing Fast',
    description: 'Optimized bundles and lazy loading out of the box.',
  },
];

myTestimonial: HelixTestimonial = {
  name: 'Jane Doe',
  company: 'Acme Corp',
  text: 'Gravion UI cut our delivery time in half.',
  logoUrl: '/assets/acme-logo.svg',
};

HelixHighlightsWidget ​

Selector: <helix-highlights-widget>

Alternating image/text highlight blocks for showcasing key product capabilities.

Inputs ​

NameTypeDefaultDescription
sectionTitlestring'Powerful Everywhere'Section heading
sectionSubtitlestring(library default)Section sub-heading
highlightsHelixHighlight[]2 default highlight blocksArray of highlight items with image and text

Example ​

html
<helix-highlights-widget
  sectionTitle="Works on every device"
  [highlights]="myHighlights"
/>
ts
myHighlights: HelixHighlight[] = [
  {
    icon: 'pi pi-desktop',
    iconBgClass: 'bg-blue-100',
    iconColorClass: 'text-blue-600',
    title: 'Desktop First',
    description: 'Optimised layouts for productivity on large screens.',
    imageUrl: '/assets/desktop-preview.png',
    imageAlt: 'Desktop screenshot',
    imageBgClass: 'bg-blue-50',
    imageAlign: 'right',
  },
];

HelixPricingWidget ​

Selector: <helix-pricing-widget>

Pricing plan cards section with click-to-select interaction.

Inputs ​

NameTypeDefaultDescription
sectionTitlestring'Matchless Pricing'Section heading
sectionSubtitlestring(library default)Section sub-heading
plansHelixPricingPlan[]3 plans (Free / Startup / Enterprise)Array of pricing plan cards

Outputs ​

NamePayloadDescription
planSelectHelixPricingPlanEmitted when a card or its button is clicked

Example ​

html
<helix-pricing-widget
  [plans]="pricingPlans"
  (planSelect)="onPlanSelected($event)"
/>
ts
pricingPlans: HelixPricingPlan[] = [
  {
    title: 'Free',
    price: '$0',
    pricePeriod: '/ month',
    imageUrl: '/assets/plan-free.svg',
    imageAlt: 'Free plan',
    buttonLabel: 'Get started',
    features: ['5 projects', '1 GB storage', 'Community support'],
  },
  {
    title: 'Pro',
    price: '$29',
    pricePeriod: '/ month',
    imageUrl: '/assets/plan-pro.svg',
    imageAlt: 'Pro plan',
    buttonLabel: 'Start free trial',
    features: ['Unlimited projects', '50 GB storage', 'Priority support'],
  },
];

onPlanSelected(plan: HelixPricingPlan) {
  this.router.navigate(['/checkout'], { queryParams: { plan: plan.title } });
}

HelixFooterWidget ​

Selector: <helix-footer-widget>

Landing page footer with brand link and multi-column link groups. Uses the same HelixFooterColumn model as HelixFooter.

Inputs ​

NameTypeDefaultDescription
brandNamestring'SAKAI'Brand name displayed in the footer
homeRoutestring'/'Router path the brand name links to
columnsHelixFooterColumn[](library defaults)Link columns. Shares the HelixFooterColumn model with HelixFooter

UI Components ​

HelixBadge ​

Selector: <helix-badge>
File: projects/shell/src/lib/ui/badge/badge.ts

Small inline badge with color-coded severity and optional icon / label.

Inputs ​

NameTypeDefaultDescription
severityBadgeSeverity—'info' | 'warn' | 'error' | 'success'
labelstring—Text label inside the badge
iconstring—HelixIcons class (pi pi-*), e.g. 'pi pi-check'
size'sm' | 'md''md'Badge size variant

Example ​

html
<helix-badge severity="success" icon="pi pi-check" label="Verified" />
<helix-badge severity="warn" label="Pending" size="sm" />

HelixEnvironmentBadge ​

Selector: <helix-environment-badge>
File: projects/shell/src/lib/ui/badge/environment-badge.ts

Convenience wrapper around HelixBadge that maps a named environment to a fixed severity, icon, and label.

Inputs ​

NameTypeDefaultDescription
environmentEnvironment | CustomEnvironment—'development' | 'testing' | 'staging' | 'production', or { label: string; severity: 'info' | 'warn' | 'error' | 'success' }

Mapped appearance ​

EnvironmentSeverityIconLabel
developmentsuccesspi pi-codeDevelopment
testinginfopi pi-flaskTesting
stagingwarnpi pi-layersStaging
productionerrorpi pi-verifiedProduction
unknowninfopi pi-questionUnknown
{ label, severity }given severitynonegiven label (also the accessible name)

Example ​

html
<helix-environment-badge environment="staging" />
<helix-environment-badge [environment]="envName" />
<helix-environment-badge [environment]="{ label: 'Canary', severity: 'warn' }" />

HelixPageHeader ​

Selector: <helix-page-header>
File: projects/shell/src/lib/ui/page-header/page-header.ts

The header of a page: an optional breadcrumb, the title (an h1 by default) with a subtitle, and the page's actions on the end edge. The actions are projected with the helixPageActions attribute and wrap under the title on narrow screens.

Inputs ​

NameTypeDefaultDescription
titlestring— (required)The page title
subtitlestring—One line under the title
breadcrumbHxBreadcrumbItem[]—The trail above the title (rendered with hx-breadcrumb); its last item is the current page
homeHxBreadcrumbItem—The first item of the breadcrumb, usually a home icon
headingLevel1–61The heading element of the title

Example ​

html
<helix-page-header title="Invoices" subtitle="Open and paid invoices" [breadcrumb]="crumbs" [home]="{ icon: 'pi pi-home', routerLink: '/' }">
  <button helixPageActions hx-button type="button" variant="outlined">Export</button>
  <button helixPageActions hx-button type="button">New invoice</button>
</helix-page-header>

HelixStatCard ​

Selector: <helix-stat-card>
File: projects/shell/src/lib/ui/stat-card/stat-card.ts

A dashboard figure on an hx-card: a label, the value, an icon in a tinted box, and a trend whose direction is shown by an arrow and colour and read out as "up", "down" or "flat" by screen readers. Extra content is projected below the trend.

Inputs ​

NameTypeDefaultDescription
labelstring— (required)What the figure is; also the accessible name of the card
valuestring | number— (required)The figure; a number is formatted with format
formatIntl.NumberFormatOptions—e.g. { style: 'currency', currency: 'EUR' }
localestringbrowserLocale of the number formats
iconstring—Icon classes (pi pi-users)
severity'primary' | 'info' | 'success' | 'warn' | 'danger''primary'Colour of the icon box
trendnumber—The change: positive is up (green), negative is down (red), 0 is flat
trendUnitstring'%'Appended to the trend figure
trendLabelstring—Text after the trend ("since last month")
trendDigitsnumber1Fraction digits of the trend

Example ​

html
<helix-stat-card label="Orders" [value]="152" icon="pi pi-shopping-cart" [trend]="24" trendUnit="" trendLabel="new since last visit" />
<helix-stat-card label="Revenue" [value]="2100" [format]="{ style: 'currency', currency: 'EUR' }" [trend]="-3.2" trendLabel="since last week" severity="warn" />

HelixEmptyState ​

Selector: <helix-empty-state>
File: projects/shell/src/lib/ui/empty-state/empty-state.ts

The state of a list, table or page that has nothing to show: an icon, a title, a sentence that says what to do, and projected actions. medium (default) is the page-level state, small fits inside a card or the empty row of an hx-data-table (project it with hxTableEmpty).

Inputs ​

NameTypeDefaultDescription
titlestring— (required)The heading
descriptionstring—What the user can do about it
iconstring—Icon classes (pi pi-inbox)
size'small' | 'medium''medium'Padding and icon size
headingLevel2–63The heading element of the title

Example ​

html
<helix-empty-state icon="pi pi-inbox" title="No invoices yet" description="Invoices you create appear here.">
  <button hx-button type="button">New invoice</button>
</helix-empty-state>

<hx-data-table [value]="[]" [columns]="columns">
  <ng-template hxTableEmpty><helix-empty-state size="small" title="No results" description="Change the filter." /></ng-template>
</hx-data-table>

Form Infrastructure ​

Structural components for building reactive forms with human-readable error messages. The validators come from @gravionlabs/helix-ui/validators (see Validators); the shell itself does not depend on anything else for forms:

ts
import { Validators } from '@gravionlabs/helix-ui/validators';
import { FormControl } from '@angular/forms';

const emailCtrl = new FormControl('', [
  Validators.required('Email is required'),
  Validators.email('Invalid email address'),
]);

helix-form-field shows the first error message of the control once it is touched and invalid.


HelixFormField ​

Selector: <helix-form-field>
File: projects/shell/src/lib/form/form-field/form-field.ts

A structural wrapper component that renders a label, projected input content, and hint/error messages. Uses OnPush change detection and is fully standalone.

Inputs ​

NameTypeDefaultDescription
labelstring—Label text shown above the projected input
controlAbstractControl | nullnullReactive forms control for touched/invalid state detection
hintstring—Helper text shown below the field; hidden when an error is active
errorstring | nullnullExternal error message; overrides control-derived error
showLabelbooleantrueShow or hide the label
showHintbooleantrueShow or hide the hint/error area

Computed activeError ​

Priority: error() input > control validation error (when touched + invalid) > null

Usage examples ​

html
<!-- Text input with label, control, and hint -->
<helix-form-field label="Email" [control]="emailCtrl" hint="Work email preferred">
  <input hx-input fluid id="email" [formControl]="emailCtrl" />
</helix-form-field>

<!-- Helix number input -->
<helix-form-field label="Price" [control]="priceCtrl">
  <hx-input-number [formControl]="priceCtrl" mode="currency" currency="EUR" />
</helix-form-field>

<!-- External error (e.g. from server) -->
<helix-form-field label="Username" [control]="userCtrl" [error]="serverError()">
  <input hx-input fluid [formControl]="userCtrl" />
</helix-form-field>

Interfaces ​

HelixRouteMenuItem ​

The core menu/route model used by HelixAppLayout's [menu] input, HelixNavRail, helixRoutesFrom, helixMenuLinksFrom, and routing utilities. Extends HxMenuItem of helix-ui with Angular routing properties.

ts
interface HelixRouteMenuItem extends MenuItem {
  /** Angular route path segment (relative to parent route) */
  path?: string;
  /** Breadcrumb label or resolver function */
  breadcrumb?: string | ((route: ActivatedRouteSnapshot) => string);
  /** Component to render for this route */
  component?: Type<unknown>;
  /** Lazy-loaded children */
  loadChildren?: Route['loadChildren'];
  /** Route guards */
  canActivate?: CanActivateFn[];
  /** Additional route data (breadcrumb auto-injected) */
  data?: Record<string, unknown>;
  /** Nested child items (typed override of HxMenuItem.items) */
  items?: HelixRouteMenuItem[];
}

All HxMenuItem fields are inherited: label, icon, routerLink, visible, disabled, badge, target, command, url, etc.


HelixTopbarAction ​

Used by HelixTopbar topbarActions input.

ts
interface HelixTopbarAction {
  /** HelixIcons class (pi pi-*), e.g. 'pi pi-search' */
  icon: string;
  /** Accessible label for the button */
  label: string;
  /** Optional click handler */
  command?: () => void;
}

Used by HelixFooterColumn.

ts
interface HelixFooterLink {
  label: string;
  url: string;
}

HelixFooterColumn ​

Used by HelixFooter and HelixFooterWidget.

ts
interface HelixFooterColumn {
  title: string;
  links: HelixFooterLink[];
}

HelixLoginCredentials ​

Emitted by HelixLogin loginSubmit output.

ts
interface HelixLoginCredentials {
  email: string;
  password: string;
}

HelixNotfoundSuggestion ​

Used by HelixNotfound suggestions input.

ts
interface HelixNotfoundSuggestion {
  label: string;
  route: string;
}

Used by HelixTopbarWidget navLinks input.

ts
interface HelixNavLink {
  /** Display text */
  label: string;
  /** URL fragment (hash anchor) for single-page scrolling */
  fragment: string;
}

HelixFeature ​

Used by HelixFeaturesWidget features input.

ts
interface HelixFeature {
  /** HelixIcons class (pi pi-*), e.g. 'pi pi-bolt' */
  icon: string;
  /** Tailwind background class for the icon container, e.g. 'bg-yellow-200' */
  iconBgClass: string;
  /** Tailwind text-color class for the icon, e.g. 'text-yellow-700' */
  iconColorClass: string;
  title: string;
  description: string;
  /** Optional inline CSS string — used for gradient border effects */
  cardStyle?: string;
}

HelixTestimonial ​

Used by HelixFeaturesWidget testimonial input.

ts
interface HelixTestimonial {
  name: string;
  company: string;
  text: string;
  /** Optional company logo URL */
  logoUrl?: string;
}

HelixHighlight ​

Used by HelixHighlightsWidget highlights input.

ts
interface HelixHighlight {
  /** HelixIcons class (pi pi-*) */
  icon: string;
  /** Tailwind background class for the icon container */
  iconBgClass: string;
  /** Tailwind text-color class for the icon */
  iconColorClass: string;
  title: string;
  description: string;
  imageUrl: string;
  imageAlt: string;
  /** Tailwind background class for the image container, e.g. 'bg-purple-100' */
  imageBgClass: string;
  /** Position of the image relative to the text block */
  imageAlign: 'left' | 'right';
}

HelixPricingPlan ​

Used by HelixPricingWidget plans input and planSelect output.

ts
interface HelixPricingPlan {
  title: string;
  /** Price string, e.g. '$29' */
  price: string;
  /** Period label, e.g. '/ month' */
  pricePeriod: string;
  imageUrl: string;
  imageAlt: string;
  buttonLabel: string;
  features: string[];
}

Released under the MIT licence.