Choose Your Styling Approach: shadcn/ui vs. Noundry Default
Noundry.ts UI components support two styling approaches:
.input, .btn, .cardBoth use Tailwind CSS under the hood, so you can mix and match as needed!
Example:
class="btn btn-primary"
Example:
class="px-4 py-2 bg-blue-600 text-white rounded-lg"
See how to use each styling approach with Noundry.ts TypeScript components
import { Input } from './ui-components/src';
const emailInput = Input.create({
name: 'email',
type: 'email',
placeholder: 'name@example.com',
inputClass: 'input', // BasecoatUI class
icon: 'envelope',
iconPosition: 'left'
});
document.getElementById('form')
.appendChild(emailInput);
import { Input } from './ui-components/src';
const emailInput = Input.create({
name: 'email',
type: 'email',
placeholder: 'name@example.com',
// No inputClass - uses Tailwind defaults
icon: 'envelope',
iconPosition: 'left'
});
document.getElementById('form')
.appendChild(emailInput);
Key Difference:
With shadcn/ui, add inputClass: 'input'.
Without it, Noundry uses beautiful Tailwind defaults automatically.
import { DataTable } from './ui-components/src';
const table = DataTable.create({
title: 'Users',
columns: [
{ key: 'id', label: 'ID' },
{ key: 'name', label: 'Name' }
],
class: 'table-container',
tableClass: 'table',
// Uses BasecoatUI table styling
apiEndpoint: '/api/users'
});
document.getElementById('app')
.appendChild(table);
import { DataTable } from './ui-components/src';
const table = DataTable.create({
title: 'Users',
columns: [
{ key: 'id', label: 'ID' },
{ key: 'name', label: 'Name' }
],
// No class overrides - uses Tailwind defaults
apiEndpoint: '/api/users',
pagination: true,
searchable: true
});
document.getElementById('app')
.appendChild(table);
Available Class Overrides:
tableClass - Override the table elementheaderClass - Override header cellscellClass - Override body cellspaginationClass - Override pagination containerimport { MultiSelect } from './ui-components/src';
const userSelect = MultiSelect.create({
name: 'users[]',
placeholder: 'Select users...',
buttonClass: 'select-trigger',
// BasecoatUI select styling
apiEndpoint: '/api/users',
onChange: (selected) => {
console.log('Selected:', selected);
}
});
document.getElementById('form')
.appendChild(userSelect);
import { MultiSelect } from './ui-components/src';
const userSelect = MultiSelect.create({
name: 'users[]',
placeholder: 'Select users...',
// Uses Tailwind defaults automatically
apiEndpoint: '/api/users',
onChange: (selected) => {
console.log('Selected:', selected);
}
});
document.getElementById('form')
.appendChild(userSelect);
Available Class Overrides:
buttonClass - Override the trigger buttondropdownClass - Override the dropdown containeroptionClass - Override individual optionsimport { DatePicker } from './ui-components/src';
const datePicker = DatePicker.create({
name: 'birthdate',
placeholder: 'Select date',
format: 'YYYY-MM-DD',
inputClass: 'input',
// BasecoatUI input styling
onChange: (value) => {
console.log('Selected:', value);
}
});
document.getElementById('form')
.appendChild(datePicker);
import { DatePicker } from './ui-components/src';
const datePicker = DatePicker.create({
name: 'birthdate',
placeholder: 'Select date',
format: 'YYYY-MM-DD',
// Uses Tailwind defaults automatically
onChange: (value) => {
console.log('Selected:', value);
}
});
document.getElementById('form')
.appendChild(datePicker);
Available Class Overrides:
inputClass - Override the input fieldcalendarClass - Override the calendar dropdownimport { FullScreenModal } from './ui-components/src';
const modal = FullScreenModal.create({
title: 'Preview',
overlayClass: 'dialog-overlay',
contentClass: 'dialog-content',
// BasecoatUI dialog styling
onClose: () => {
console.log('Modal closed');
}
});
modal.setContent('<p>Content here</p>');
modal.open();
import { FullScreenModal } from './ui-components/src';
const modal = FullScreenModal.create({
title: 'Preview',
// Uses Tailwind defaults automatically
onClose: () => {
console.log('Modal closed');
}
});
modal.setContent('<p>Content here</p>');
modal.open();
Available Class Overrides:
overlayClass - Override the backdrop/overlaycontentClass - Override the modal content wrapperheaderClass - Override the header sectionAll available class override props for each component
| Component | Class Override Props | BasecoatUI Equivalent |
|---|---|---|
| Input |
inputClass
iconClass
|
input
|
| DataTable |
tableClass
headerClass
cellClass
paginationClass
|
table
table-container
|
| MultiSelect |
buttonClass
dropdownClass
optionClass
|
select-trigger
|
| SearchSelect |
buttonClass
dropdownClass
optionClass
|
select-trigger
|
| FullScreenModal |
overlayClass
contentClass
headerClass
|
dialog-overlay
dialog-content
|
| DatePicker |
inputClass
calendarClass
|
input
|
| DateRangePicker |
inputClass
calendarClass
|
input
|
| SlideOver |
overlayClass
panelClass
|
Custom |
| NavigationMenu |
menuClass
itemClass
|
Custom |
| Pacer |
barClass
|
Custom |
Yes! Mix and match freely.
Both approaches use Tailwind CSS, so you can use BasecoatUI classes for some components and Noundry defaults for others in the same project.
// Mix BasecoatUI and Noundry styling in the same form
const form = document.getElementById('myForm');
// Use BasecoatUI for this input
const emailInput = Input.create({
name: 'email',
inputClass: 'input' // BasecoatUI
});
// Use Noundry default for this input
const passwordInput = Input.create({
name: 'password'
// No inputClass - Noundry defaults
});
// Use BasecoatUI for the table
const table = DataTable.create({
columns: [...],
class: 'table-container',
tableClass: 'table' // BasecoatUI
});
form.appendChild(emailInput);
form.appendChild(passwordInput);
form.appendChild(table);
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/basecoat-ui@1.7.0/dist/basecoat.css">
inputClass: 'input'
<script src="https://cdn.tailwindcss.com"></script>
Input.create({ name: 'email' })
Check out the live demo pages to see each styling approach:
✨ shadcn/ui Style: Use component classes (inputClass: 'input') for a polished, professional look
⚡ Noundry Default: Omit class overrides to use beautiful Tailwind defaults automatically
🎨 Mix Both: Use different approaches for different components in the same project
🚀 No Breaking Changes: All class overrides are optional - existing code works unchanged