Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cronixui-1.1.3.tar.gz (49.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cronixui-1.1.3-py3-none-any.whl (51.4 kB view details)

Uploaded Python 3

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

Hashes for cronixui-1.1.3.tar.gz
Algorithm Hash digest
SHA256 cedffd1437b324fa2bae6a3a6aec49a7dd29f835975577213a0458c95ecdd54c
MD5 b11668ef833d5d000297bdec14398913
BLAKE2b-256 f5b45ce11029b19b4403e1506263f3c38318860936b5038e618a3ff78e3573d2

See more details on using hashes here.

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

Hashes for cronixui-1.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 1d621b24f5fe3421ed1e6a0be3201d83a19a191dd2cc5baffcb6ba37b36f2033
MD5 4dd0fd8e9780e2a3d3aac4ccca248695
BLAKE2b-256 5805ed2bf0d178c189a5e8fab621f4130d6ad96497fe6fe5b4083229dad36b64

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page