Added docs RazorConsole
This commit is contained in:
34
docs/razorconsole/README.md
Normal file
34
docs/razorconsole/README.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# RazorConsole — Документация
|
||||||
|
|
||||||
|
Документация по библиотеке [RazorConsole](https://github.com/RazorConsole/RazorConsole) для проекта LazyBearWorks.
|
||||||
|
|
||||||
|
## Файлы
|
||||||
|
|
||||||
|
| Файл | Содержание |
|
||||||
|
|---|---|
|
||||||
|
| [overview.md](overview.md) | Обзор, установка, минимальный пример, примеры приложений |
|
||||||
|
| [components.md](components.md) | Полный справочник по 25+ встроенным компонентам |
|
||||||
|
| [custom-translators.md](custom-translators.md) | Архитектура VDOM, создание и регистрация кастомных трансляторов |
|
||||||
|
| [contributing.md](contributing.md) | Настройка окружения, стандарты кода, процесс PR |
|
||||||
|
|
||||||
|
## Быстрый старт
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet add package RazorConsole.Core
|
||||||
|
```
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- .csproj -->
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||||
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Program.cs
|
||||||
|
IHostBuilder hostBuilder = Host.CreateDefaultBuilder(args)
|
||||||
|
.UseRazorConsole<MyRootComponent>();
|
||||||
|
await hostBuilder.Build().RunAsync();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Версия
|
||||||
|
|
||||||
|
Документация актуальна для **v0.5.0** (март 2026).
|
||||||
418
docs/razorconsole/components.md
Normal file
418
docs/razorconsole/components.md
Normal file
@@ -0,0 +1,418 @@
|
|||||||
|
# RazorConsole — Встроенные компоненты
|
||||||
|
|
||||||
|
Полный справочник по 25+ компонентам, поставляемым с `RazorConsole.Core`.
|
||||||
|
Каждый компонент транслируется в `IRenderable` Spectre.Console во время рендеринга.
|
||||||
|
|
||||||
|
> Параметры, отмеченные ⚠️, являются обязательными.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Макет (Layout)
|
||||||
|
|
||||||
|
### Align
|
||||||
|
|
||||||
|
Выравнивает дочерний контент горизонтально и вертикально.
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `ChildContent` | `RenderFragment?` | — | Вложенный контент |
|
||||||
|
| `Horizontal` | `HorizontalAlignment` | `Left` | `Left`, `Center`, `Right` |
|
||||||
|
| `Vertical` | `VerticalAlignment` | `Top` | `Top`, `Middle`, `Bottom` |
|
||||||
|
| `Width` | `int?` | `null` | Фиксированная ширина в символах |
|
||||||
|
| `Height` | `int?` | `null` | Фиксированная высота в строках |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Columns
|
||||||
|
|
||||||
|
Располагает дочерние элементы горизонтально (колонками).
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `ChildContent` | `RenderFragment?` | — | Элементы колонок |
|
||||||
|
| `Expand` | `bool` | `false` | Растянуть на всю ширину консоли |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Rows
|
||||||
|
|
||||||
|
Стекует дочерние элементы вертикально.
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `ChildContent` | `RenderFragment?` | — | Элементы строк |
|
||||||
|
| `Expand` | `bool` | `false` | Растянуть на всю высоту |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### FlexBox
|
||||||
|
|
||||||
|
CSS-подобный flexbox-макет с настройкой направления, выравнивания и переноса.
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `ChildContent` | `RenderFragment?` | — | Элементы контейнера |
|
||||||
|
| `Direction` | `FlexDirection` | `Row` | `Row` (горизонталь) или `Column` (вертикаль) |
|
||||||
|
| `Justify` | `FlexJustify` | `Start` | `Start`, `End`, `Center`, `SpaceBetween`, `SpaceAround`, `SpaceEvenly` |
|
||||||
|
| `Align` | `FlexAlign` | `Start` | `Start`, `End`, `Center`, `Stretch` |
|
||||||
|
| `Wrap` | `FlexWrap` | `NoWrap` | `NoWrap`, `Wrap` |
|
||||||
|
| `Gap` | `int` | `0` | Отступ между элементами (символы / строки) |
|
||||||
|
| `Width` | `int?` | `null` | Явное ограничение ширины |
|
||||||
|
| `Height` | `int?` | `null` | Явное ограничение высоты |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Grid
|
||||||
|
|
||||||
|
Многострочный многоколоночный макет с точным управлением ячейками.
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `ChildContent` | `RenderFragment?` | — | Строки и ячейки сетки |
|
||||||
|
| `Columns` | `int` | `2` | Количество колонок |
|
||||||
|
| `Expand` | `bool` | `false` | Растянуть на доступную ширину |
|
||||||
|
| `Width` | `int?` | `null` | Фиксированная ширина |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Padder
|
||||||
|
|
||||||
|
Добавляет внешние отступы вокруг дочернего контента.
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `ChildContent` | `RenderFragment?` | — | Внутренний контент |
|
||||||
|
| `Padding` | `Padding` | `new(0,0,0,0)` | Отступы (left, top, right, bottom) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Scrollable
|
||||||
|
|
||||||
|
Постраничный скроллинг для типизированных коллекций с поддержкой клавиатуры.
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `Items` | `IReadOnlyList<TItem>` | `Array.Empty<TItem>()` | Источник данных |
|
||||||
|
| `PageSize` | `int` | `1` | Элементов на странице |
|
||||||
|
| `ChildContent` | `RenderFragment<ScrollContext<TItem>>` | — | Разметка видимой страницы |
|
||||||
|
| `ScrollOffset` | `int` | `0` | Двусторонний: индекс начала страницы |
|
||||||
|
| `ScrollOffsetChanged` | `EventCallback<int>` | — | Срабатывает при смене offset |
|
||||||
|
| `IsScrollbarEmbedded` | `bool` | `true` | Встроить скроллбар внутрь `Table`/`Panel`/`Border` |
|
||||||
|
|
||||||
|
#### ScrollContext\<TItem\>
|
||||||
|
|
||||||
|
| Член | Тип | Описание |
|
||||||
|
|---|---|---|
|
||||||
|
| `this[int i]` | `TItem` | Видимый элемент по индексу |
|
||||||
|
| `Count` | `int` | Количество видимых элементов |
|
||||||
|
| `KeyDownEventHandler` | `Func<KeyboardEventArgs,Task>` | Привязать через `@onkeydown` |
|
||||||
|
| `CurrentOffset` | `int` | Текущий scroll offset |
|
||||||
|
| `PagesCount` | `int` | Всего страниц |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### ViewHeightScrollable
|
||||||
|
|
||||||
|
Постраничный скроллинг произвольного `RenderFragment` по строкам (без типизированных данных).
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `ChildContent` | `RenderFragment<ScrollContext>` | — | ⚠️ Контент вьюпорта |
|
||||||
|
| `LinesToRender` | `int` | `10` | Высота вьюпорта в строках |
|
||||||
|
| `ScrollOffset` | `int` | `0` | Двусторонний: индекс первой видимой строки |
|
||||||
|
| `ScrollOffsetChanged` | `EventCallback<int>` | — | Срабатывает при скролле |
|
||||||
|
| `Scrollbar` | `ScrollbarSettings?` | `null` | Настройки скроллбара |
|
||||||
|
| `IsScrollbarEmbedded` | `bool` | `true` | Встроить скроллбар внутрь border-компонента |
|
||||||
|
|
||||||
|
**Горячие клавиши:** `↑`/`↓` — одна строка, `PageUp`/`PageDown`/`Space` — страница, `Home`/`End` — границы.
|
||||||
|
|
||||||
|
#### ScrollbarSettings
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `TrackChar` | `char` | `'│'` | Символ дорожки |
|
||||||
|
| `ThumbChar` | `char` | `'█'` | Символ ползунка |
|
||||||
|
| `TrackColor` | `Color` | `Color.Grey` | Цвет дорожки |
|
||||||
|
| `ThumbColor` | `Color` | `Color.White` | Цвет ползунка |
|
||||||
|
| `TrackFocusedColor` | `Color` | `Color.Grey74` | Цвет дорожки при фокусе |
|
||||||
|
| `ThumbFocusedColor` | `Color` | `Color.DeepSkyBlue1` | Цвет ползунка при фокусе |
|
||||||
|
| `MinThumbHeight` | `int` | `1` | Минимальная высота ползунка |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Ввод (Input)
|
||||||
|
|
||||||
|
### TextInput
|
||||||
|
|
||||||
|
Поле ввода текста с placeholder, маскированием и управлением фокусом.
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `Value` | `string?` | `null` | Двустороннее связывание текста |
|
||||||
|
| `ValueChanged` | `EventCallback<string?>` | — | Срабатывает при изменении |
|
||||||
|
| `OnInput` | `EventCallback<string?>` | — | Срабатывает при каждом нажатии |
|
||||||
|
| `Placeholder` | `string?` | `null` | Текст-подсказка |
|
||||||
|
| `MaskInput` | `bool` | `false` | Маскирование символов (пароли) |
|
||||||
|
| `FocusOrder` | `int?` | `null` | Порядок фокуса |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### TextButton
|
||||||
|
|
||||||
|
Кликабельная кнопка с изменением цвета при фокусе.
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `Content` | `string` | `string.Empty` | Текст кнопки |
|
||||||
|
| `BackgroundColor` | `Color` | `Color.Default` | Фон в нормальном состоянии |
|
||||||
|
| `FocusedColor` | `Color` | `Color.DeepSkyBlue1` | Фон при фокусе |
|
||||||
|
| `OnClick` | `EventCallback` | — | Срабатывает при нажатии |
|
||||||
|
| `FocusOrder` | `int?` | `null` | Порядок фокуса |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Select
|
||||||
|
|
||||||
|
Интерактивный выпадающий список с клавиатурной навигацией.
|
||||||
|
|
||||||
|
**Основные параметры:**
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `Options` | `string[]` | `Array.Empty<string>()` | Доступные варианты |
|
||||||
|
| `Value` | `string?` | `null` | Текущий выбор |
|
||||||
|
| `ValueChanged` | `EventCallback<string>` | — | Срабатывает при смене |
|
||||||
|
| `OnSelected` | `EventCallback<string?>` | — | Срабатывает при подтверждении |
|
||||||
|
| `OnClear` | `EventCallback` | — | Срабатывает при очистке |
|
||||||
|
| `Placeholder` | `string` | `"Select an option"` | Текст при отсутствии выбора |
|
||||||
|
| `Expand` | `bool` | `false` | Растянуть горизонтально |
|
||||||
|
| `FocusOrder` | `int?` | `null` | Порядок фокуса |
|
||||||
|
| `BorderStyle` | `BoxBorder` | `Rounded` | Стиль рамки |
|
||||||
|
|
||||||
|
**Клавиатура:** стрелки, `Space` для переключения, `Enter` для подтверждения, `Escape` для отмены, буквы для быстрого перехода.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Отображение (Display)
|
||||||
|
|
||||||
|
### Markup
|
||||||
|
|
||||||
|
Стилизованный текст с тегами разметки Spectre.
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `Content` ⚠️ | `string` | — | Текст (автоматически экранируется) |
|
||||||
|
| `Foreground` | `Color` | `Style.Plain.Foreground` | Цвет текста |
|
||||||
|
| `Background` | `Color` | `Style.Plain.Background` | Цвет фона |
|
||||||
|
| `Decoration` | `Decoration` | `None` | `Bold`, `Italic`, `Underline` и др. |
|
||||||
|
| `link` | `string?` | `null` | Гиперссылка |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Markdown
|
||||||
|
|
||||||
|
Рендеринг markdown-строки в консоль.
|
||||||
|
|
||||||
|
| Параметр | Тип | Описание |
|
||||||
|
|---|---|---|
|
||||||
|
| `Content` ⚠️ | `string` | Markdown-текст для отображения |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Panel
|
||||||
|
|
||||||
|
Обёртка Spectre.Console Panel с заголовком и рамкой.
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `ChildContent` | `RenderFragment?` | — | Содержимое панели |
|
||||||
|
| `Title` | `string?` | `null` | Заголовок панели |
|
||||||
|
| `TitleColor` | `Color?` | `null` | Цвет заголовка |
|
||||||
|
| `BorderColor` | `Color?` | `null` | Цвет рамки |
|
||||||
|
| `Border` | `BoxBorder?` | `null` | Стиль рамки |
|
||||||
|
| `Height` | `int?` | `null` | Фиксированная высота |
|
||||||
|
| `Width` | `int?` | `null` | Фиксированная ширина |
|
||||||
|
| `Padding` | `Padding?` | `null` | Внутренние отступы |
|
||||||
|
| `Expand` | `bool` | `false` | Растянуть на ширину |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Border
|
||||||
|
|
||||||
|
Рамка вокруг дочернего контента (без заголовка).
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `ChildContent` | `RenderFragment?` | — | Контент внутри рамки |
|
||||||
|
| `BorderColor` | `Color?` | `null` | Цвет рамки |
|
||||||
|
| `BoxBorder` | `BoxBorder` | `Rounded` | Стиль рамки |
|
||||||
|
| `Padding` | `Padding` | `new(0,0,0,0)` | Внутренние отступы |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Table
|
||||||
|
|
||||||
|
HTML-подобная таблица, транслируемая в Spectre.Console `Table`.
|
||||||
|
|
||||||
|
> Ключевая идея: используйте стандартные `<table>`, `<thead>`, `<tbody>`, `<tfoot>`, `<tr>`, `<th>`, `<td>`.
|
||||||
|
|
||||||
|
| Атрибут | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `class="table"` ⚠️ | — | — | Обязательный хук для транслятора |
|
||||||
|
| `data-expand` | `bool` | `false` | Растянуть на ширину консоли |
|
||||||
|
| `data-width` | `int?` | `null` | Фиксированная ширина |
|
||||||
|
| `data-title` | `string?` | `null` | Подпись таблицы |
|
||||||
|
| `data-border` | `TableBorderStyle` | `None` | Стиль рамки |
|
||||||
|
| `data-show-headers` | `bool` | `true` | Показывать заголовки |
|
||||||
|
|
||||||
|
Выравнивание колонок: атрибут `data-align="left|center|right"` на `<th>`.
|
||||||
|
|
||||||
|
```razor
|
||||||
|
<table class="table" data-border="Square" data-expand="true" data-title="Build status">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th data-align="left">Stage</th>
|
||||||
|
<th data-align="right">Result</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Compile</td>
|
||||||
|
<td><Markup Content="[green]✔[/]" /></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Figlet
|
||||||
|
|
||||||
|
Большой ASCII-арт текст с использованием FIGlet-шрифтов.
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `Content` | `string` | `string.Empty` | Текст для рендеринга |
|
||||||
|
| `Justify` | `Justify` | `Center` | Выравнивание |
|
||||||
|
| `Color` | `Color` | `Color.Default` | Цвет глифов |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### BarChart
|
||||||
|
|
||||||
|
Горизонтальная барная диаграмма.
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `BarChartItems` ⚠️ | `List<IBarChartItem>` | — | Данные (`Label`, `Value`, `Color`) |
|
||||||
|
| `Width` | `int?` | `null` | Ширина (по умолчанию — вся консоль) |
|
||||||
|
| `Label` | `string?` | `null` | Заголовок диаграммы |
|
||||||
|
| `MaxValue` | `double?` | `null` | Максимальное значение шкалы |
|
||||||
|
| `ShowValues` | `bool` | `false` | Показывать числа рядом с барами |
|
||||||
|
| `Culture` | `CultureInfo` | текущая | Культура для форматирования чисел |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### BreakdownChart
|
||||||
|
|
||||||
|
Диаграмма разбивки (pie-style).
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `BreakdownChartItems` ⚠️ | `List<IBreakdownChartItem>` | — | Данные (`Label`, `Value`, `Color`) |
|
||||||
|
| `Compact` | `bool` | `false` | Компактный режим |
|
||||||
|
| `Expand` | `bool` | `false` | Растянуть на всю ширину |
|
||||||
|
| `Width` | `int?` | `null` | Ширина |
|
||||||
|
| `ShowTags` | `bool` | `false` | Показывать легенду |
|
||||||
|
| `ShowTagValues` | `bool` | `false` | Показывать абсолютные значения |
|
||||||
|
| `ShowTagValuesPercentage` | `bool` | `false` | Показывать проценты |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### StepChart
|
||||||
|
|
||||||
|
Ступенчатая диаграмма с использованием Unicode box-drawing символов.
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `Series` ⚠️ | `List<ChartSeries>` | — | Набор серий данных |
|
||||||
|
| `Width` | `int` | `60` | Ширина диаграммы |
|
||||||
|
| `Height` | `int` | `20` | Высота диаграммы |
|
||||||
|
| `ShowAxes` | `bool` | `true` | Показывать оси |
|
||||||
|
| `AxesColor` | `Color` | `Color.Grey` | Цвет осей |
|
||||||
|
| `LabelsColor` | `Color` | `Color.Grey` | Цвет подписей |
|
||||||
|
| `Title` | `string?` | `null` | Заголовок |
|
||||||
|
| `TitleColor` | `Color` | `Color.Grey` | Цвет заголовка |
|
||||||
|
|
||||||
|
**ChartSeries:**
|
||||||
|
|
||||||
|
| Член | Тип | Описание |
|
||||||
|
|---|---|---|
|
||||||
|
| `Color` | `Color` | Цвет линии |
|
||||||
|
| `Points` | `List<(double X, double Y)>` | Точки данных |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### SpectreCanvas
|
||||||
|
|
||||||
|
Рендеринг массива пикселей с разными цветами.
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `Pixels` ⚠️ | `(int x, int y, Color color)[]` | — | Массив пикселей |
|
||||||
|
| `CanvasWidth` ⚠️ | `int` | — | Ширина холста |
|
||||||
|
| `CanvasHeight` ⚠️ | `int` | — | Высота холста |
|
||||||
|
| `MaxWidth` | `int?` | `null` | Максимальная ширина |
|
||||||
|
| `PixelWidth` | `int` | `2` | Ширина прямоугольника пикселя |
|
||||||
|
| `Scale` | `bool` | `false` | Масштабировать при рендеринге |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### SyntaxHighlighter
|
||||||
|
|
||||||
|
Подсветка синтаксиса кода с темами ColorCode.
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `Code` | `string` | `string.Empty` | Исходный код |
|
||||||
|
| `Language` | `string?` | `null` | Язык: `"csharp"`, `"json"`, `"sql"` и др. |
|
||||||
|
| `Theme` | `string?` | `null` | Тема оформления |
|
||||||
|
| `ShowLineNumbers` | `bool` | `false` | Показывать номера строк |
|
||||||
|
|
||||||
|
**Встроенные языки:** `text/plaintext/plain`, `csharp/cs`, `razor`, `html`, `json`, `xml`, `sql`, `js/javascript`, `ts/typescript`, `css`, `powershell/ps`, `python`, `md/markdown`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### ModalWindow
|
||||||
|
|
||||||
|
Модальное окно с автоматическим центрированием через z-index.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### ModalWindow
|
||||||
|
|
||||||
|
Модальное окно поверх текущего экрана с автоматическим центрированием.
|
||||||
|
|
||||||
|
> Визуализация построена на z-index, чтобы окно корректно перекрывало другие элементы.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Утилиты
|
||||||
|
|
||||||
|
### Spinner
|
||||||
|
|
||||||
|
Анимированный индикатор прогресса.
|
||||||
|
|
||||||
|
| Параметр | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `SpinnerType` | `Spinner` | `Spinner.Known.Dots` | Тип спиннера |
|
||||||
|
| `SpinnerName` | `string?` | `null` | Имя спиннера (переопределение) |
|
||||||
|
| `Message` | `string?` | `null` | Сопроводительный текст |
|
||||||
|
| `Style` | `string?` | `null` | Markup-стиль Spectre |
|
||||||
|
| `AutoDismiss` | `bool` | `false` | Скрыть по завершении |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Newline
|
||||||
|
|
||||||
|
Вставляет один перенос строки. Параметров нет.
|
||||||
69
docs/razorconsole/contributing.md
Normal file
69
docs/razorconsole/contributing.md
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# RazorConsole — Контрибьюция
|
||||||
|
|
||||||
|
## Начало работы
|
||||||
|
|
||||||
|
- **Для крупных PR, рефакторингов, новых фич** — сначала создай Issue для обсуждения
|
||||||
|
- **Discord:** https://discord.gg/DphHAnJxCM — мейнтейнеры активны там
|
||||||
|
|
||||||
|
## Настройка окружения разработки
|
||||||
|
|
||||||
|
### Требования
|
||||||
|
|
||||||
|
- .NET 8.0 или 9.0 SDK
|
||||||
|
- Git LFS (для крупных медиафайлов)
|
||||||
|
|
||||||
|
### Клонирование
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git lfs install
|
||||||
|
git clone https://github.com/RazorConsole/RazorConsole.git
|
||||||
|
cd RazorConsole
|
||||||
|
dotnet build RazorConsole.slnx
|
||||||
|
dotnet test RazorConsole.slnx
|
||||||
|
```
|
||||||
|
|
||||||
|
## Стандарты кода
|
||||||
|
|
||||||
|
- Следовать правилам `.editorconfig` (4 пробела, file-scoped namespaces, System usings первые)
|
||||||
|
- Предпочитать `async/await` с `ConfigureAwait(false)` в библиотечном коде
|
||||||
|
- Public API: nullable-enabled, документировать исключения и edge cases
|
||||||
|
- Spectre.Console renderables — immutable вне rendering loops
|
||||||
|
|
||||||
|
## Перед отправкой PR
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet format RazorConsole.slnx # форматирование
|
||||||
|
dotnet test RazorConsole.slnx # тесты (должны пройти на Linux и Windows)
|
||||||
|
```
|
||||||
|
|
||||||
|
При изменениях в focus/keyboard handling — добавить/обновить тесты в `FocusManagerTests` или `KeyboardEventManagerTests`.
|
||||||
|
|
||||||
|
## Процесс PR
|
||||||
|
|
||||||
|
1. Создать Issue для крупных изменений
|
||||||
|
2. Форкнуть репозиторий, создать ветку от `main`
|
||||||
|
3. Сделать изменения, соблюдая стандарты кода
|
||||||
|
4. Написать/обновить тесты
|
||||||
|
5. Запустить `dotnet format` и `dotnet test`
|
||||||
|
6. Отправить PR с описанием изменений
|
||||||
|
|
||||||
|
## Структура тестов
|
||||||
|
|
||||||
|
- Тесты находятся в `src/RazorConsole.Tests`
|
||||||
|
- CI требует чистого прохождения на Linux и Windows
|
||||||
|
- Покрытие: Codecov (Cobertura format)
|
||||||
|
|
||||||
|
## Документация
|
||||||
|
|
||||||
|
- `README.md` — обновлять при user-facing изменениях
|
||||||
|
- XML doc-комментарии для public API
|
||||||
|
- `examples/` — добавлять примеры для новых фич
|
||||||
|
- `design-doc/` — архитектурные заметки
|
||||||
|
|
||||||
|
## Git LFS
|
||||||
|
|
||||||
|
Отслеживаемые типы файлов: `*.gif`, `*.png`, `*.jpg`, `*.jpeg`, `*.mp4`, `*.mov`, `*.avi`, `*.zip`, `*.tar.gz`, `*.pdf`.
|
||||||
|
|
||||||
|
## Релизный процесс
|
||||||
|
|
||||||
|
Создание GitHub Release запускает `.github/workflows/release.yml` — сборка, тесты, паковка и публикация. Версии следуют семантическому версионированию.
|
||||||
276
docs/razorconsole/custom-translators.md
Normal file
276
docs/razorconsole/custom-translators.md
Normal file
@@ -0,0 +1,276 @@
|
|||||||
|
# RazorConsole — Кастомные VDOM-трансляторы
|
||||||
|
|
||||||
|
## Архитектура
|
||||||
|
|
||||||
|
RazorConsole использует Virtual DOM (VDOM) для преобразования Razor-компонентов в Spectre.Console `IRenderable`. Система трансляторов (translators) является расширяемой: можно добавить поддержку новых Spectre.Console-конструкций или построить полностью кастомные компоненты.
|
||||||
|
|
||||||
|
### Ключевые компоненты
|
||||||
|
|
||||||
|
#### `IVdomElementTranslator`
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public interface IVdomElementTranslator
|
||||||
|
{
|
||||||
|
// Чем меньше значение — тем выше приоритет (обрабатывается раньше).
|
||||||
|
int Priority { get; }
|
||||||
|
|
||||||
|
bool TryTranslate(VNode node, TranslationContext context, out IRenderable? renderable);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `TranslationContext`
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public sealed class TranslationContext
|
||||||
|
{
|
||||||
|
// Рекурсивный перевод дочерних узлов
|
||||||
|
public bool TryTranslate(VNode node, out IRenderable? renderable);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `VdomSpectreTranslator`
|
||||||
|
|
||||||
|
Оркестратор, который:
|
||||||
|
1. Получает список трансляторов через DI (отсортированных по приоритету)
|
||||||
|
2. Пробует каждый по очереди
|
||||||
|
3. Возвращает первый успешный результат
|
||||||
|
4. Предоставляет статические вспомогательные методы
|
||||||
|
|
||||||
|
### Pipeline трансляции
|
||||||
|
|
||||||
|
```
|
||||||
|
Razor-компонент → ConsoleRenderer → VNode tree → VdomSpectreTranslator
|
||||||
|
→ [Priority 10] → [Priority 20] → ... → [Priority 1000 (fallback)]
|
||||||
|
→ IRenderable
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Встроенные трансляторы
|
||||||
|
|
||||||
|
| Приоритет | Транслятор | Обрабатывает |
|
||||||
|
|---|---|---|
|
||||||
|
| 10 | TextElementTranslator | `<span data-text="true">` |
|
||||||
|
| 20 | HtmlInlineTextElementTranslator | `<strong>`, `<em>`, `<code>` |
|
||||||
|
| 30 | ParagraphElementTranslator | `<p>` |
|
||||||
|
| 40 | SpacerElementTranslator | `<div data-spacer="true">` |
|
||||||
|
| 50 | NewlineElementTranslator | `<br>` |
|
||||||
|
| 60 | SpinnerElementTranslator | `<div class="spinner">` |
|
||||||
|
| 70–80 | Button translators | `<button>` |
|
||||||
|
| 90 | SyntaxHighlighterElementTranslator | `<div class="syntax-highlighter">` |
|
||||||
|
| 100–190 | Layout translators | Panels, Rows, Columns, Grid, Padding, Align |
|
||||||
|
| 1000 | FailToRenderElementTranslator | Fallback для необработанных узлов |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Создание кастомного транслятора
|
||||||
|
|
||||||
|
### Шаг 1: Реализовать интерфейс
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using RazorConsole.Core.Rendering.Vdom;
|
||||||
|
using RazorConsole.Core.Vdom;
|
||||||
|
using Spectre.Console;
|
||||||
|
using Spectre.Console.Rendering;
|
||||||
|
|
||||||
|
public sealed class OverflowElementTranslator : IVdomElementTranslator
|
||||||
|
{
|
||||||
|
public int Priority => 85; // между встроенными 80 и 90
|
||||||
|
|
||||||
|
public bool TryTranslate(VNode node, TranslationContext context, out IRenderable? renderable)
|
||||||
|
{
|
||||||
|
renderable = null;
|
||||||
|
|
||||||
|
// 1. Быстрые проверки — fail fast
|
||||||
|
if (node.Kind != VNodeKind.Element) return false;
|
||||||
|
if (!string.Equals(node.TagName, "div", StringComparison.OrdinalIgnoreCase)) return false;
|
||||||
|
if (!node.Attributes.TryGetValue("data-overflow", out var overflowType)) return false;
|
||||||
|
|
||||||
|
// 2. Трансляция дочерних узлов
|
||||||
|
if (!VdomSpectreTranslator.TryConvertChildrenToRenderables(
|
||||||
|
node.Children, context, out var children)) return false;
|
||||||
|
|
||||||
|
var content = VdomSpectreTranslator.ComposeChildContent(children);
|
||||||
|
|
||||||
|
// 3. Создать IRenderable
|
||||||
|
renderable = overflowType?.ToLowerInvariant() switch
|
||||||
|
{
|
||||||
|
"ellipsis" => new Padder(content).Overflow(Overflow.Ellipsis),
|
||||||
|
"crop" => new Padder(content).Overflow(Overflow.Crop),
|
||||||
|
"fold" => new Padder(content).Overflow(Overflow.Fold),
|
||||||
|
_ => content
|
||||||
|
};
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Шаг 2: Зарегистрировать транслятор
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using RazorConsole.Core;
|
||||||
|
using RazorConsole.Core.Vdom;
|
||||||
|
|
||||||
|
IHostBuilder hostBuilder = Host.CreateDefaultBuilder(args)
|
||||||
|
.UseRazorConsole<MyComponent>(configure: config =>
|
||||||
|
{
|
||||||
|
config.ConfigureServices(services =>
|
||||||
|
{
|
||||||
|
// По типу (создаётся через DI)
|
||||||
|
services.AddVdomTranslator<OverflowElementTranslator>();
|
||||||
|
|
||||||
|
// По экземпляру
|
||||||
|
services.AddVdomTranslator(new OverflowElementTranslator());
|
||||||
|
|
||||||
|
// Через фабрику (для инъекции зависимостей)
|
||||||
|
services.AddVdomTranslator(sp =>
|
||||||
|
new OverflowElementTranslator(sp.GetRequiredService<IMyService>()));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Шаг 3: Использовать в Razor-компонентах
|
||||||
|
|
||||||
|
```razor
|
||||||
|
<div data-overflow="ellipsis">
|
||||||
|
Очень длинный текст, который будет обрезан с многоточием...
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Вспомогательные методы `VdomSpectreTranslator`
|
||||||
|
|
||||||
|
### Инспекция узла
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
string? value = VdomSpectreTranslator.GetAttribute(node, "data-style");
|
||||||
|
bool hasClass = VdomSpectreTranslator.HasClass(node, "my-class");
|
||||||
|
string? text = VdomSpectreTranslator.CollectInnerText(node);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Парсинг атрибутов
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// bool
|
||||||
|
if (VdomSpectreTranslator.TryGetBoolAttribute(node, "data-enabled", out bool enabled)) { }
|
||||||
|
|
||||||
|
// int с fallback
|
||||||
|
int count = VdomSpectreTranslator.TryGetIntAttribute(node, "data-count", fallback: 10);
|
||||||
|
|
||||||
|
// положительный int
|
||||||
|
if (VdomSpectreTranslator.TryParsePositiveInt(rawValue, out int result)) { }
|
||||||
|
|
||||||
|
// int? (null если невалидно)
|
||||||
|
int? width = VdomSpectreTranslator.ParseOptionalPositiveInt(rawValue);
|
||||||
|
|
||||||
|
// CSS-подобный padding: "1", "1,2", "1,2,3,4"
|
||||||
|
if (VdomSpectreTranslator.TryParsePadding(rawValue, out Padding padding)) { }
|
||||||
|
```
|
||||||
|
|
||||||
|
### Парсинг выравнивания
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
var hAlign = VdomSpectreTranslator.ParseHorizontalAlignment(value); // Left/Center/Right
|
||||||
|
var vAlign = VdomSpectreTranslator.ParseVerticalAlignment(value); // Top/Middle/Bottom
|
||||||
|
```
|
||||||
|
|
||||||
|
### Работа с дочерними узлами
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Перевести дочерние узлы
|
||||||
|
if (VdomSpectreTranslator.TryConvertChildrenToRenderables(
|
||||||
|
node.Children, context, out List<IRenderable> renderables)) { }
|
||||||
|
|
||||||
|
// Объединить в один IRenderable
|
||||||
|
// - 1 элемент → возвращает его напрямую
|
||||||
|
// - N элементов → Rows
|
||||||
|
// - 0 элементов → пустой Markup
|
||||||
|
IRenderable composed = VdomSpectreTranslator.ComposeChildContent(renderables);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Правила выбора приоритета
|
||||||
|
|
||||||
|
| Диапазон | Когда использовать |
|
||||||
|
|---|---|
|
||||||
|
| 1–9 | Переопределить встроенное поведение |
|
||||||
|
| 10–190 | Вклиниться между конкретными встроенными трансляторами |
|
||||||
|
| 200–999 | Общие кастомные трансляторы |
|
||||||
|
| 1000+ | Fallback-обработчики |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Лучшие практики
|
||||||
|
|
||||||
|
1. **Fail fast** — сразу возвращай `false` если узел не совпадает
|
||||||
|
2. **Case-insensitive сравнение** — `StringComparison.OrdinalIgnoreCase` для `TagName` и атрибутов
|
||||||
|
3. **Всегда используй `TryConvertChildrenToRenderables`** для рекурсивной трансляции детей
|
||||||
|
4. **Валидируй атрибуты** — предусматривай defaults, не бросай исключения
|
||||||
|
5. **Immutability** — создавай новые экземпляры `IRenderable`, не мутируй существующие
|
||||||
|
6. **Thread safety** — трансляторы должны быть stateless или использовать immutable state
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Продвинутые сценарии
|
||||||
|
|
||||||
|
### DI в трансляторе
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public sealed class DatabaseStyleTranslator : IVdomElementTranslator
|
||||||
|
{
|
||||||
|
private readonly IStyleProvider _styleProvider;
|
||||||
|
|
||||||
|
public DatabaseStyleTranslator(IStyleProvider styleProvider)
|
||||||
|
{
|
||||||
|
_styleProvider = styleProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Priority => 95;
|
||||||
|
|
||||||
|
public bool TryTranslate(VNode node, TranslationContext context, out IRenderable? renderable)
|
||||||
|
{
|
||||||
|
renderable = null;
|
||||||
|
if (!node.Attributes.TryGetValue("data-style-id", out var styleId)) return false;
|
||||||
|
|
||||||
|
var style = _styleProvider.GetStyle(styleId);
|
||||||
|
// ... создать renderable ...
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Регистрация
|
||||||
|
services.AddSingleton<IStyleProvider, MyStyleProvider>();
|
||||||
|
services.AddVdomTranslator<DatabaseStyleTranslator>();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Условная трансляция (Alert-компонент)
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public sealed class AlertTranslator : IVdomElementTranslator
|
||||||
|
{
|
||||||
|
public int Priority => 105;
|
||||||
|
|
||||||
|
public bool TryTranslate(VNode node, TranslationContext context, out IRenderable? renderable)
|
||||||
|
{
|
||||||
|
renderable = null;
|
||||||
|
if (!VdomSpectreTranslator.HasClass(node, "alert")) return false;
|
||||||
|
|
||||||
|
if (!VdomSpectreTranslator.TryConvertChildrenToRenderables(
|
||||||
|
node.Children, context, out var children)) return false;
|
||||||
|
|
||||||
|
var content = VdomSpectreTranslator.ComposeChildContent(children);
|
||||||
|
|
||||||
|
renderable = VdomSpectreTranslator.HasClass(node, "alert-danger")
|
||||||
|
? new Panel(content).BorderColor(Color.Red).Header("[red]⚠ Error[/]")
|
||||||
|
: VdomSpectreTranslator.HasClass(node, "alert-success")
|
||||||
|
? new Panel(content).BorderColor(Color.Green).Header("[green]✓ Success[/]")
|
||||||
|
: new Panel(content).BorderColor(Color.Blue).Header("[blue]ℹ Info[/]");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
116
docs/razorconsole/overview.md
Normal file
116
docs/razorconsole/overview.md
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
# RazorConsole — Обзор
|
||||||
|
|
||||||
|
**Репозиторий:** https://github.com/RazorConsole/RazorConsole
|
||||||
|
**Лицензия:** MIT
|
||||||
|
**Последняя версия:** v0.5.0 (март 2026)
|
||||||
|
**NuGet:** `RazorConsole.Core`
|
||||||
|
|
||||||
|
## Что такое RazorConsole?
|
||||||
|
|
||||||
|
RazorConsole — это .NET-библиотека для построения интерактивных TUI-приложений (Terminal User Interface) с использованием синтаксиса Razor-компонентов и движка рендеринга Spectre.Console.
|
||||||
|
|
||||||
|
Библиотека заполняет разрыв между веб-разработкой на Blazor/Razor и консольными приложениями: разработчик пишет компоненты `.razor`, а на выходе получает полноценный интерактивный терминальный интерфейс.
|
||||||
|
|
||||||
|
## Ключевые возможности
|
||||||
|
|
||||||
|
| Возможность | Описание |
|
||||||
|
|---|---|
|
||||||
|
| Компонентная архитектура | Razor-компоненты с data binding, event handling и lifecycle |
|
||||||
|
| 25+ встроенных компонентов | Макет, ввод, отображение, утилиты |
|
||||||
|
| Интерактивность | Кнопки, текстовые поля, селекторы, навигация клавиатурой |
|
||||||
|
| Hot Reload | Обновление UI без перезапуска через metadata update handler |
|
||||||
|
| VDOM + Translators | Виртуальный DOM с расширяемой системой трансляторов |
|
||||||
|
| DI интеграция | Построен на `Microsoft.Extensions.Hosting` |
|
||||||
|
| Галерея компонентов | Глобальный инструмент `razorconsole-gallery` |
|
||||||
|
|
||||||
|
## Технологический стек
|
||||||
|
|
||||||
|
- **Runtime:** .NET 8 / .NET 9
|
||||||
|
- **SDK:** `Microsoft.NET.Sdk.Razor` (обязателен в `.csproj`)
|
||||||
|
- **Рендеринг:** Spectre.Console
|
||||||
|
- **DI/Host:** `Microsoft.Extensions.Hosting`
|
||||||
|
- **Синтаксис подсветки:** ColorCode
|
||||||
|
|
||||||
|
## Установка
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet add package RazorConsole.Core
|
||||||
|
```
|
||||||
|
|
||||||
|
## Минимальный проект
|
||||||
|
|
||||||
|
### Файл проекта (`.csproj`)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||||
|
<!-- другие настройки -->
|
||||||
|
</Project>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Компонент `Counter.razor`
|
||||||
|
|
||||||
|
```razor
|
||||||
|
@using Microsoft.AspNetCore.Components
|
||||||
|
@using Microsoft.AspNetCore.Components.Web
|
||||||
|
@using RazorConsole.Components
|
||||||
|
|
||||||
|
<Columns>
|
||||||
|
<p>Current count</p>
|
||||||
|
<Markup Content="@currentCount.ToString()" Foreground="@Spectre.Console.Color.Green" />
|
||||||
|
</Columns>
|
||||||
|
<TextButton Content="Click me"
|
||||||
|
OnClick="IncrementCount"
|
||||||
|
BackgroundColor="@Spectre.Console.Color.Grey"
|
||||||
|
FocusedColor="@Spectre.Console.Color.Blue" />
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private int currentCount = 0;
|
||||||
|
private void IncrementCount() { currentCount++; }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### `Program.cs`
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using RazorConsole.Core;
|
||||||
|
|
||||||
|
IHostBuilder hostBuilder = Host.CreateDefaultBuilder(args)
|
||||||
|
.UseRazorConsole<Counter>();
|
||||||
|
|
||||||
|
IHost host = hostBuilder.Build();
|
||||||
|
await host.RunAsync();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Примеры приложений
|
||||||
|
|
||||||
|
| Пример | Демонстрирует |
|
||||||
|
|---|---|
|
||||||
|
| `examples/Counter/` | Основы: кнопки, состояние, layout, styled text |
|
||||||
|
| `examples/LLMAgentTUI/` | Интеграция с AI SDK (OpenAI/Ollama), чат-интерфейс |
|
||||||
|
| `examples/LoginForm/` | Форма с валидацией, маскирование пароля, состояния ошибок |
|
||||||
|
|
||||||
|
## Компонентная галерея
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet tool install --global RazorConsole.Gallery --version 0.0.3-alpha
|
||||||
|
razorconsole-gallery
|
||||||
|
```
|
||||||
|
|
||||||
|
## Структура репозитория
|
||||||
|
|
||||||
|
```
|
||||||
|
src/ — исходный код библиотеки
|
||||||
|
examples/ — примеры приложений
|
||||||
|
design-doc/ — архитектурные документы
|
||||||
|
nuget/ — конфигурация NuGet
|
||||||
|
release-notes/ — история релизов
|
||||||
|
docfx/ — генерация документации
|
||||||
|
website/ — сайт проекта
|
||||||
|
```
|
||||||
|
|
||||||
|
## Сообщество
|
||||||
|
|
||||||
|
- Discord: https://discord.gg/DphHAnJxCM
|
||||||
|
- Issues: https://github.com/RazorConsole/RazorConsole/issues
|
||||||
|
- Codecov: https://codecov.io/gh/RazorConsole/RazorConsole
|
||||||
Reference in New Issue
Block a user