CronixUI - A dark-themed UI toolkit with crimson accents and Outfit typography
Project description
CronixUI
A multi-platform, multi-language UI toolkit with a dark theme, crimson accents, and Outfit typography.
If you find this useful, consider starring this repo!
Installation
JavaScript/TypeScript
npm install cronixui
React, Vue, Svelte, Solid
npm install @cronixui/react
npm install @cronixui/vue
npm install @cronixui/svelte
npm install @cronixui/solid
Python
pip install cronixui
Go
go get github.com/CazyUndee/CronixUI/packages/go/cronixui
Rust
[dependencies]
cronixui = "1.1.2"
Flutter
dependencies:
cronixui:
git:
url: https://github.com/CazyUndee/CronixUI.git
path: packages/flutter
CDN
<link rel="stylesheet" href="https://unpkg.com/cronixui@1.1.2/packages/web/dist/cronixui.css">
<script src="https://unpkg.com/cronixui@1.1.2/packages/web/dist/cronixui.js"></script>
Quick Start (Web)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My App</title>
<link rel="stylesheet" href="https://unpkg.com/cronixui@1.1.2/packages/web/dist/cronixui.css">
</head>
<body>
<div class="cn-container">
<h1 class="cn-h1">Hello, CronixUI!</h1>
<button class="cn-btn cn-btn-primary">Get Started</button>
</div>
<script src="https://unpkg.com/cronixui@1.1.2/packages/web/dist/cronixui.js"></script>
</body>
</html>
Design Tokens
CronixUI uses CSS custom properties for consistent theming:
| Token | Value | Description |
|---|---|---|
--cn-bg |
#0a0a0a |
Background |
--cn-surface |
#111111 |
Surface |
--cn-accent |
#6b2323 |
Crimson accent |
--cn-text |
#f0ede8 |
Primary text |
--cn-border |
rgba(255,255,255,0.08) |
Border color |
Components
Typography
<h1 class="cn-h1">Heading 1</h1>
<h2 class="cn-h2">Heading 2</h2>
<h3 class="cn-h3">Heading 3</h3>
<p class="cn-text-muted">Muted text</p>
<p class="cn-text-dim">Dim text</p>
<code class="cn-text-mono">code</code>
Buttons
<button class="cn-btn cn-btn-primary">Primary</button>
<button class="cn-btn">Default</button>
<button class="cn-btn cn-btn-ghost">Ghost</button>
<button class="cn-btn cn-btn-outline">Outline</button>
<button class="cn-btn cn-btn-success">Success</button>
<button class="cn-btn cn-btn-danger">Danger</button>
<!-- Sizes -->
<button class="cn-btn cn-btn-sm">Small</button>
<button class="cn-btn cn-btn-lg">Large</button>
<!-- Button Group -->
<div class="cn-btn-group">
<button class="cn-btn">Left</button>
<button class="cn-btn">Center</button>
<button class="cn-btn">Right</button>
</div>
Inputs
<!-- Basic input -->
<input class="cn-input" placeholder="Enter text...">
<!-- With label -->
<div class="cn-form-group">
<label class="cn-form-label">Email</label>
<input class="cn-input" type="email" placeholder="you@example.com">
</div>
<!-- With error -->
<div class="cn-form-group">
<label class="cn-form-label">Password</label>
<input class="cn-input cn-input-error" type="password">
<span class="cn-form-error">Password is required</span>
</div>
<!-- Sizes -->
<input class="cn-input cn-input-sm" placeholder="Small">
<input class="cn-input cn-input-lg" placeholder="Large">
<!-- Select -->
<div class="cn-select-wrapper">
<select class="cn-select">
<option>Option 1</option>
<option>Option 2</option>
</select>
</div>
<!-- Textarea -->
<textarea class="cn-input cn-textarea" placeholder="Long text..."></textarea>
Checkbox & Radio
<label class="cn-checkbox">
<input type="checkbox" checked>
<span class="cn-checkbox-box"></span>
<span class="cn-checkbox-label">Checked</span>
</label>
<label class="cn-radio">
<input type="radio" name="group" checked>
<span class="cn-radio-box"></span>
<span class="cn-radio-label">Option A</span>
</label>
Toggle
<div class="cn-toggle on"></div>
<span class="cn-toggle-label">Enabled</span>
// Toggle state
document.querySelector('.cn-toggle').classList.toggle('on');
Slider
<input type="range" class="cn-slider" min="0" max="100" value="50">
Badges
<span class="cn-badge cn-badge-default">Default</span>
<span class="cn-badge cn-badge-accent">Accent</span>
<span class="cn-badge cn-badge-success">Success</span>
<span class="cn-badge cn-badge-warning">Warning</span>
<span class="cn-badge cn-badge-error">Error</span>
<span class="cn-badge cn-badge-info">Info</span>
<!-- Solid variants -->
<span class="cn-badge cn-badge-solid cn-badge-accent">Solid</span>
Tags
<span class="cn-tag">
Tag Name
<span class="cn-tag-remove">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="18" y1="6" x2="6" y2="18"/>
<line x1="6" y1="6" x2="18" y2="18"/>
</svg>
</span>
</span>
Stats
<div class="cn-stat">
<div class="cn-stat-value">2,847</div>
<div class="cn-stat-label">Total runs</div>
<div class="cn-stat-delta cn-stat-delta-up">+12%</div>
</div>
Progress
<div class="cn-progress-label"><span>Loading</span><span>68%</span></div>
<div class="cn-progress">
<div class="cn-progress-bar" style="width: 68%;"></div>
</div>
<!-- Variants -->
<div class="cn-progress cn-progress-success">...</div>
<div class="cn-progress cn-progress-warning">...</div>
<div class="cn-progress cn-progress-error">...</div>
<div class="cn-progress cn-progress-lg">...</div>
Cards
<div class="cn-card">
<h3 class="cn-card-title">Card Title</h3>
<p class="cn-card-body">Card content.</p>
</div>
<!-- Clickable -->
<div class="cn-card cn-card-clickable">...</div>
<!-- With header/footer -->
<div class="cn-card">
<div class="cn-card-header">
<span class="cn-card-title">Title</span>
<button class="cn-btn cn-btn-sm">Action</button>
</div>
<p class="cn-card-body">Content</p>
<div class="cn-card-footer">Footer</div>
</div>
Navigation
<div class="cn-nav">
<button class="cn-nav-item cn-nav-active">Home</button>
<button class="cn-nav-item">Projects</button>
<button class="cn-nav-item">Settings</button>
</div>
CronixUI.Nav.init();
Tabs
<div class="cn-tabs">
<div class="cn-tabs-list">
<button class="cn-tab cn-tab-active">Tab 1</button>
<button class="cn-tab">Tab 2</button>
<button class="cn-tab">Tab 3</button>
</div>
</div>
<div class="cn-tab-content">
<div class="cn-tab-panel cn-tab-panel-active">Content 1</div>
<div class="cn-tab-panel">Content 2</div>
<div class="cn-tab-panel">Content 3</div>
</div>
Breadcrumb
<div class="cn-breadcrumb">
<a href="#" class="cn-breadcrumb-item">Home</a>
<span class="cn-breadcrumb-separator">/</span>
<a href="#" class="cn-breadcrumb-item">Projects</a>
<span class="cn-breadcrumb-separator">/</span>
<span class="cn-breadcrumb-current">Current</span>
</div>
Alerts
<div class="cn-alert cn-alert-info">
<div class="cn-alert-icon">...</div>
<div class="cn-alert-content">
<div class="cn-alert-title">Title</div>
<div class="cn-alert-message">Message</div>
</div>
<button class="cn-alert-close">×</button>
</div>
Variants: cn-alert-info, cn-alert-success, cn-alert-warning, cn-alert-error
Toast
// Show toast
CronixUI.Toast.success('Operation completed!');
CronixUI.Toast.error('Something went wrong');
CronixUI.Toast.warning('Please review');
CronixUI.Toast.info('New updates');
// With title
CronixUI.Toast.show({
title: 'Success',
message: 'Your changes have been saved.',
type: 'success',
duration: 5000
});
Modal
<div class="cn-modal-backdrop" id="myModal">
<div class="cn-modal">
<div class="cn-modal-header">
<h3 class="cn-modal-title">Modal Title</h3>
<button class="cn-modal-close">×</button>
</div>
<div class="cn-modal-body">Content</div>
<div class="cn-modal-footer">
<button class="cn-btn cn-btn-ghost">Cancel</button>
<button class="cn-btn cn-btn-primary">Confirm</button>
</div>
</div>
</div>
const modal = document.getElementById('myModal');
modal._cnModal.open();
modal._cnModal.close();
Dropdown
<div class="cn-dropdown">
<button class="cn-btn cn-dropdown-trigger">
Menu <svg>...</svg>
</button>
<div class="cn-dropdown-menu">
<div class="cn-dropdown-item">Profile</div>
<div class="cn-dropdown-item">Settings</div>
<div class="cn-dropdown-divider"></div>
<div class="cn-dropdown-item">Logout</div>
</div>
</div>
Tooltip
<div class="cn-tooltip">
<button class="cn-btn">Hover me</button>
<div class="cn-tooltip-content">Tooltip text</div>
</div>
Table
<div class="cn-table-wrapper cn-table-sortable">
<table class="cn-table">
<thead>
<tr>
<th data-sort="name">Name</th>
<th data-sort="value">Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>Item 1</td>
<td>100</td>
</tr>
</tbody>
</table>
</div>
List
<div class="cn-list">
<div class="cn-list-item cn-list-item-clickable">
<div class="cn-list-item-content">
<div class="cn-list-item-title">Title</div>
<div class="cn-list-item-subtitle">Subtitle</div>
</div>
</div>
</div>
Accordion
<div class="cn-accordion">
<div class="cn-accordion-item cn-accordion-open">
<div class="cn-accordion-header">
<span class="cn-accordion-title">Section 1</span>
<svg class="cn-accordion-icon">...</svg>
</div>
<div class="cn-accordion-content">Content</div>
</div>
</div>
Avatar
<div class="cn-avatar">JD</div>
<div class="cn-avatar cn-avatar-sm">AB</div>
<div class="cn-avatar cn-avatar-lg">XY</div>
<div class="cn-avatar cn-avatar-xl">ZZ</div>
<!-- Group -->
<div class="cn-avatar-group">
<div class="cn-avatar">A</div>
<div class="cn-avatar">B</div>
<div class="cn-avatar">+5</div>
</div>
Pagination
<div class="cn-pagination" id="pagination"></div>
new CronixUI.Pagination(document.getElementById('pagination'), {
total: 10,
current: 1,
onChange: (page) => console.log('Page:', page)
});
File Input
<div class="cn-file-input">
<input type="file">
<div class="cn-file-input-label">
<svg class="cn-file-input-icon">...</svg>
<div class="cn-file-input-text">
<span>Click to upload</span> or drag and drop
</div>
</div>
</div>
Search
<div class="cn-search">
<svg class="cn-search-icon">...</svg>
<input class="cn-input cn-search-input" placeholder="Search...">
<div class="cn-search-results"></div>
</div>
const search = document.querySelector('.cn-search');
search._cnSearch.setItems([
{ title: 'Result 1', subtitle: 'Description', action: () => {} },
{ title: 'Result 2', action: () => {} }
]);
Command Palette
<div class="cn-command-palette" id="cmd">
<div class="cn-command-palette-inner">
<input class="cn-command-palette-input" placeholder="Type a command...">
<div class="cn-command-palette-results"></div>
</div>
</div>
const cmd = document.getElementById('cmd');
new CronixUI.CommandPalette(cmd);
cmd._cnCommandPalette.setItems([
{ title: 'New File', kbd: 'Ctrl+N', action: () => {} },
{ title: 'Save', kbd: 'Ctrl+S', action: () => {} }
]);
// Open
cmd._cnCommandPalette.open();
Loading States
<!-- Spinner -->
<div class="cn-spinner"></div>
<div class="cn-spinner cn-spinner-sm"></div>
<div class="cn-spinner cn-spinner-lg"></div>
<!-- Skeleton -->
<div class="cn-skeleton cn-skeleton-title"></div>
<div class="cn-skeleton cn-skeleton-text"></div>
<div class="cn-skeleton cn-skeleton-avatar"></div>
Layout
<!-- Container -->
<div class="cn-container">...</div>
<div class="cn-container-sm">...</div>
<div class="cn-container-lg">...</div>
<!-- Flex -->
<div class="cn-flex cn-items-center cn-gap-4">...</div>
<!-- Grid -->
<div class="cn-grid cn-grid-3">...</div>
<!-- Stack -->
<div class="cn-stack">...</div>
<div class="cn-hstack">...</div>
<!-- Sections -->
<div class="cn-section">...</div>
<div class="cn-divider"></div>
JavaScript API
Global Object
// Initialize all components
CronixUI.init();
// Utilities
CronixUI.$(selector);
CronixUI.$$(selector);
CronixUI.createEl(tag, className, attrs);
Classes
| Class | Methods |
|---|---|
CronixUI.Toggle |
toggle(), isOn(), setOn(bool) |
CronixUI.Modal |
open(), close() |
CronixUI.Dropdown |
open(), close(), toggle() |
CronixUI.Toast |
show(opts), success(), error(), warning(), info() |
CronixUI.Tabs |
setActive(index) |
CronixUI.Accordion |
toggle(item), openAll(), closeAll() |
CronixUI.Pagination |
goTo(page), render() |
CronixUI.CommandPalette |
open(), close(), setItems([]) |
CronixUI.Search |
setItems([]), filter(), open(), close() |
Browser Support
- Chrome 80+
- Firefox 75+
- Safari 13+
- Edge 80+
License
GPL 3.0, see LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cronixui-1.1.3.tar.gz.
File metadata
- Download URL: cronixui-1.1.3.tar.gz
- Upload date:
- Size: 49.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cedffd1437b324fa2bae6a3a6aec49a7dd29f835975577213a0458c95ecdd54c
|
|
| MD5 |
b11668ef833d5d000297bdec14398913
|
|
| BLAKE2b-256 |
f5b45ce11029b19b4403e1506263f3c38318860936b5038e618a3ff78e3573d2
|
File details
Details for the file cronixui-1.1.3-py3-none-any.whl.
File metadata
- Download URL: cronixui-1.1.3-py3-none-any.whl
- Upload date:
- Size: 51.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1d621b24f5fe3421ed1e6a0be3201d83a19a191dd2cc5baffcb6ba37b36f2033
|
|
| MD5 |
4dd0fd8e9780e2a3d3aac4ccca248695
|
|
| BLAKE2b-256 |
5805ed2bf0d178c189a5e8fab621f4130d6ad96497fe6fe5b4083229dad36b64
|