Lit
Install CLI
Install the Elements CLI to your system. This creates a canonical executable path and adds the nve command to your path when possible.
macOS / Linux
Windows PowerShell
NodeJS curl -fsSL https://nvidia.github.io/elements/install.sh | bash
curl -fsSL https://nvidia.github.io/elements/install.sh | bash
irm https://nvidia.github.io/elements/install.ps1 | iex
irm https://nvidia.github.io/elements/install.ps1 | iex
# install the CLI
npm install -g @nvidia-elements/cli
# install the CLI
npm install -g @nvidia-elements/cli
Create a New Project
Use the Elements CLI to quickly bootstrap a new lit project with the necessary dependencies:
nve project.create --type=lit
nve project.create --type=lit
Setup an Existing Project
Setup an existing project to use Elements you can use the setup command to add the necessary dependencies and configure the MCP server.
nve project.setup
nve project.setup
If not yet done, install NodeJS. NodeJS is a JavaScript runtime that has a large ecosystem of tooling and packages for Web Development. Once installed the Node Package Manager (NPM) will be available for use.
Manual Integration
If installing to an existing project, install the core dependencies:
# install core dependencies
npm install @nvidia-elements/themes @nvidia-elements/styles @nvidia-elements/core
# install core dependencies
npm install @nvidia-elements/themes @nvidia-elements/styles @nvidia-elements/core
import '@nvidia-elements/core/alert/define.js';
import '@nvidia-elements/core/alert/define.js';
Properties and events then work via the standard lit template syntax.
// - ?hidden - HTML Boolean attribute
// - status - HTML attribute
// - .closable - can update via attributes or JavaScript property binding
// - @close - event listener binding for 'close' custom event
// - ?hidden - HTML Boolean attribute
// - status - HTML attribute
// - .closable - can update via attributes or JavaScript property binding
// - @close - event listener binding for 'close' custom event
<nve-alert-group status="success" ?hidden=${!showAlert}>
<nve-alert .closable=${true} @close=${() => showAlert = false}">hello there!</nve-alert>
</nve-alert-group>
<nve-alert-group status="success" ?hidden=${!showAlert}>
<nve-alert .closable=${true} @close=${() => showAlert = false}">hello there!</nve-alert>
</nve-alert-group>
CSS Utilities
Elements provides layout and typography utilities to make it easy to style your UI.
These utilities are global CSS attributes that apply to any element.
To use these utilities within a Lit element, you need to import the styles, so they are available in your elements Shadow DOM.
Import the needed style files via CSS or Typescript: /* Import CSS attributes via Typescript */
import { html, unsafeCSS, LitElement } from 'lit';
import { customElement } from 'lit/decorators/custom-element.js';
// https://github.com/tc39/proposal-import-attributes
import typography from '@nvidia-elements/styles/dist/typography.css' with { type: 'css' };
import layout from '@nvidia-elements/styles/dist/layout.css' with { type: 'css' };
@customElement('my-element')
class MyElement extends LitElement {
static styles = [typography, layout];
render() {
return html`
<div nve-layout="column gap:lg">
<p nve-text="display">display</p>
<p nve-text="heading">heading</p>
<p nve-text="body">body</p>
<p nve-text="label">label</p>
<p nve-text="label sm">label sm</p>
</div>
`;
}
}
/* Import CSS attributes via Typescript */
import { html, unsafeCSS, LitElement } from 'lit';
import { customElement } from 'lit/decorators/custom-element.js';
// https://github.com/tc39/proposal-import-attributes
import typography from '@nvidia-elements/styles/dist/typography.css' with { type: 'css' };
import layout from '@nvidia-elements/styles/dist/layout.css' with { type: 'css' };
@customElement('my-element')
class MyElement extends LitElement {
static styles = [typography, layout];
render() {
return html`
<div nve-layout="column gap:lg">
<p nve-text="display">display</p>
<p nve-text="heading">heading</p>
<p nve-text="body">body</p>
<p nve-text="label">label</p>
<p nve-text="label sm">label sm</p>
</div>
`;
}
}
/* Import CSS attributes via CSS */
@import '@nvidia-elements/styles/typography.css';
@import '@nvidia-elements/styles/layout.css';
/* Import CSS attributes via CSS */
@import '@nvidia-elements/styles/typography.css';
@import '@nvidia-elements/styles/layout.css';
When using Elements in forms with Lit components you can leverage the HTML FormData API to manage form state and validation.
Attach events to the form element to capture submit and input events. Using FormData, the name of the input serves as the key for the form values.
@customElement('app-login')
export class AppLogin extends LitElement {
@query('form') form: HTMLFormElement;
@state() formValues = { email: '', password: '', remember: false };
render() {
return html`
<form @submit=${e => this.#submit(e)} @input=${this.#input}>
<nve-input>
<label>Email</label>
<input .value=${this.formValues.email} type="email" name="email" autocomplete="off" pattern=".+@nvidia.com" required autocomplete="off" />
<nve-control-message error="valueMissing">required</nve-control-message>
<nve-control-message error="patternMismatch">invalid NVIDIA email</nve-control-message>
</nve-input>
<nve-password>
<label>Password</label>
<input .value=${this.formValues.password} type="password" name="password" minlength="6" required />
<nve-control-message error="valueMissing">required</nve-control-message>
<nve-control-message error="tooShort">minimum length is 6 characters</nve-control-message>
</nve-password>
<nve-checkbox>
<label>Remember me</label>
<input ?checked=${this.formValues.remember} type="checkbox" name="remember" />
</nve-checkbox>
<nve-button interaction="emphasis">Login</nve-button>
</form>
`;
}
#input() {
this.formValues = Object.fromEntries(new FormData(this.form)) as any;
}
#submit(e) {
e.preventDefault();
if (this.form.reportValidity()) {
console.log(this.formValues)
}
}
}
@customElement('app-login')
export class AppLogin extends LitElement {
@query('form') form: HTMLFormElement;
@state() formValues = { email: '', password: '', remember: false };
render() {
return html`
<form @submit=${e => this.#submit(e)} @input=${this.#input}>
<nve-input>
<label>Email</label>
<input .value=${this.formValues.email} type="email" name="email" autocomplete="off" pattern=".+@nvidia.com" required autocomplete="off" />
<nve-control-message error="valueMissing">required</nve-control-message>
<nve-control-message error="patternMismatch">invalid NVIDIA email</nve-control-message>
</nve-input>
<nve-password>
<label>Password</label>
<input .value=${this.formValues.password} type="password" name="password" minlength="6" required />
<nve-control-message error="valueMissing">required</nve-control-message>
<nve-control-message error="tooShort">minimum length is 6 characters</nve-control-message>
</nve-password>
<nve-checkbox>
<label>Remember me</label>
<input ?checked=${this.formValues.remember} type="checkbox" name="remember" />
</nve-checkbox>
<nve-button interaction="emphasis">Login</nve-button>
</form>
`;
}
#input() {
this.formValues = Object.fromEntries(new FormData(this.form)) as any;
}
#submit(e) {
e.preventDefault();
if (this.form.reportValidity()) {
console.log(this.formValues)
}
}
}