Developers

Nova supports developers with the tools they need to build more product in less time, while saving them from the mind-numbing work of creating the same base components over and over again.

Getting Started with Web Components

Web Components allows us to create custom tags that can be reused in any HTML based application. We take advantage of this to offer a cross-platform solution for the Nova UI components.

This includes three packages: the native package that can be used in in any HTML environment, and two additional wrapper packages for React and Angular. These wrappers provide TypeScript support and IDE autocompletion, making development easier and faster in these environments.

Prerequisites

To access our npm packages hosted on GitHub Packages, you must authenticate with a GitHub token. Follow these steps to obtain and set up your token:

  • Ensure you are a member of the EliaGroup-Innersource organization on GitHub. You can apply for access here.
  • Navigate to your developer settings on GitHub: https://github.com/settings/apps
  • Create a new personal access token (classic) with the scope read:packages.
  • Copy the token and set an environment variable on your machine named NPM_GITHUB_AUTH_TOKEN.
  • Click the Configure SSO button and authorize the EliaGroup-Innersource organization to use this token.

Installation

Before installing the Nova packages, you must configure your package manager to authenticate correctly with the GitHub Packages registry. This setup involves configuring npm or Yarn to use custom registries and include authorization tokens.

Configuring npm

Add the following lines to your project’s .npmrc file. This configuration tells npm where to fetch the packages and includes the authorization needed to access private packages:

@eliagroup-innersource:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NPM_GITHUB_AUTH_TOKEN}

Configuring Yarn

When using Yarn, it’s important to set up Yarn to recognize npm's private registries and authentication tokens. Extend the registry settings from your .npmrc in a new .yarnrc file within the same project directory:

registry "https://npm.pkg.github.com"
"@eliagroup-innersource:registry" "https://npm.pkg.github.com"

After defining these registry settings, Yarn will use the existing npm configurations for authentication. So make sure to keep both files within the root of your project.

Installing the packages

You can now proceed to install the Nova packages. Ensure that your authentication token is set correctly in your environment variables (recommended) or set it directly in the installation command if necessary.

NPM_GITHUB_AUTH_TOKEN="yourtoken" npm add @eliagroup-innersource/nova-core @eliagroup-innersource/nova-components-native

If you set the token in your machine's environment variables:

npm add @eliagroup-innersource/nova-core @eliagroup-innersource/nova-components-native

Usage

1. Import the package and CSS in your main JavaScript file:

import '@eliagroup-innersource/nova-components-native';
import '@eliagroup-innersource/nova-components-native/nova-components.css';

2. Add the icons and font files to your CSS bundle:

@font-face {
  font-display: block;
  font-family: 'nova-icons';
  font-weight: normal;
  font-style: normal;
  src: url('@eliagroup-innersource/nova-core/dist/assets/fonts/nova-icons.woff2')
    format('woff2');
  descent-override: 15%;
}
@font-face {
  font-family: 'TT Norms Pro';
  font-style: normal;
  font-weight: 400;
  src: url('@eliagroup-innersource/nova-core/dist/assets/fonts/tt-norms-pro-normal.woff2')
    format('woff2');
  font-display: swap;
  ascent-override: 110%;
}
@font-face {
  font-family: 'TT Norms Pro';
  font-style: normal;
  font-weight: 500;
  src: url('@eliagroup-innersource/nova-core/dist/assets/fonts/tt-norms-pro-medium.woff2')
    format('woff2');
  font-display: swap;
  ascent-override: 110%;
}
@font-face {
  font-family: 'TT Norms Pro';
  font-style: normal;
  font-weight: 700;
  src: url('@eliagroup-innersource/nova-core/dist/assets/fonts/tt-norms-pro-bold.woff2')
    format('woff2');
  font-display: swap;
  ascent-override: 110%;
}

Note: depending on your build system, you may need to use relative imports for the font files. For example: src: url('../node_modules/@eliagroup-innersource/nova-core/dist/assets/fonts/nova-icons.woff2')

3. Wrap your app content with the `nv-theme` component to ensure proper theming and dark mode functionality:

<nv-theme>
  <div id="app">
    <!-- Your app content goes here -->
  </div>
</nv-theme>

Use Nova Components in your HTML:

<nv-button cta level="1">My Button</nv-button>

Setting up Dark Mode

To toggle dark mode, set the dark class on the html element:

<html class="dark">
  <!-- Your app content -->
</html>

Make sure to wrap your app with the nv-theme component.

Using the React wrappers

While React can already render web components, it makes some assumptions about HTML elements that don't always hold true for custom elements, making them harder to use. For instance, React assumes that all JSX properties map to HTML attributes and provides no way to set properties, making it difficult to pass complex data to web components. It also assumes that all DOM events have corresponding "event properties" and uses those instead of addEventListener().

The React wrappers take care of setting properties and listening to events for you, making it easier to integrate Nova Components until React fixes these issues.

Installation

Follow the steps outlined in the for installing the nova-core and nova-components-native packages.

Additionally, you need to install the react wrappers:

npm add @eliagroup-innersource/nova-components-react

Usage

1. Import the CSS in your main file and ensure it's available globally:

import '@eliagroup-innersource/nova-components-native/nova-components.css';

2.Add the icons and font files to your CSS bundle as described in the section above.

3.Wrap your app with the NvTheme component:

import { NvTheme } from '@eliagroup-innersource/nova-components-react';

const AppLayout = () => (
  <NvTheme>
    {/* Your app content */}
  </NvTheme>
);

4.Import and use Nova Components in any React component:

import { NvButton } from '@eliagroup-innersource/nova-components-react';

const MyComponent = () => (
  <NvButton cta level="1" onClick={handleClick}>
    My Button
  </NvButton>
);

Using the Angular wrappers

While you could directly use the web components in an Angular project, you would need to set CUSTOM_ELEMENTS_SCHEMA globally. This would disable all static type checking of your other components. Also, you would not have any autocompletion features or static type checking for the UI elements. Our Angular wrappers take care of setting input properties and listening to output events. Since Angular uses web components, the Nova native web components will inject the shadow DOM into the Angular wrappers. The wrappers ensure that Angular properties stay in sync with the native properties.

Installation

Follow the steps outlined in the web-components section for installing the nova-core and nova-components-native packages.

Additionally, you need to install the angular wrappers:

npm add @eliagroup-innersource/nova-components-angular

Usage

1. Import the native nova components JS into your `main.ts` file

import '@eliagroup-innersource/nova-components-native';

2. Add the NovaComponentsModule to your application module's imports. This will make all of the wrapper components available globally.

// app.module.ts
...
import { NovaComponentsModule } from '@eliagroup-innersource/nova-components-angular';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, NovaComponentsModule],
  providers: [],
  bootstrap: [AppComponent],
  schemas: [],
})
export class AppModule {}

3. Import the CSS in your main css file and ensure it's available globally:

@import '@eliagroup-innersource/nova-components-native/nova-components.css';

4. Add the icons and font files to your CSS bundle as described in the section above.

5. Wrap your app with the `NvTheme` component:

# app.component.html
<nv-theme>
  ...
</nv-theme>

6. Use the Nova components

<nv-stack [gutter]="2" mb="6">
  <nv-button cta level="1" (onClick)="clickCallback()">Button</nv-button>
  <nv-button cta level="1" (onClick)="clickCallback()">Button</nv-button>
  <nv-button cta level="1" (onClick)="clickCallback()">Button</nv-button>
</nv-stack>

Getting Started With Blazor

1. Install Package

Get the Nugget package from : https://artifactstore.belgrid.net/feeds/libraries/Nova/versions

dotnet add package nova-blazor@X.X.X

2. Reference Nova (globally) within your project

Within the _Imports.razor file, add the using statements below. Alternatively, you can add these using statements to the top of each component file.

@using Nova.Components
@using Nova.Constants
@using Nova.Services
@using Nova.Utils

3. Add the building services

Within the Program.cs file, add the following line to add the Nova Design System to the services collection. Make sure the line is added before the builder.Build() method is called.

NVServices.AddNovaDesignSystem(builder.Services);

4. HTML Layout in wwwroot

Styles

Add css in the head of your layout.

<link href="_content/Nova/assets/css/nova.css" rel="stylesheet"/>

Scripts

Add script fot the theme (light/dark) management in the head oy your layout.

<script async>
  try {
  if (localStorage.theme === "dark" || (!(localStorage.theme) && window.matchMedia("(prefers-color-scheme: dark)").matches)) {
  document.documentElement.classList.add("dark");
} else {
  document.documentElement.classList.remove("dark");
}
} catch (_) {
}
</script>

Add script for webassembly and nova at the bottom of the body before

<script src="_content/Nova/assets/js/nova.js"></script>
<script src="_framework/blazor.webassembly.js"></script>

Full sample of the index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
    <title>App</title>

    <script async>
      try {
        if (localStorage.theme === "dark" || (!(localStorage.theme) && window.matchMedia("(prefers-color-scheme: dark)").matches)) {
          document.documentElement.classList.add("dark");
        } else {
          document.documentElement.classList.remove("dark");
        }
      } catch (_) {
      }
    </script>

    <base href="/"/>
    <link href="_content/Nova/assets/css/nova.css" rel="stylesheet"/>
  </head>

  <body>
    <div id="app">
      <div id="app-loader" style="position:fixed;inset:0;display:flex;align-items: center;justify-content: center;">
        <div class="nv-loader nv-loader-xl primary is-loading"></div>
      </div>
    </div>
    <div id="blazor-error-ui">
      An unhandled error has occurred.
      <a href="" class="reload">Reload</a>
      <a class="dismiss">🗙</a>
    </div>

    <script src="_content/Nova/assets/js/nova.js"></script>
    <script defer src="_framework/blazor.webassembly.js"></script>
  </body>
</html>

Sample of Main Layout

@inherits LayoutComponentBase
@inject Nova.Services.NVAppStateService AppState;

<NVNVLayout HasSidebarOpened="AppState.IsSidebarVisible()" >
  <NVLayoutHeader>
    <NVStack PX="8" Height="64px" Color="primary">
      <NVButton ML="-5" MR="3" Level="1" Color="primary" Display="block" MD="@(new {Display = "hidden"})" Icon="menu" OnClick="@(() => AppState.ToggleDisplaySidebar())" />
      <NVBlock>LOGO</NVBlock>
      <NVNav Level="1" Color="primary" ML="auto" Gutter="4">
        <NVLink Title="link 1" Href="#">link 1</NVLink>
        <NVLink Title="link 2" Href="#">link 2</NVLink>
        <NVLink Title="link 3" Href="#">link 3</NVLink>
      </NVNav>
    </NVStack>
  </NVLayoutHeader>

  <NVLayoutSidebar>
    <NVSidebar Stack StackVertical Color="white" HFull>
      <NVButton Shrink="0" Grow="0" Level="2" Display="block" ML="auto" MD="@(new {Display = "hidden"})" Icon="x" OnClick="@(() => AppState.DisplaySidebar(false))" />
      <NVNav Vertical Color="primary" Level="1" Overflow="auto">
        <NVLink Title="Search" Href="#" Stack GutterX="3">
          <NVIcon Name="search" Small></NVIcon>
          <NVBlock Display="block" MD="@(new {Display = "hidden"})" XL="@(new {Display = "block"})">Search</NVBlock>
        </NVLink>
        <NVLink Title="Edit" Href="#" Stack GutterX="3">
          <NVIcon Name="edit" Small></NVIcon>
          <NVBlock Display="block" MD="@(new {Display = "hidden"})" XL="@(new {Display = "block"})">Edit</NVBlock>
        </NVLink>
        <Link Title="Delete" Href="#" Stack GutterX="3">
          <NVIcon Name="trash" Small></NVIcon>
          <NVBlock Display="block" MD="@(new {Display = "hidden"})" XL="@(new {Display = "block"})">Delete</NVBlock>
        </Link>
      </NVNav>
    </NVSidebar>
  </NVLayoutSidebar>

  <NVLayoutContent>
    <NVBlock P="8">
      @Body
    </NVBlock>
  </NVLayoutContent>
</NVNVLayout>

<NVOverlays />

@code {
  protected override void OnInitialized()
  {
    base.OnInitialized();
    AppState.DisplaySidebar(false);
  } 
}