AI Prompt Box
Tier 2: Light-DOMAI Copilot prompt box with auto-expanding textarea, action toolbar, and stop state
Installation
$npx nnui add ai-prompt-box
copy$npm install nnui-kit
copyInteractive Preview & Code
Draft Autosave:
persist="local" (Type a prompt & refresh!)
Submitted Prompt:
(none)
<!-- Platform Innovations Live Banner -->
<div style="background: rgba(99, 102, 241, 0.08); border: 1px solid rgba(99, 102, 241, 0.2); border-radius: var(--ui-radius-md); padding: 0.65rem 1rem; width: 100%; max-width: 550px; display: flex; align-items: center; justify-content: space-between; font-size: 0.8rem; gap: 0.5rem; flex-wrap: wrap;">
<div style="display: flex; align-items: center; gap: 0.5rem;">
<span style="display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--ui-color-brand-500);"></span>
<span style="color: var(--ui-text-primary); font-weight: 600;">Draft Autosave:</span>
<span style="color: var(--ui-text-secondary);"><code style="color: var(--ui-color-brand-400);">persist="local"</code> (Type a prompt & refresh!)</span>
</div>
<button type="button" class="ui-button ui-button--secondary" onclick="window.nnuiInspect(document.getElementById('demo-prompt'))" style="padding: 0.2rem 0.6rem; font-size: 0.75rem; height: 26px;">
🤖 Inspect AI Schema
</button>
</div>
<ui-ai-prompt-box id="demo-prompt" max-rows="6" persist="local" placeholder="Ask AI coding assistant anything (draft auto-saves)..." style="width: 100%; max-width: 550px;">
<textarea data-part="input"></textarea>
<div data-part="toolbar">
<div style="display: flex; gap: 0.35rem;">
<button data-part="attach-btn" type="button" class="ui-button ui-button--ghost" style="padding: 0.3rem 0.5rem; font-size: 0.85rem;" title="Attach file">📎</button>
<button type="button" class="ui-button ui-button--ghost" style="padding: 0.3rem 0.5rem; font-size: 0.85rem;" title="Microphone">🎙️</button>
</div>
<div style="display: flex; gap: 0.35rem;">
<button data-part="stop-btn" type="button" class="ui-button ui-button--destructive" style="padding: 0.3rem 0.75rem; font-size: 0.8rem; display: none;">■ Stop</button>
<button data-part="submit-btn" type="button" class="ui-button" style="padding: 0.3rem 0.75rem; font-size: 0.8rem;">Send ▲</button>
</div>
</div>
</ui-ai-prompt-box>
<div data-ui="card" style="padding: 1rem 1.5rem; width: 100%; max-width: 550px; text-align: left; font-size: 0.85rem; color: var(--ui-text-secondary);">
Submitted Prompt: <code id="prompt-output" style="color: var(--ui-color-brand-500); font-weight: 600; display: block; margin-top: 0.35rem;">(none)</code>
</div>import React, { useState } from 'react';
import 'nnui-kit'; // Registers universal Light-DOM elements
export default function AipromptboxDemo() {
const [tab, setTab] = useState('all');
const [val, setVal] = useState(50);
const [selected, setSelected] = useState('');
const [query, setQuery] = useState('');
return (
<!-- Platform Innovations Live Banner -->
<div style="background: rgba(99, 102, 241, 0.08); border: 1px solid rgba(99, 102, 241, 0.2); border-radius: var(--ui-radius-md); padding: 0.65rem 1rem; width: 100%; max-width: 550px; display: flex; align-items: center; justify-content: space-between; font-size: 0.8rem; gap: 0.5rem; flex-wrap: wrap;">
<div style="display: flex; align-items: center; gap: 0.5rem;">
<span style="display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--ui-color-brand-500);"></span>
<span style="color: var(--ui-text-primary); font-weight: 600;">Draft Autosave:</span>
<span style="color: var(--ui-text-secondary);"><code style="color: var(--ui-color-brand-400);">persist="local"</code> (Type a prompt & refresh!)</span>
</div>
<button type="button" className="ui-button ui-button--secondary" onclick="window.nnuiInspect(document.getElementById('demo-prompt'))" style="padding: 0.2rem 0.6rem; font-size: 0.75rem; height: 26px;">
🤖 Inspect AI Schema
</button>
</div>
<ui-ai-prompt-box id="demo-prompt" max-rows="6" persist="local" placeholder="Ask AI coding assistant anything (draft auto-saves)..." style="width: 100%; max-width: 550px;">
<textarea data-part="input"></textarea>
<div data-part="toolbar">
<div style="display: flex; gap: 0.35rem;">
<button data-part="attach-btn" type="button" className="ui-button ui-button--ghost" style="padding: 0.3rem 0.5rem; font-size: 0.85rem;" title="Attach file">📎</button>
<button type="button" className="ui-button ui-button--ghost" style="padding: 0.3rem 0.5rem; font-size: 0.85rem;" title="Microphone">🎙️</button>
</div>
<div style="display: flex; gap: 0.35rem;">
<button data-part="stop-btn" type="button" className="ui-button ui-button--destructive" style="padding: 0.3rem 0.75rem; font-size: 0.8rem; display: none;">■ Stop</button>
<button data-part="submit-btn" type="button" className="ui-button" style="padding: 0.3rem 0.75rem; font-size: 0.8rem;">Send ▲</button>
</div>
</div>
</ui-ai-prompt-box>
<div data-ui="card" style="padding: 1rem 1.5rem; width: 100%; max-width: 550px; text-align: left; font-size: 0.85rem; color: var(--ui-text-secondary);">
Submitted Prompt: <code id="prompt-output" style="color: var(--ui-color-brand-500); font-weight: 600; display: block; margin-top: 0.35rem;">(none)</code>
</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>
<!-- Platform Innovations Live Banner -->
<div style="background: rgba(99, 102, 241, 0.08); border: 1px solid rgba(99, 102, 241, 0.2); border-radius: var(--ui-radius-md); padding: 0.65rem 1rem; width: 100%; max-width: 550px; display: flex; align-items: center; justify-content: space-between; font-size: 0.8rem; gap: 0.5rem; flex-wrap: wrap;">
<div style="display: flex; align-items: center; gap: 0.5rem;">
<span style="display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--ui-color-brand-500);"></span>
<span style="color: var(--ui-text-primary); font-weight: 600;">Draft Autosave:</span>
<span style="color: var(--ui-text-secondary);"><code style="color: var(--ui-color-brand-400);">persist="local"</code> (Type a prompt & refresh!)</span>
</div>
<button type="button" class="ui-button ui-button--secondary" onclick="window.nnuiInspect(document.getElementById('demo-prompt'))" style="padding: 0.2rem 0.6rem; font-size: 0.75rem; height: 26px;">
🤖 Inspect AI Schema
</button>
</div>
<ui-ai-prompt-box id="demo-prompt" max-rows="6" persist="local" placeholder="Ask AI coding assistant anything (draft auto-saves)..." style="width: 100%; max-width: 550px;">
<textarea data-part="input"></textarea>
<div data-part="toolbar">
<div style="display: flex; gap: 0.35rem;">
<button data-part="attach-btn" type="button" class="ui-button ui-button--ghost" style="padding: 0.3rem 0.5rem; font-size: 0.85rem;" title="Attach file">📎</button>
<button type="button" class="ui-button ui-button--ghost" style="padding: 0.3rem 0.5rem; font-size: 0.85rem;" title="Microphone">🎙️</button>
</div>
<div style="display: flex; gap: 0.35rem;">
<button data-part="stop-btn" type="button" class="ui-button ui-button--destructive" style="padding: 0.3rem 0.75rem; font-size: 0.8rem; display: none;">■ Stop</button>
<button data-part="submit-btn" type="button" class="ui-button" style="padding: 0.3rem 0.75rem; font-size: 0.8rem;">Send ▲</button>
</div>
</div>
</ui-ai-prompt-box>
<div data-ui="card" style="padding: 1rem 1.5rem; width: 100%; max-width: 550px; text-align: left; font-size: 0.85rem; color: var(--ui-text-secondary);">
Submitted Prompt: <code id="prompt-output" style="color: var(--ui-color-brand-500); font-weight: 600; display: block; margin-top: 0.35rem;">(none)</code>
</div>
</template><script>
import 'nnui-kit';
let activeTab = $state('all');
let sliderValue = $state(50);
let selected = $state('');
</script>
<!-- Platform Innovations Live Banner -->
<div style="background: rgba(99, 102, 241, 0.08); border: 1px solid rgba(99, 102, 241, 0.2); border-radius: var(--ui-radius-md); padding: 0.65rem 1rem; width: 100%; max-width: 550px; display: flex; align-items: center; justify-content: space-between; font-size: 0.8rem; gap: 0.5rem; flex-wrap: wrap;">
<div style="display: flex; align-items: center; gap: 0.5rem;">
<span style="display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--ui-color-brand-500);"></span>
<span style="color: var(--ui-text-primary); font-weight: 600;">Draft Autosave:</span>
<span style="color: var(--ui-text-secondary);"><code style="color: var(--ui-color-brand-400);">persist="local"</code> (Type a prompt & refresh!)</span>
</div>
<button type="button" class="ui-button ui-button--secondary" onclick="window.nnuiInspect(document.getElementById('demo-prompt'))" style="padding: 0.2rem 0.6rem; font-size: 0.75rem; height: 26px;">
🤖 Inspect AI Schema
</button>
</div>
<ui-ai-prompt-box id="demo-prompt" max-rows="6" persist="local" placeholder="Ask AI coding assistant anything (draft auto-saves)..." style="width: 100%; max-width: 550px;">
<textarea data-part="input"></textarea>
<div data-part="toolbar">
<div style="display: flex; gap: 0.35rem;">
<button data-part="attach-btn" type="button" class="ui-button ui-button--ghost" style="padding: 0.3rem 0.5rem; font-size: 0.85rem;" title="Attach file">📎</button>
<button type="button" class="ui-button ui-button--ghost" style="padding: 0.3rem 0.5rem; font-size: 0.85rem;" title="Microphone">🎙️</button>
</div>
<div style="display: flex; gap: 0.35rem;">
<button data-part="stop-btn" type="button" class="ui-button ui-button--destructive" style="padding: 0.3rem 0.75rem; font-size: 0.8rem; display: none;">■ Stop</button>
<button data-part="submit-btn" type="button" class="ui-button" style="padding: 0.3rem 0.75rem; font-size: 0.8rem;">Send ▲</button>
</div>
</div>
</ui-ai-prompt-box>
<div data-ui="card" style="padding: 1rem 1.5rem; width: 100%; max-width: 550px; text-align: left; font-size: 0.85rem; color: var(--ui-text-secondary);">
Submitted Prompt: <code id="prompt-output" style="color: var(--ui-color-brand-500); font-weight: 600; display: block; margin-top: 0.35rem;">(none)</code>
</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 { AIPromptBox } from 'nnui-kit/react';Universal Web Components (Vue 3, Svelte 5, Astro, HTMX)
<!-- Automatically registers <ui-ai-prompt-box> and <nnui-ai-prompt-box> -->
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.