Input & Field
Tier 0: Zero-JSForm text inputs and labeled field containers
Installation
$npx nnui add input
copy$npm install nnui-kit
copyInteractive Preview & Code
We'll never share your email with third parties.
🔍
Username contains forbidden special characters.
<!-- Standard Field with Label and Hint -->
<div data-ui="field">
<label for="email" data-ui="label" data-required="true">Email Address</label>
<input id="email" data-ui="input" type="email" placeholder="name@company.com">
<span data-ui="hint">We'll never share your email.</span>
</div>
<!-- Input with Left Icon -->
<div data-ui="field">
<label for="search" data-ui="label">Search</label>
<div data-part="input-group">
<span data-part="input-icon-left">🔍</span>
<input id="search" data-ui="input" type="search" placeholder="Search...">
</div>
</div>
<!-- Invalid Input State -->
<div data-ui="field">
<label for="username" data-ui="label">Username</label>
<input id="username" data-ui="input" aria-invalid="true">
<span data-ui="error">Username contains forbidden characters.</span>
</div>import React, { useState } from 'react';
import 'nnui-kit'; // Registers universal Light-DOM elements
export default function InputfieldDemo() {
const [tab, setTab] = useState('all');
const [val, setVal] = useState(50);
const [selected, setSelected] = useState('');
const [query, setQuery] = useState('');
return (
<!-- Standard Field with Label and Hint -->
<div data-ui="field">
<label htmlFor="email" data-ui="label" data-required="true">Email Address</label>
<input id="email" data-ui="input" type="email" placeholder="name@company.com" />
<span data-ui="hint">We'll never share your email.</span>
</div>
<!-- Input with Left Icon -->
<div data-ui="field">
<label htmlFor="search" data-ui="label">Search</label>
<div data-part="input-group">
<span data-part="input-icon-left">🔍</span>
<input id="search" data-ui="input" type="search" placeholder="Search..." />
</div>
</div>
<!-- Invalid Input State -->
<div data-ui="field">
<label htmlFor="username" data-ui="label">Username</label>
<input id="username" data-ui="input" aria-invalid="true" />
<span data-ui="error">Username contains forbidden characters.</span>
</div>
);
}<script setup>
import { ref } from 'vue';
import 'nnui-kit'; // Registers universal Light-DOM elements
const activeTab = ref('all');
const sliderValue = ref(50);
const selected = ref('');
const query = ref('');
const handleSelect = (val) => {
console.log('Selected:', val);
};
</script>
<template>
<!-- Standard Field with Label and Hint -->
<div data-ui="field">
<label for="email" data-ui="label" data-required="true">Email Address</label>
<input id="email" data-ui="input" type="email" placeholder="name@company.com">
<span data-ui="hint">We'll never share your email.</span>
</div>
<!-- Input with Left Icon -->
<div data-ui="field">
<label for="search" data-ui="label">Search</label>
<div data-part="input-group">
<span data-part="input-icon-left">🔍</span>
<input id="search" data-ui="input" type="search" placeholder="Search...">
</div>
</div>
<!-- Invalid Input State -->
<div data-ui="field">
<label for="username" data-ui="label">Username</label>
<input id="username" data-ui="input" aria-invalid="true">
<span data-ui="error">Username contains forbidden characters.</span>
</div>
</template><script>
import 'nnui-kit';
let activeTab = $state('all');
let sliderValue = $state(50);
let selected = $state('');
</script>
<!-- Standard Field with Label and Hint -->
<div data-ui="field">
<label for="email" data-ui="label" data-required="true">Email Address</label>
<input id="email" data-ui="input" type="email" placeholder="name@company.com">
<span data-ui="hint">We'll never share your email.</span>
</div>
<!-- Input with Left Icon -->
<div data-ui="field">
<label for="search" data-ui="label">Search</label>
<div data-part="input-group">
<span data-part="input-icon-left">🔍</span>
<input id="search" data-ui="input" type="search" placeholder="Search...">
</div>
</div>
<!-- Invalid Input State -->
<div data-ui="field">
<label for="username" data-ui="label">Username</label>
<input id="username" data-ui="input" aria-invalid="true">
<span data-ui="error">Username contains forbidden characters.</span>
</div>How to Utilize
NNUI-KIT components live directly in the document Light DOM. You can use them via declarative HTML, with our first-class React wrapper, or platform-natively in Svelte, Vue, Astro, and HTMX:
React 18 & 19 (Next.js 15 App Router)
import 'nnui-kit/css';
import 'nnui-kit/client';
import { InputField } from 'nnui-kit/react';Universal Web Components (Vue 3, Svelte 5, Astro, HTMX)
<!-- Automatically registers <ui-input> and <nnui-input> -->
import 'nnui-kit/css';
import 'nnui-kit/client';Platform Features
Zero Shadow DOM
Element lives in the Light DOM. Tailwind and global CSS apply directly.
persist="url | local"
Add declarative persistence attribute to auto-sync state with URL search params.
sync="cross-tab"
Synchronize changes across all open browser tabs via BroadcastChannel.