text-ui-kit
v1.6.1
Published
CLI to copy editable UI component templates into a project (init + add commands).
Readme
text-ui-kit
A lightweight, customizable React component library with editable templates. Copy components directly into your project and customize them to fit your needs.
Features
- 🎨 Fully Customizable - Components are copied to your project, not imported from node_modules
- 📦 Zero Lock-in - Own your components completely
- 🚀 Production Ready - Built with TypeScript and modern React patterns
- 💅 Tailwind CSS - Styled with utility-first CSS
- 🎯 Type Safe - Full TypeScript support
Installation
npm install text-ui-kitQuick Start
1. Initialize the project
npx text-ui-kit@latest initThis creates the necessary folder structure and utility files in your project.
2. Add components
npx text-ui-kit@latest add button
npx text-ui-kit@latest add table
npx text-ui-kit@latest add searchable-selectComponents will be copied to components/ui/<component-name> in your project.
Available Components
Button
A versatile button component with multiple variants, sizes, and loading states.
Features:
- Multiple variants: primary, secondary, outline, ghost, danger
- Three sizes: sm, md, lg
- Loading state with spinner
- Left and right icon support
- Fully accessible
Usage:
import Button from './components/ui/button/Button';
import { Download } from 'lucide-react';
function App() {
return (
<div>
<Button variant="primary" size="md">
Click me
</Button>
<Button variant="outline" loading>
Loading...
</Button>
<Button variant="secondary" rightIcon={<Download size={16} />}>
Download
</Button>
</div>
);
}Props:
| Prop | Type | Default | Description | |------|------|---------|-------------| | variant | 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger' | 'primary' | Button style variant | | size | 'sm' | 'md' | 'lg' | 'md' | Button size | | loading | boolean | false | Show loading spinner | | leftIcon | React.ReactNode | - | Icon on the left side | | rightIcon | React.ReactNode | - | Icon on the right side | | disabled | boolean | false | Disable button |
DataTable
A powerful data table with server-side pagination, filtering, sorting, and more.
Features:
- Server-side pagination
- Column sorting
- Global search
- Column-specific filters
- Date range filtering
- Row selection
- Column visibility customization
- Export functionality
- Loading states
- Responsive design
Usage:
import DataTable from './components/ui/table/DataTable';
import { useState } from 'react';
function UserTable() {
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
const [search, setSearch] = useState('');
const columns = [
{ key: 'id', label: 'ID', sortable: true },
{ key: 'name', label: 'Name', sortable: true, filterable: true },
{ key: 'email', label: 'Email', filterable: true },
{
key: 'status',
label: 'Status',
render: (value) => (
<span className={value === 'active' ? 'text-green-600' : 'text-gray-600'}>
{value}
</span>
)
},
{ key: 'createdAt', label: 'Created At', sortable: true, filterable: true }
];
const data = [
{ id: 1, name: 'John Doe', email: '[email protected]', status: 'active', createdAt: '2024-01-15' },
{ id: 2, name: 'Jane Smith', email: '[email protected]', status: 'inactive', createdAt: '2024-02-20' }
];
return (
<DataTable
data={data}
columns={columns}
searchable
exportable
selectable
columnFilters
onSearch={(term) => setSearch(term)}
onSort={(field, direction) => console.log('Sort:', field, direction)}
onColumnFilter={(filters) => console.log('Filters:', filters)}
onDateFilterChange={(filters) => console.log('Date filters:', filters)}
pagination={{
currentPage: page,
pageSize: pageSize,
totalItems: 100,
totalPages: 10,
onPageChange: setPage,
onPageSizeChange: setPageSize
}}
onRowClick={(row) => console.log('Row clicked:', row)}
onSelectionChange={(rows) => console.log('Selected:', rows)}
/>
);
}Props:
| Prop | Type | Default | Description | |------|------|---------|-------------| | data | T[] | required | Array of data objects | | columns | DataTableColumn[] | required | Column configuration | | searchable | boolean | false | Enable global search | | exportable | boolean | false | Show export button | | customizable | boolean | true | Allow column visibility customization | | selectable | boolean | false | Enable row selection | | columnFilters | boolean | true | Enable column-specific filters | | loading | boolean | false | Show loading skeleton | | pagination | object | - | Server-side pagination config | | onSearch | function | - | Search callback | | onSort | function | - | Sort callback | | onColumnFilter | function | - | Column filter callback | | onDateFilterChange | function | - | Date filter callback | | onRowClick | function | - | Row click callback | | onSelectionChange | function | - | Selection change callback |
SearchableSelect
A searchable dropdown with single/multi-select support and advanced features.
Features:
- Single and multi-select modes
- Search with minimum character requirement
- Keyboard navigation (Arrow keys, Enter, Escape)
- Maximum/minimum selection limits
- Loading states
- Error handling
- Custom option rendering
- Primitive and object value support
Usage:
import SearchableSelect from './components/ui/searchable-select/SearchableSelect';
import { useState } from 'react';
function UserSelector() {
const [selected, setSelected] = useState([]);
const options = [
{ value: 1, label: 'John Doe' },
{ value: 2, label: 'Jane Smith' },
{ value: 3, label: 'Bob Johnson' }
];
return (
<div>
{/* Single Select */}
<SearchableSelect
options={options}
value={selected}
onChange={setSelected}
placeholder="Select a user..."
label="User"
/>
{/* Multi Select with limits */}
<SearchableSelect
options={options}
value={selected}
onChange={setSelected}
placeholder="Select users..."
label="Users"
isMulti
maxSelections={3}
minSelections={1}
minSearchLength={2}
/>
</div>
);
}Props:
| Prop | Type | Default | Description | |------|------|---------|-------------| | options | SearchableSelectOption[] | required | Array of options | | value | various | - | Selected value(s) | | onChange | function | - | Change callback | | placeholder | string | 'Search and select...' | Placeholder text | | label | string | - | Label text | | isMulti | boolean | false | Enable multi-select | | minSearchLength | number | 3 | Min characters to start search | | maxSelections | number | - | Max selections (multi-select) | | minSelections | number | - | Min selections (multi-select) | | loading | boolean | false | Show loading state | | disabled | boolean | false | Disable component | | required | boolean | false | Mark as required | | error | string | - | Error message |
Local Development & Testing
If you're developing the package locally:
# In the package directory
node ./bin/index.js init
node ./bin/index.js add button
node ./bin/index.js add table
node ./bin/index.js add searchable-selectDependencies
The components require the following peer dependencies:
react>= 18.0.0react-dom>= 18.0.0tailwindcss>= 3.0.0lucide-react(for icons)rsuite(for DateRangePicker in DataTable)
Tailwind Configuration
Make sure your tailwind.config.js includes the component paths:
module.exports = {
content: [
'./src/**/*.{js,jsx,ts,tsx}',
'./components/**/*.{js,jsx,ts,tsx}', // Add this line
],
theme: {
extend: {
colors: {
accent: '#3b82f6', // Customize your accent color
error: '#ef4444',
},
},
},
plugins: [],
}Customization
Since components are copied to your project, you have complete control:
- Modify styles - Edit Tailwind classes directly
- Add features - Extend component functionality
- Change behavior - Adjust logic to your needs
- Update types - Modify TypeScript interfaces
Why text-ui-kit?
Unlike traditional component libraries that you import from node_modules, text-ui-kit takes a different approach:
- Full Control: Components live in your codebase, not hidden in dependencies
- No Version Lock: Update components independently
- Easy Customization: No need to override complex styles or fight with CSS specificity
- Learn by Example: See how components are built and modify them
- Bundle Size: Only include what you use
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Support
For issues and feature requests, please use the GitHub issue tracker.
