UI Components

Pre-built, customizable components for rapid development

Installation

Add components to your project using the CLI:

# Add specific components
noun add button card table input

# Add all components
noun add --all

# List available components
noun list

Components are installed to components/ui/

Buttons

Button

A flexible button with multiple variants and states.

Usage
import { Button } from './components/ui/button.js'

mount('#btn', Button, {
  variant: 'primary',
  size: 'md',
  loading: false
})

Props

PropTypeDefaultDescription
variantstring'primary'primary, secondary, outline, ghost, danger, success, warning, link
sizestring'md'xs, sm, md, lg, xl
disabledbooleanfalseDisable button
loadingbooleanfalseShow loading spinner
blockbooleanfalseFull width button
iconstring''Icon HTML

Events

EventPayloadDescription
btn-clickEventButton clicked

Form Inputs

Input

Text input with label and error states.

import { Input } from './components/ui/input.js'

mount('#input', Input, {
  type: 'email',
  label: 'Email',
  placeholder: 'you@example.com',
  required: true,
  error: ''  // Error message to display
})

Props

PropTypeDefaultDescription
typestring'text'Input type
labelstring''Label text
placeholderstring''Placeholder text
valuestring''Input value
errorstring''Error message
helpTextstring''Help text

Events

EventPayloadDescription
input-change{ value }Value changed
input-blur{ value }Input blurred

Textarea

Multi-line text input.

mount('#textarea', Textarea, {
  label: 'Description',
  rows: 4,
  maxLength: 500
})

Checkbox

Checkbox input with label.

mount('#checkbox', Checkbox, {
  label: 'Accept terms',
  checked: false
})

Toggle

Toggle switch input.

mount('#toggle', Toggle, {
  label: 'Enable notifications',
  checked: true
})

RadioGroup

Group of radio buttons.

mount('#radios', RadioGroup, {
  name: 'size',
  options: [
    { value: 'sm', label: 'Small' },
    { value: 'md', label: 'Medium' },
    { value: 'lg', label: 'Large' }
  ],
  value: 'md'
})

Select & Dropdown

Select

Dropdown select input.

mount('#select', Select, {
  label: 'Country',
  options: [
    { value: 'us', label: 'United States' },
    { value: 'uk', label: 'United Kingdom' },
    { value: 'ca', label: 'Canada' }
  ],
  value: 'us',
  searchable: true
})

MultiSelect

Multi-value select with tags.

mount('#tags', MultiSelect, {
  options: [
    { value: 'react', label: 'React' },
    { value: 'vue', label: 'Vue' },
    { value: 'angular', label: 'Angular' }
  ],
  value: ['react', 'vue'],
  max: 5
})

Alert & Toast

Alert

Alert message box.

mount('#alert', Alert, {
  variant: 'success', // info, success, warning, error
  title: 'Success!',
  message: 'Your changes have been saved.',
  dismissible: true
})

Toast

Toast notifications.

import { toast } from './components/ui/alert.js'

toast.success('Item saved successfully!')
toast.error('Failed to save item')
toast.info('New updates available')
toast.warning('Session expiring soon')

// With options
toast.success('Saved!', {
  duration: 5000,
  position: 'top-right'
})

Card

Card

Container card with header, body, and footer.

mount('#card', Card, {
  bordered: true,
  hoverable: false,
  shadow: 'sm' // none, sm, md, lg
})
HTML Structure
<div class="card">
  <header>Card Title</header>
  <section>
    <p>Card content goes here.</p>
  </section>
  <footer>
    <button class="btn-secondary">Cancel</button>
    <button class="btn">Save</button>
  </footer>
</div>

Table

Table

Data table with sorting and pagination.

import { Table } from './components/ui/table.js'

mount('#table', Table, {
  columns: [
    { key: 'name', label: 'Name', sortable: true },
    { key: 'email', label: 'Email', sortable: true },
    { key: 'role', label: 'Role' },
    {
      key: 'status',
      label: 'Status',
      render: (value) => `<span class="badge">${value}</span>`
    }
  ],
  data: users,
  sortable: true,
  pagination: true,
  pageSize: 10,
  selectable: true
})

Events

EventPayloadDescription
row-click{ row, index }Row clicked
sort{ column, direction }Sort changed
select{ selected }Selection changed
page-change{ page }Page changed

NounTable Pro

A powerful, feature-rich data grid component inspired by svelte-tablecn/tablecn.com. Perfect for building admin panels, dashboards, and data-heavy applications.

9
Cell Variants
Keyboard
Navigation
Copy
& Paste
Undo
& Redo
Usage
import { NounTable, CellVariant } from '@noundryfx/nounjs/components'

const table = new NounTable('#my-table', {
  data: [
    { id: 1, name: 'John Doe', email: 'john@example.com', age: 32, active: true },
    { id: 2, name: 'Jane Smith', email: 'jane@example.com', age: 28, active: true }
  ],
  columns: [
    { key: 'name', label: 'Name' },
    { key: 'email', label: 'Email' },
    { key: 'age', label: 'Age', meta: { variant: CellVariant.NUMBER } },
    { key: 'active', label: 'Active', meta: { variant: CellVariant.CHECKBOX } },
    {
      key: 'status',
      label: 'Status',
      meta: {
        variant: CellVariant.SELECT,
        options: [
          { value: 'active', label: 'Active' },
          { value: 'inactive', label: 'Inactive' }
        ]
      }
    }
  ],
  enableSearch: true,
  enableFiltering: true,
  enableSorting: true,
  enableRowSelection: true,
  showPagination: true
})

table.mount()

// Listen for changes
table.on('data-change', ({ data }) => {
  // Save to backend
})

Cell Variants

VariantDescriptionOptions
SHORT_TEXTSingle-line text input (default)-
LONG_TEXTMulti-line expandable editor-
NUMBERNumeric inputmin, max, step
DATEDate picker-
SELECTSingle dropdown selectionoptions: [{value, label}]
MULTI_SELECTMultiple selection with tagsoptions: [{value, label}]
CHECKBOXBoolean toggle-
URLLink with preview-
FILEFile attachments-

Keyboard Shortcuts

Arrow Keys Navigate cells
Tab Move to next cell
Enter Start/confirm edit
Esc Cancel editing
Ctrl+Z Undo
Ctrl+Shift+Z Redo
Ctrl+C Copy cells
Ctrl+V Paste
Ctrl+F Focus search

Loading States

Spinner

mount('#spinner', Spinner, {
  size: 'md', // sm, md, lg, xl
  color: 'primary'
})

Skeleton

mount('#skeleton', Skeleton, {
  width: '100%',
  height: '200px',
  rounded: true
})

Progress

mount('#progress', Progress, {
  value: 65,
  max: 100,
  showLabel: true,
  striped: true
})

Form Validation

useForm Hook

Built-in form validation with validators.

import { Form, FormField, validators, useForm } from './components/ui/form.js'

const form = useForm({
  fields: {
    email: {
      value: '',
      validators: [validators.required, validators.email]
    },
    password: {
      value: '',
      validators: [validators.required, validators.minLength(8)]
    }
  }
})

Built-in Validators

validators.required
validators.email
validators.minLength(n)
validators.maxLength(n)
validators.min(n)
validators.max(n)
validators.pattern(regex)
validators.url
validators.phone