Build completed
Production bundle finished without warnings.
Набор базовых элементов интерфейса.
Базовая типографика задаёт размеры заголовков, текстовые состояния и моноширинный код. Используй семантические теги, а служебные классы добавляй для вариаций текста.
Lead text выделяет вводный абзац, описание страницы или важный контекст перед набором действий.
Основной текст интерфейса. Используется для контента.
Вторичный текст, комментарии, подписи.
Приглушённый текст, подсказки.
Caption text для технических подписей, footnote и compact metadata.
Состояния текста: success, warning, danger, info.
Inline code npm run build и keyboard hint esc.
Интерфейс должен оставаться читаемым даже в плотных технических сценариях. GNexus UI Kit
<h1 class="contrast">Dashboard</h1>
<span class="eyebrow">System label</span>
<p class="text-lead">Вводный текст страницы.</p>
<p class="text-primary">Основной текст интерфейса.</p>
<p class="text-muted">Приглушённая подсказка.</p>
<code class="code">npm run build</code>
<span class="kbd">esc</span>
Палитра построена вокруг тёмной базы, светлого primary-текста и ярких статусных цветов. Классы `bg-*` нужны для быстрых цветовых маркеров и демонстрации токенов.
<div class="color-box bg-primary"></div>
<div class="color-box bg-secondary"></div>
<div class="color-box bg-success"></div>
<div class="color-box bg-warning"></div>
<div class="color-box bg-error"></div>
Кнопки собираются из базового класса `.btn`, цветового модификатора и опционального размера. Для иконок добавляй `.with-icon`, а состояние загрузки помечай `.loading-state`.
<button class="btn btn-primary">Primary</button>
<button class="btn btn-secondary with-icon">
<i class="ph ph-code"></i>
Secondary
</button>
<button class="btn btn-warning btn-small">Small</button>
<button class="btn btn-success with-icon loading-state" disabled>
<i class="ph-bold ph-spinner"></i>
Loading
</button>
Формы используют `.form-group`, `.label` и `.input`. Ошибки задаются на label через `.error`, а пояснение выводится соседним `.input-info`.
<div class="form-group">
<label class="label error">
Project name
<i class="ph ph-user"></i>
<input class="input" type="text" placeholder="Launch Plan">
</label>
<div class="input-info">
<i class="ph ph-warning-circle"></i>
Field cannot be empty
</div>
</div>
<fieldset class="fieldset">
<legend class="legend">Fieldset</legend>
<label class="label success">
Validated
<input class="input" type="text" value="Release Plan">
</label>
</fieldset>
<label class="file-upload">
Upload file
<input type="file">
</label>
<fieldset class="fieldset">
<legend class="legend">Date & Time</legend>
<div class="form-grid">
<label class="label">
Date
<i class="ph ph-calendar-blank"></i>
<input class="input input-date" type="date" value="2026-04-23" data-date-picker>
</label>
<label class="label">
Time
<i class="ph ph-clock"></i>
<input class="input input-time" type="time" value="14:30" data-date-picker>
</label>
<label class="label">
Date & time
<i class="ph ph-calendar-dots"></i>
<input class="input input-datetime" type="datetime-local" value="2026-04-23T14:30" data-date-picker>
</label>
</div>
</fieldset>
<div class="file-upload-panel">
<form class="file-upload-form" enctype="multipart/form-data">
<div class="file-upload-header">
<div class="file-upload-heading">
<h3 class="file-upload-title">Upload files</h3>
<p class="file-upload-description">Attach documents, archives or images.</p>
</div>
<span class="badge badge-info">Max 12 MB</span>
</div>
<label class="file-upload-dropzone">
<span class="file-upload-icon" aria-hidden="true">
<i class="ph ph-cloud-arrow-up"></i>
</span>
<span class="file-upload-body">
<span class="file-upload-primary">Choose files</span>
<span class="file-upload-secondary">Images get thumbnails, other files show their type</span>
</span>
<input type="file" name="files" multiple data-file-upload-input>
</label>
<div class="file-upload-preview" data-file-upload-preview hidden></div>
<div class="file-upload-actions">
<button class="btn btn-secondary btn-small" type="reset">Reset</button>
<button class="btn btn-accent btn-small" type="submit">Upload</button>
</div>
</form>
</div>
Utilities дают предсказуемую систему отступов, размеров, раскладки и текстовых правок без создания новых компонентов. Spacing scale используется и в SCSS-переменных, и в utility-классах.
| Token | Value | Alias | Utility examples |
|---|---|---|---|
$space-0 |
0 | - | m-0 p-0 g-0 |
$space-1 |
5px | $space-xs |
mt-1 px-1 |
$space-2 |
8px | $space-sm |
mb-2 g-2 |
$space-3 |
12px | - | p-3 gy-3 |
$space-4 |
15px | $space-md |
mx-4 gx-4 |
$space-5 |
18px | - | pt-5 pb-5 |
$space-6 |
22px | $space-lg |
my-6 g-6 |
$space-8 |
34px | $space-xl |
mt-8 p-8 |
$space-10 |
48px | $space-xxl |
mb-10 py-10 |
$space-12 |
80px | - | mt-12 pb-12 |
m-*
mt-*
mr-*
mb-*
ml-*
mx-*
my-*
p-*
pt-*
pr-*
pb-*
pl-*
px-*
py-*
g-*
gx-*
gy-*
row
column
f-grid
grid
grid-2
grid-3
items-center
justify-between
justify-end
fs-sm
text-center
text-uppercase
text-nowrap
<div class="grid-2 g-4 items-center">
<div class="p-5">Panel</div>
<div class="px-6 py-3 text-right">Actions</div>
</div>
Editable String превращает обычный контейнер с текстом в inline-редактор. Компонент возвращает DOM-элемент с API `editableString`.
<div class="editable-example">Hello world</div>
const editor = editableString(document.querySelector(".editable-example"));
editor.editableString.onChange(component => {
console.log(component.value);
});
Списки покрывают обычные перечни, навигацию, definition list и строки с действиями. Для интерактивных пунктов используй `.list-nav`, `.list-action`, `.list-label` и `.list-meta`.
<ul class="list list-nav">
<li class="list-item list-item-active">
<button class="list-action" type="button">
<span class="list-label">
<i class="ph ph-lightbulb"></i>
Projects
</span>
<span class="list-meta">12</span>
</button>
</li>
</ul>
Badges используются для коротких статусов, счётчиков и меток состояния. Цветовой модификатор выбирается по смыслу: success, warning, error, info и так далее.
<span class="badge badge-success">Online</span>
<span class="badge badge-warning">Degraded</span>
<span class="badge badge-error">Offline</span>
<span class="badge badge-info">Info</span>
Alerts подходят для заметных системных сообщений внутри контента. Используй `.alert` и один цветовой модификатор.
<div class="alert alert-primary">Primary message</div>
<div class="alert alert-success">Operation completed</div>
<div class="alert alert-warning">Check settings</div>
<div class="alert alert-error">Action failed</div>
Таблицы используют базовый класс `.table`, semantic table markup и дополнительные элементы: `.table-caption`, `.table-head`, `.table-body`, `.table-foot`.
| Project | Status | Owner | Updated | Actions |
|---|---|---|---|---|
| Website Redesign | Online |
@design
|
2 min ago | |
| Billing API | Degraded |
@backend
|
1 hour ago | |
| Archive Import | Offline |
@ops
|
Yesterday | |
| Job | State | Runtime | Run ID | Actions |
|---|---|---|---|---|
| Sync catalog | Done | 18s | run_1048 | |
| Import archive | Running | 2m 14s | run_1047 | |
| Export report | Failed | 4s | run_1046 |
<table class="table">
<caption class="table-caption">Projects list</caption>
<thead class="table-head">
<tr class="table-row">
<th scope="col">Project</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody class="table-body">
<tr class="table-row">
<td>Website Redesign</td>
<td><span class="badge badge-success">Online</span></td>
</tr>
</tbody>
</table>
<table class="table table-compact">
<caption class="table-caption">Recent jobs</caption>
<thead class="table-head">
<tr class="table-row">
<th scope="col">Job</th>
<th scope="col">State</th>
<th scope="col">Run ID</th>
</tr>
</thead>
<tbody class="table-body">
<tr class="table-row">
<td>Sync catalog</td>
<td><span class="badge badge-success">Done</span></td>
<td class="table-cell-mono">run_1048</td>
</tr>
</tbody>
</table>
Toolbar, search field, pagination, empty state и skeleton закрывают типовые состояния таблиц, списков и страниц с данными.
Nothing matched the current filters. Reset the query or create a new item.
<div class="toolbar">
<div class="toolbar-group">
<div>
<h3 class="toolbar-title">Projects</h3>
<span class="toolbar-meta">24 items</span>
</div>
</div>
<div class="toolbar-group">
<div class="input-group input-group-compact search-field">
<span class="input-group-addon"><i class="ph ph-magnifying-glass"></i></span>
<input class="input-group-input" type="search" placeholder="Search">
<button class="input-group-action" type="button" data-input-clear aria-label="Clear search">
<i class="ph ph-x"></i>
</button>
</div>
<button class="btn btn-accent btn-small">Create</button>
</div>
</div>
<div class="input-group">
<span class="input-group-addon">https://</span>
<input class="input-group-input" type="text" placeholder="Domain">
<button class="input-group-action" type="button">Save</button>
</div>
<nav class="pagination" aria-label="Pagination">
<button class="pagination-item" type="button" disabled>Prev</button>
<button class="pagination-item pagination-item-active" type="button" aria-current="page">1</button>
<button class="pagination-item" type="button">2</button>
<span class="pagination-ellipsis">...</span>
<button class="pagination-item" type="button">12</button>
<button class="pagination-item" type="button">Next</button>
</nav>
<div class="empty-state">
<div class="empty-state-icon"><i class="ph ph-package"></i></div>
<h3 class="empty-state-title">No results</h3>
<p class="empty-state-text">Nothing matched the current filters.</p>
<div class="empty-state-actions">
<button class="btn btn-secondary btn-small">Reset</button>
<button class="btn btn-accent btn-small">Create</button>
</div>
</div>
<div class="skeleton-stack" aria-label="Loading preview">
<span class="skeleton skeleton-title"></span>
<span class="skeleton skeleton-line"></span>
<span class="skeleton skeleton-line" style="width: 84%"></span>
<span class="skeleton skeleton-block"></span>
</div>
InputPatterns.init();
// Available on the global namespace too:
GNexusUIKit.InputPatterns.init();
Page Header собирает заголовок экрана, короткое описание, статусные метки и основные действия.
Track active work, review critical states, and open the next action without leaving the page.
<header class="page-header">
<div class="page-header-content">
<span class="page-header-kicker">Workspace</span>
<h1 class="page-header-title">Projects overview</h1>
<p class="page-header-subtitle">
Track active work and open the next action without leaving the page.
</p>
<div class="page-header-meta">
<span class="badge badge-success">Healthy</span>
<span>Updated 2 min ago</span>
</div>
</div>
<div class="page-header-actions">
<button class="btn btn-secondary btn-small" type="button">Export</button>
<button class="btn btn-accent btn-small" type="button">Create</button>
</div>
</header>
<header class="page-header page-header-compact page-header-accent">
<div class="page-header-content">
<h2 class="page-header-title">Billing settings</h2>
<div class="page-header-meta">
<span class="badge badge-warning">Pending</span>
<span>3 changes waiting</span>
</div>
</div>
<div class="page-header-actions">
<button class="btn btn-primary btn-small" type="button">Review</button>
<button class="btn btn-danger btn-small" type="button">Discard</button>
</div>
</header>
Description List подходит для read-only деталей сущности: ID, владельцы, статусы, даты и короткие metadata values.
@design
run_1048
<dl class="description-list">
<div class="description-list-row">
<dt class="description-list-term">Project</dt>
<dd class="description-list-value">Website Redesign</dd>
</div>
<div class="description-list-row">
<dt class="description-list-term">Status</dt>
<dd class="description-list-value">
<span class="badge badge-success">Online</span>
<span class="description-list-value-muted">All checks passed</span>
</dd>
</div>
</dl>
<dl class="description-list description-list-compact">
<div class="description-list-row">
<dt class="description-list-term">Run ID</dt>
<dd class="description-list-value"><code class="code">run_1048</code></dd>
</div>
<div class="description-list-row">
<dt class="description-list-term">Runtime</dt>
<dd class="description-list-value">18s</dd>
</div>
</dl>
Progress закрывает загрузку, usage meters и staged progress для операций с понятным состоянием выполнения.
<div class="progress" role="progressbar" aria-label="Build progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="64" style="--progress-value: 64%">
<div class="progress-header">
<span>Build</span>
<span class="progress-value">64%</span>
</div>
<div class="progress-track">
<span class="progress-bar"></span>
</div>
</div>
<div class="usage-meter">
<h3 class="usage-meter-title">
Storage
<span class="usage-meter-value">78%</span>
</h3>
<div class="progress progress-success" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="78" style="--progress-value: 78%">
<div class="progress-track">
<span class="progress-bar"></span>
</div>
</div>
<p class="usage-meter-meta">312 GB used from 400 GB limit.</p>
</div>
<div class="progress-stages" aria-label="Deploy stages">
<span class="progress-stage progress-stage-complete">Queued</span>
<span class="progress-stage progress-stage-complete">Build</span>
<span class="progress-stage progress-stage-current">Deploy</span>
<span class="progress-stage">Verify</span>
</div>
Steps описывает wizard-flow, onboarding и последовательные процессы с текущим, завершенным и недоступным шагом.
Basic profile data is ready.
Billing plan is selected.
Review settings before launch.
Available after confirmation.
Job accepted and waiting for worker slot.
Current task is processing input data.
Final summary appears after completion.
<ol class="steps">
<li class="step step-complete">
<span class="step-marker"><i class="ph ph-check"></i></span>
<h3 class="step-title">Account</h3>
<p class="step-text">Basic profile data is ready.</p>
</li>
<li class="step step-current" aria-current="step">
<span class="step-marker">2</span>
<h3 class="step-title">Confirm</h3>
<p class="step-text">Review settings before launch.</p>
</li>
<li class="step step-disabled">
<span class="step-marker">3</span>
<h3 class="step-title">Launch</h3>
<p class="step-text">Available after confirmation.</p>
</li>
</ol>
<ol class="steps steps-vertical">
<li class="step step-complete">
<span class="step-marker"><i class="ph ph-check"></i></span>
<h3 class="step-title">Queued</h3>
<p class="step-text">Job accepted and waiting for worker slot.</p>
</li>
<li class="step step-current" aria-current="step">
<span class="step-marker">2</span>
<h3 class="step-title">Running</h3>
<p class="step-text">Current task is processing input data.</p>
</li>
</ol>
Chips используются для фильтров, коротких labels, selectable states и removable tokens.
<div class="chip-group">
<span class="chip chip-primary">Primary</span>
<span class="chip chip-secondary">Secondary</span>
<span class="chip chip-success">Success</span>
<span class="chip">
<i class="ph ph-funnel"></i>
Filtered
</span>
</div>
<div class="chip-group" aria-label="Filter chips">
<button class="chip chip-selected" type="button" aria-pressed="true">Active</button>
<button class="chip" type="button" aria-pressed="false">Queued</button>
<button class="chip" type="button" aria-pressed="false">Failed</button>
</div>
<span class="chip">
Frontend
<button class="chip-remove" type="button" aria-label="Remove Frontend">
<i class="ph ph-x"></i>
</button>
</span>
Avatar и Identity показывают пользователя, команду, сервис или объект с initials, icon, image и status marker.
<span class="avatar avatar-secondary is-online">
AK
<span class="avatar-status"></span>
</span>
<span class="avatar avatar-outline">
<i class="ph ph-user"></i>
</span>
<span class="avatar">
<img src="/assets/imgs/gnexus-mark.svg" alt="GNexus mark">
</span>
<div class="identity">
<span class="avatar avatar-secondary is-online">
AK
<span class="avatar-status"></span>
</span>
<span class="identity-content">
<span class="identity-title">Alex Kim</span>
<span class="identity-meta">Product Designer</span>
</span>
</div>
<div class="avatar-stack" aria-label="Assigned users">
<span class="avatar avatar-sm">AK</span>
<span class="avatar avatar-sm avatar-secondary">JS</span>
<span class="avatar avatar-sm avatar-warning">MR</span>
<span class="avatar-stack-count">+4</span>
</div>
Timeline и Activity Log показывают историю событий, audit trail, job updates и системные изменения.
Production bundle finished without warnings.
Design tokens changed and need one visual pass before release.
Component documentation and demo examples were updated.
<ol class="timeline">
<li class="timeline-item timeline-item-success">
<span class="timeline-marker"><i class="ph ph-check-circle"></i></span>
<div class="timeline-content">
<article class="timeline-card">
<div class="timeline-header">
<h3 class="timeline-title">Build completed</h3>
<time class="timeline-time" datetime="2026-04-11T22:24:00">22:24</time>
</div>
<p class="timeline-text">Production bundle finished without warnings.</p>
</article>
</div>
</li>
</ol>
<div class="activity-log">
<div class="activity-log-row">
<time class="activity-log-time" datetime="2026-04-11T22:24:00">22:24</time>
<span class="activity-log-title">Build completed</span>
<span class="badge badge-success">Done</span>
</div>
</div>
Accordion и Disclosure используют native <details> / <summary>, а раскрытие анимируется через Accordion.init().
Check component states, copy examples, keyboard focus, and responsive layout before release.
Keep component copy short and include code examples for the smallest useful markup.
Use native disclosure behavior when the component does not need custom animation or async content.
Use this variant for a single expandable group inside forms or metadata blocks.
<div class="accordion">
<details class="accordion-item" open>
<summary class="accordion-summary">
<span class="accordion-summary-content">
<i class="ph ph-list-checks"></i>
Release checklist
</span>
<i class="ph ph-caret-down accordion-icon"></i>
</summary>
<div class="accordion-panel">
<p>Check component states, copy examples, keyboard focus, and responsive layout.</p>
</div>
</details>
</div>
<details class="disclosure">
<summary class="accordion-summary">
<span class="accordion-summary-content">Compact disclosure</span>
<i class="ph ph-caret-down accordion-icon"></i>
</summary>
<div class="accordion-panel">
<p>Use this variant for a single expandable group.</p>
</div>
</details>
Tabs переключают связанные панели внутри одного контекста. Компонент поддерживает click, keyboard navigation и ARIA state через Tabs.init().
Overview keeps the primary status, totals, and next actions visible without leaving the current screen.
Activity contains the latest events, audit notes, and handoff messages for the same record.
Settings groups secondary options that affect this context but do not need full page navigation.
Use compact tabs in dense panels, settings pages, and narrow metadata blocks.
Disabled tabs can stay visible when a feature is unavailable for the current object.
Billing content is disabled in this example.
Vertical tabs work well when labels are longer or the panel needs a stable left rail.
Use them for account details, admin records, or focused configuration groups.
On smaller screens the tab rail becomes a horizontal scrollable list.
<div class="tabs" data-tabs>
<div class="tabs-list" aria-label="Project sections">
<button class="tab tab-active" type="button" aria-controls="panel-overview">Overview</button>
<button class="tab" type="button" aria-controls="panel-activity">Activity</button>
</div>
<div class="tabs-panels">
<div class="tab-panel tab-panel-active" id="panel-overview">Overview content</div>
<div class="tab-panel" id="panel-activity">Activity content</div>
</div>
</div>
Drawer подходит для контекстных деталей, quick edit и длинных вторичных сценариев без ухода со страницы. По API он близок к Modal, но панель закреплена у края экрана.
Используй Drawer, когда нужно сохранить контекст основного экрана и раскрыть боковую область с формой, метаданными или журналом.
Drawer.create("details-drawer", {
title: "Details",
bodyHtml: `
<p class="text">Context content, forms, logs, metadata.</p>
`,
actions: drawer => {
const close = document.createElement("button");
close.className = "btn btn-primary";
close.textContent = "Close";
close.addEventListener("click", () => drawer.close());
return [close];
}
}).show();
Drawer.create("navigation-drawer", {
title: "Navigation",
position: "left",
bodyText: "Left drawer content"
}).show();
Toasts создаются из JS и добавляются в `body` вызовом `.show()`. Для коротких уведомлений доступны методы `createInfo`, `createSuccess`, `createWarning`, `createDanger`.
Toasts.createSuccess(
"Success",
"Операция выполнена успешно",
{ lifetime: 4000, alone: true }
).show();
Toasts.createDanger("Error", "Произошла ошибка").show();
Card подходит для компактных виджетов и контентных блоков. Цветовые состояния карточек задаются модификаторами `card-success`, `card-warning`, `card-error`, `card-info`.
Карточка для контента, виджетов, статусов.
Primary status card with a short description.
Neutral card for a module, widget, or section.
Warning state for items that need attention.
Error state for failed actions or blocked flows.
Informational card for contextual metadata.
Secondary state for queued or background work.
Monthly usage
84.2%
Use action cards for primary next steps, onboarding prompts, and compact empty state actions.
<div class="card status-card card-success">
<span class="card-title">Status title</span>
<div class="card-content">
<div class="status-icon-container">
<div class="status-icon">
<i class="ph ph-check-circle"></i>
OK
</div>
</div>
<p class="status-name">Primary status card.</p>
</div>
</div>
<div class="card metric-card">
<div class="card-content">
<div class="metric-card-header">
<p class="metric-card-label">Monthly usage</p>
<span class="metric-card-icon"><i class="ph ph-chart-line-up"></i></span>
</div>
<p class="metric-card-value">84.2%</p>
<div class="metric-card-meta">
<span class="metric-card-delta">+12.8%</span>
<span>vs previous period</span>
</div>
</div>
</div>
<div class="card action-card">
<div class="card-content">
<span class="action-card-kicker">Quick action</span>
<h3 class="action-card-title">Create workflow</h3>
<p class="action-card-text">
Use action cards for primary next steps and compact empty state actions.
</p>
<div class="action-card-actions">
<button class="btn btn-secondary btn-small">Preview</button>
<button class="btn btn-accent btn-small">Create</button>
</div>
</div>
</div>
Modal создаётся из JS через `Modals.create`. Для обычного текста используй `bodyText`; HTML-контент передавай явно через `bodyHtml` или DOM-элемент.
Modals.create("demo-modal", {
title: "Demo modal",
bodyText: "Modal content",
actions: modal => {
const close = document.createElement("button");
close.className = "btn btn-primary";
close.textContent = "Close";
close.addEventListener("click", () => modal.close());
return [close];
}
}).show();
Confirm Dialog использует существующий `confirmPopup` поверх Modal. Он нужен для коротких подтверждений перед опасными или необратимыми действиями.
confirmPopup(
"This action cannot be undone.",
() => Toasts.createSuccess("Confirmed", "Action accepted").show(),
() => Toasts.createInfo("Canceled", "Action skipped").show()
);
GNexusUIKit.confirmPopup(
"Apply this change?",
() => console.log("confirmed"),
() => console.log("canceled")
);