\n
\n {graph && reactLayer && reactLayer.renderPortal(renderBlock)}\n
\n
\n );\n ```\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n Overall, everything is quite simple. Nothing described above needs to\n be written by yourself—everything is already implemented and ready to\n use.\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n ## Our graph library: what the benefits are and how to use\n it{#library}\n\n\n When we started working on the library, the main question was: how do\n we make it so that a developer doesn’t have to choose between\n performance and development convenience? The answer turned out to be\n automating that choice.\n\n\n ### Benefits\n\n\n #### Performance + convenience\n\n\n [@gravity‑ui/graph](https://github.com/gravity-ui/graph){target=\"_blank\"}\n automatically switches between Canvas and HTML depending on the scale.\n This means you get:\n\n * Stable 60 FPS on graphs with thousands of elements.\n * The ability to use full-fledged HTML components with rich interactivity when viewing in detail.\n * A single event model regardless of rendering method—click, mouseenter work the same on Canvas and in HTML.\n\n #### Compatibility with UI libraries\n\n\n One of the main advantages is compatibility with any UI libraries. If\n your team uses:\n\n * Gravity UI,\n * Material‑UI,\n * Ant Design,\n * custom components.\n\n …then you don’t need to give them up! When you zoom in, the graph\n automatically switches to HTML mode, where familiar `Button`,\n `Select`, `DatePicker` in the color theme you need work exactly the\n same as in a regular React app.\n\n\n #### Framework agnostic\n\n\n Although we implemented the basic HTML renderer using React, we tried\n to develop the library so that it remains framework-agnostic. This\n means that if necessary, you can fairly easily implement a layer\n integrating your favorite framework.\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: \"\\n## Are there any alternatives?{#analogs}\\n\\nThere are quite a lot of solutions on the market for graph rendering, from paid solutions like [yFiles](https://yfiles.dev/){target=\\\"_blank\\\"}, [JointJS](https://github.com/clientIO/joint){target=\\\"_blank\\\"}, to open-source solutions [Foblex Flow](https://github.com/Foblex/f-flow){target=\\\"_blank\\\"}, [baklavajs](https://github.com/newcat/baklavajs){target=\\\"_blank\\\"}, [jsPlumb](https://github.com/jsplumb/community-edition){target=\\\"_blank\\\"}. But for comparison we consider [@antv/g6](https://github.com/antvis/G6){target=\\\"_blank\\\"} and [React Flow](https://github.com/xyflow/xyflow){target=\\\"_blank\\\"} as the most popular tools. Each of them has its own features.\\n\\nReact Flow is a good library tailored for building node-based interfaces. It has very extensive capabilities, but due to using svg and html its performance is rather modest. The library is good when you’re confident graphs won’t exceed 100–200 blocks.\\n\\nIn turn, @antv/g6 has a ton of features; it supports Canvas and in particular WebGL. Comparing @antv/g6 and @gravity‑ui/graph directly is probably not quite correct: their team is more focused on building graphs and charts—but node-based UI is also supported. So antv/g6 is suitable if you care not only about a node-based interface but also about drawing charts.\\n\\nAlthough @antv/g6 can do both canvas/webgl and html/svg, you’ll have to manage the switching rules manually, and you need to do it correctly. Performance-wise it is much faster than React Flow, but there are still questions about the library. While WebGL support is claimed, if you look at their [stress test](https://g6.antv.antgroup.com/en/examples/performance/massive-data#60000){target=\\\"_blank\\\"}, it’s noticeable that on 60k nodes the library can’t deliver dynamics—on a MacBook M3 rendering a single frame took 4 seconds. For comparison, our [stress test](https://preview.gravity-ui.com/graph/?path=/story/stories-main-grapheditor--graph-stress-test){target=\\\"_blank\\\"} on 111k nodes and 109k connections on the same Macbook M3: rendering the entire graph scene takes ~60ms, which yields ~15–20 FPS. That’s not very much, but with Spatial Culling there is an option to limit the viewport and thus improve responsiveness. Although the maintainers [stated](https://github.com/antvis/G6/issues/1597){target=\\\"_blank\\\"} they want to achieve rendering 100k nodes at 30 FPS, apparently they have not managed to do so yet.\\n\\nAnother point where @gravity‑ui/graph wins is bundle size.\\n\\n#|\\n|||Bundle size Minified|Bundle size Minified + Gzipped||\\n||@antv/g6 [bundlephobia](https://bundlephobia.com/package/@antv/g6@5.0.49){target=\\\"_blank\\\"}|1.1 MB|324.5\\_kB||\\n||react flow [bundlephobia](https://bundlephobia.com/package/@xyflow/react@12.8.1){target=\\\"_blank\\\"}|181.2\\_kB|56.4\\_kB||\\n||@gravity-ui/graph [bundlephobia](https://bundlephobia.com/package/@gravity-ui/graph){target=\\\"_blank\\\"}|2.2\\_kB|672\\_B||\\n|#\\n\\nAlthough both libraries are quite strong in terms of performance or integration convenience, @gravity‑ui/graph has a number of advantages—it can provide performance on truly large graphs while preserving UI/UX for the user and simplifying development.\\n\"\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n ## Plans for the future{#future}\n\n\n The library already has sufficient performance headroom for most\n tasks, so in the near future we will focus more on developing the\n ecosystem around the library—building layers (plugins), integrations\n for other libraries and frameworks (Angular/Vue/Svelte, …etc), adding\n support for touch devices, adaptation for mobile browsers, and\n generally improving UX/DX.\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n ## Try it and join in{#try}\n\n\n In the\n [repository](https://github.com/gravity-ui/graph){target=\"_blank\"}\n you’ll find a fully working library:\n\n * Canvas + R-Tree core (≈ 30K lines of code),\n * React integration,\n * Storybook with examples.\n\n You can install the library in one line:\n\n\n `npm install @gravity-ui/graph`\n\n\n --------------\n\n\n For quite a long time, the library that is now called\n @gravity‑ui/graph was an internal tool inside Nirvana, and the chosen\n approach has proven itself well. Now we want to share our work and\n help developers outside draw their graphs more easily, faster, and\n more efficiently.\n\n\n We want to standardize approaches to displaying complex graphs in the\n open-source community—too many teams reinvent the wheel or struggle\n with unsuitable tools.\n\n\n That’s why it’s very important for us to collect your\n feedback—different projects bring different edge cases that help\n evolve the library. This will help us refine the library and grow the\n Gravity UI ecosystem faster.\n - type: blog-layout-block\n resetPaddings: true\n fullWidth: false\n children:\n - type: blog-meta-block\n column: left\n resetPaddings: true\n - type: blog-suggest-block\n resetPaddings: true\n",
+ "title": "",
+ "noIndex": false,
+ "shareTitle": null,
+ "shareDescription": null,
+ "shareImage": "https://storage.yandexcloud.net/gravity-landing-static/blog/blog-cover-bg.png",
+ "pageLocaleId": null,
+ "author": "timofeyevvv",
+ "metaDescription": null,
+ "keywords": [],
+ "shareGenTitle": null,
+ "canonicalLink": null,
+ "sharingType": "semi-full",
+ "sharingTheme": "dark",
+ "comment": "sharing pic",
+ "shareImageUrl": "https://storage.cloud-preprod.yandex.net/ui-api-ru-preprod-stable-share-generator-screenshots/cache/b155df2ab692d6e154ff809a7d91b9ad4789de53.png",
+ "pageRegionId": 76,
+ "summary": null,
+ "versionId": 216,
+ "service": null,
+ "solution": null,
+ "locales": [
+ {
+ "id": 75,
+ "pageId": 71,
+ "locale": "ru",
+ "createdAt": "2026-01-15T11:26:48.440Z",
+ "updatedAt": "2026-01-15T11:26:48.519Z",
+ "publishedVersionId": null,
+ "lastVersionId": 195
+ },
+ {
+ "id": 76,
+ "pageId": 71,
+ "locale": "en",
+ "createdAt": "2026-01-15T11:26:48.532Z",
+ "updatedAt": "2026-01-15T11:26:48.609Z",
+ "publishedVersionId": null,
+ "lastVersionId": 196
+ }
+ ],
+ "pageRegions": [
+ {
+ "regionCode": "ru-ru",
+ "publishedVersionId": 199
+ },
+ {
+ "regionCode": "en",
+ "publishedVersionId": 216
+ }
+ ],
+ "searchCategory": {
+ "id": 7,
+ "slug": "blog",
+ "title": "Blog",
+ "url": "/blog"
+ },
+ "voiceovers": []
+ }
+
\ No newline at end of file
diff --git a/src/api/.mocks/en/pages/gravity-ui-in-opensource.json b/src/api/.mocks/en/pages/gravity-ui-in-opensource.json
index 80e028a39a9f..26307ed008cc 100644
--- a/src/api/.mocks/en/pages/gravity-ui-in-opensource.json
+++ b/src/api/.mocks/en/pages/gravity-ui-in-opensource.json
@@ -1,8 +1,8 @@
{
"id": 70,
"name": "blog/gravity-ui-in-opensource",
- "createdAt": "2025-12-25T10:46:31.596Z",
- "updatedAt": "2025-12-25T10:46:31.596Z",
+ "createdAt": "2026-01-15T11:59:09.523Z",
+ "updatedAt": "2026-01-15T11:59:09.523Z",
"type": "default",
"isDeleted": false,
"versionOnTranslationId": null,
@@ -10,27 +10,27 @@
"regions": [],
"pageId": 70,
"regionCode": "en",
- "publishedVersionId": 194,
- "lastVersionId": 194,
- "content": "blocks:\n - type: blog-header-block\n resetPaddings: true\n paddingBottom: l\n width: m\n verticalOffset: m\n theme: dark\n background:\n image:\n src: https://storage.yandexcloud.net/yandex-opensource/blog-cover-bg.png\n disableCompress: true\n color: ''\n fullWidth: false\n - type: blog-layout-block\n resetPaddings: true\n mobileOrder: reverse\n children:\n - type: blog-author-block\n column: right\n resetPaddings: true\n authorId: 1069\n - type: blog-yfm-block\n column: right\n resetPaddings: true\n text: \"\\nВ этой статье:\\n\\n - [В чём особенности Gravity\\_UI](#peculiarities)\\n - [Как работать с Gravity\\_UI](#work)\\n - [Как воспользоваться Gravity\\_UI](#use)\\n\"\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: \"\\nВсем привет, я Алексей Сизиков, руководитель отдела User Experience в Yandex Cloud. В этой статье я хочу поделиться новостью: мы выпустили нашу дизайн‑систему и библиотеку компонентов [Gravity\\_UI](https://github.com/gravity-ui){target=\\\"_blank\\\"} в опенсорс. \\n\\nС помощью библиотеки компонентов Gravity\\_UI можно строить современные интерфейсы. В неё входит:\\n\\n * набор базовых React‑компонентов;\\n * библиотека‑конструктор для лендингов;\\n * [подробные гайды](https://gravity-ui.com/design){target=\\\"_blank\\\"} по использованию компонентов;\\n * библиотека в [Figma](https://www.figma.com/community/file/1271150067798118027/Gravity-UI-Design-System-(Beta)){target=\\\"_blank\\\"}; \\n * набор готовых иконок, в составе которого почти 600 вариантов;\\n * ChartKit — пакет для визуализации данных;\\n * Yagr — высокопроизводительный рендеринг графиков, основанный на uPlot;\\n * I18n — пакет для локализации интерфейса\\n * и ещё более [25 полезных библиотек](https://gravity-ui.com/libraries){target=\\\"_blank\\\"}.\\n\"\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic0.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: \"\\nПод катом — рассказ, зачем мы сделали Gravity\\_UI, как его используем, в чём особенности и преимущества нашего подхода и как мы планируем развивать его дальше. А ещё — как настроить разные цветовые схемы в своих проектах и почему у нас четыре темы вместо двух стандартных.\\n\\n{% cut \\\"Зачем мы сделали Gravity\\_UI\\\" %}\\n\\nИзначально библиотека UIKit была внутренним продуктом для ускорения работы команды. По мере роста числа новых сервисов мы поставили цель: построить единый UX в наших продуктах. Нам было важно использовать одинаковые паттерны поведения пользователей в сервисах, чтобы пользователь ощущал всю платформу как единое целое.\\n\\nДополнительной целью дизайн‑команды было создать такие инструменты, чтобы разработчики смогли без привлечения дизайнеров сделать новый сервис.\\n\\nОтносительно недавно платформы и сервисы, использующие нашу дизайн‑систему, начали выходить в опенсорс: [YTsaurus](https://ytsaurus.tech/){target=\\\"_blank\\\"}, [YDB](https://ydb.tech/){target=\\\"_blank\\\"}, [DataLens](https://datalens.tech/){target=\\\"_blank\\\"}, [Diplodoc](https://diplodoc.com/){target=\\\"_blank\\\"}. Многие пользователи позитивно отзывались о них и помогали улучшать код вместе с разработчиками. Вдохновившись их примером, мы пришли к идее выпустить в открытый доступ и Gravity\\_UI, потому что видели, насколько библиотека может быть полезна многим сервисам не только внутри Яндекса.\\n\\n{% endcut %}\\n\"\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: \"\\n## В чём особенности Gravity\\_UI{#peculiarities}\\n\\n### Основано на реальном опыте\\n\\nОдна из отличительных черт нашей дизайн‑системы — она развивается на основе потребностей наших пользователей, большинство из которых являются разработчиками. Более того, наши дизайнеры неразрывно связаны с продуктами, в которых они работают. У каждого дизайнера есть несколько сервисов с собственными сценариями использования. После того как решение протестировано в их сервисах, продуктовый дизайнер передаёт его в другие сервисы, чтобы убедиться, что оно работает и помогает разработчикам. \\n\\nНапример, компонент боковой навигации изначально развивался только с логотипом и пунктами меню. Позже для удобства мы добавили пункт со всеми сервисами и поиском. А когда у нас появился сервис, где была необходимость создавать новую сущность сразу в боковом меню, у нас появилась отдельная кнопка с плюсиком. Дальше появились разделы меню с разделителями для сложных сервисов с большим количеством пунктов меню, а также кнопка «Остальные пункты».\\n\"\n - type: blog-media-block\n column: left\n resetPaddings: true\n paddingBottom: s\n text: >-\n Компонент Навигации — можно настроить как простой вариант, так и\n максимально нагруженный\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic1.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: \"\\n### Гибкая вариативность\\n\\nМногие компоненты Gravity\\_UI можно настроить, учитывая разные сценарии. Например, у компонента [pagination](https://gravity-ui.com/components/uikit/pagination){target=\\\"_blank\\\"} есть несколько вариантов отображения: с общим числом страниц, полными подписями кнопок, возможностью перейти к конкретной странице и изменить число ответов на странице — этот вариант рассчитан на большое число страниц. А если у вас кейс, где результатов ответов немного, можно сделать компактный режим или даже скрыть цифры и показывать только стрелочки. \\n\"\n - type: blog-media-block\n column: left\n resetPaddings: true\n paddingBottom: s\n text: Пример отображения разных вариантов пагинации\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic2.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: \"\\n### Широкая область применения\\n\\nПри помощи Gravity\\_UI можно сделать как простой интерфейс для администрирования, так и сложный дашборд с графиками. Вот несколько примеров того, что можно собрать с помощью нашей дизайн‑системы:\\n\\n * лендинги,\\n * админки,\\n * дашборды,\\n * графики,\\n * СRM,\\n * аналитический сервис.\\n\\nНапример, наши коллеги сделали такой дашборд:\\n\"\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: \"Пример дашборда, который можно сделать с помощью Gravity\\_UI\"\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic3.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: \"\\nТакже можно сделать простой лендинг. Например, [сайт](https://opensource.yandex/){target=\\\"_blank\\\"} с нашими проектами в опенсорс сделан на компонентах Gravity\\_UI. \\n\"\n - type: blog-media-block\n column: left\n resetPaddings: true\n paddingBottom: s\n text: >-\n А это пример сайта, который тоже можно сделать с помощью нашей\n дизайн‑системы\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic4.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n ### Более 150 контрибьюторов\n\n\n Наша экосистема постоянно развивается и улучшается. Кроме обратной\n связи от нашего сообщества разработчиков, к нам поступают предложения\n более чем от 100 сервисов, которые уже используют нашу\n дизайн‑систему. \n\n\n Приведу пример. Изначально у нас было две темы — тёмная и светлая. Но\n мы стали получать фидбэк от команд, которые транслируют интерфейс на\n телевизоры для просмотра графиков или во время стендапа. Дело в том,\n что на телевизоре плохо видно интерфейс. Похожая проблема встречается\n также у пользователей со старыми или низкокачественными мониторами.\n\n\n В итоге разработали повышенную контрастность для каждой из тем. Она\n увеличивает яркость тёмного и светлого, а также семантических цветов.\n Это настраивается CSS‑стилями, а управляется в настройках\n пользователя.\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: \"Пример интерфейса Yandex Tracker, сделанный также на компонентах Gravity\\_UI, с возможностью включения повышенной контрастности\"\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic5.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n Кстати, теперь вы тоже можете сделать свой вклад. Для этого присылайте\n PR в GitHub или оставляйте комментарии в Figma.\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: \"\\n## Как работать с Gravity\\_UI{#work}\\n\\n### Настройка интерфейса под свой бренд\\n\\nДалее я расскажу о том, что ещё можно сделать с помощью Gravity\\_UI. Начну с возможности настроить дизайн‑систему под свой бренд. Например, когда YDB выходил в опенсорс, перед нами встала задача сохранить единую дизайн‑систему, но при этом сделать её особенной для разных брендов. Для этого мы создали отдельную группу CSS‑переменных. В неё входят цвета бренда, шрифты и радиусы скруглений. В коде это выглядит как небольшой блок:\\n\\n```json \\n.g-root {\\n --g-font-family-sans: 'Inter', sans-serif;\\n\\n --g-text-header-font-weight: 600;\\n --g-text-subheader-font-weight: 600;\\n --g-text-display-font-weight: 600;\\n --g-text-accent-font-weight: 600;\\n\\n --g-color-base-brand: rgb(117, 155, 255);\\n --g-color-base-brand-hover: rgb(99, 143, 255);\\n --g-color-base-selection: rgba(82, 130, 255, 0.05);\\n --g-color-base-selection-hover: rgba(82, 130, 255, 0.1);\\n --g-color-line-brand: rgb(117, 155, 255);\\n --g-color-text-brand: rgb(117, 155, 255);\\n --g-color-text-brand-contrast: rgb(255, 255 ,255);\\n --g-color-text-link: rgb(117, 155, 255);\\n --g-color-text-link-hover: rgb(82, 130, 255);\\n\\n --g-border-radius-xs: 3px;\\n --g-border-radius-s: 5px;\\n --g-border-radius-m: 6px;\\n --g-border-radius-l: 8px;\\n --g-border-radius-xl: 10px;\\n --g-border-radius-2xl: 16px;\\n}\\n```\\n\\nВ этой группе можно заменить шрифт, цвет акцентных кнопок, скругления. И таким образом можно использовать одну дизайн‑систему для разных брендов, сохраняя при этом фирменный стиль. Если же этот вариант вам не подходит, можно создать собственную цветовую схему. Подробная инструкция есть в [документации](https://preview.gravity-ui.com/uikit/?path=/docs/branding-overview--docs#additional-customization){target=\\\"_blank\\\"}.\\n\"\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: Пример интерфейсов с разными переменными бренда\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic6.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n Стоит отметить, что изменение цветов бренда не повлияет на основной\n интерфейс. Это особенно важно для тех элементов, где используются\n семантические цвета: например, красный по‑прежнему будет означать\n ошибку, а зелёный — успех.\n\n\n ### Компоненты в Figma\n\n\n Для удобства работы наша команда дизайнеров подготовила и загрузила\n все состояния компонентов в\n [Figma](https://www.figma.com/community/file/1271150067798118027){target=\"_blank\"}.\n При желании можно сделать копию библиотеки и попробовать собрать\n интерфейс сразу в сервисе.\n\n\n С последним обновлением в библиотеке не дублируются все четыре темы.\n По умолчанию вы работаете в светлой теме, но в разделе Layer вы можете\n переключить любой элемент или всю страницу на другую тему. \n - type: blog-media-block\n column: left\n resetPaddings: true\n text: Как просмотреть элемент в разных темах\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic7.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n Все элементы библиотеки представлены на странице Overview. Тут вы\n можете найти нужный компонент и перейти на страницу со всеми\n состояниями элемента. Кроме того, у каждого компонента есть пример\n использования. \n - type: blog-media-block\n column: left\n resetPaddings: true\n paddingBottom: s\n text: \"Страница со всеми элементами Gravity\\_UI\"\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic8.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n ### Почти 600 иконок\n\n Иконки — один из обязательных элементов дизайна и юзабилити. Они\n помогают организовать и структурировать контент, расставить акценты и\n улучшить восприятие информации. На первый взгляд, сделать пак иконок\n не так уж и сложно. Но мы столкнулись с вызовом при создании иконок\n для сложных метафор, таких как виртуальные машины, базы данных и\n различные типы графиков.\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: Пока у нас 594 иконки, но скоро их станет больше\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic9.png\n fullscreen: true\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: >-\n Особой задачей стала и разработка иконок для графического редактора\n контента (WYSIWYG), который внедряется в различные места для\n форматирования текста \n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic10.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n Чтобы сделать поиск иконок более удобным, мы использовали специальную\n систему нейминга. Теперь одну и ту же иконку можно найти, вводя разные\n названия. Например, чтобы найти такую иконку со стрелочкой, можно\n ввести любое слово: arrow, enter, move, login.\n - type: blog-media-block\n column: left\n resetPaddings: true\n paddingBottom: s\n text: >-\n Все иконки доступны на [отдельной\n странице](https://gravity-ui.com/icons). Вы можете скопировать SVG или\n скачать любую иконку\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic11.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n ### Гайды\n\n\n Как я уже писал выше, наша цель заключалась в том, чтобы разработчики\n могли легко создавать типовые интерфейсы, используя описания\n компонентов в нашем гайде. Мы стремились сделать этот процесс простым,\n без необходимости обращаться к дизайнеру за каждым элементом. На\n данный момент у нас уже есть пять примеров внутренних сервисов,\n которые были полностью созданы разработчиками с использованием только\n гайдов.\n\n\n Конечно, одними руками разработчика эту задачу решить не получится:\n так или иначе есть сложные сценарии, которые требуют внимания\n UX/UI‑специалиста. Тем не менее мы смогли снять значительную часть\n нагрузки с наших дизайнеров.\n\n\n В гайдах команда дизайнеров описала компоненты и дала рекомендации по\n их использованию, демонстрируя примеры правильного и неправильного\n подхода. Вы можете ознакомиться с ними на [этой\n странице](https://gravity-ui.com/components/uikit/alert){target=\"_blank\"}.\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic12.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: \"\\n## Как воспользоваться Gravity\\_UI{#use}\\n\\nВсё, что нужно сделать, — вбить команду в консоль:\\n\\n```\\ngit clone git@github.com:gravity-ui/uikit-example-cra.git my-project && cd my-project\\nnpm i \\nnpm run start\\n```\\n\\nБолее подробная инструкция есть на главной странице репозитория в [GitHub](https://github.com/gravity-ui/uikit){target=\\\"_blank\\\"}.\\n\\nВсе компоненты Gravity\\_UI можно посмотреть в [UIkit](https://preview.gravity-ui.com/uikit/){target=\\\"_blank\\\"}, а подключить нужную библиотеку для ваших потребностей — в [Libraries](https://gravity-ui.com/libraries){target=\\\"_blank\\\"}. \\n\\n--------\\n\\nПодводя итоги, хочется ещё раз отметить: Gravity\\_UI — это дизайн‑система, которая выросла из реального опыта наших пользователей, потребности разработчиков и экспертизы дизайнеров. Это позволяет ей быть практичной и эффективной. И теперь ею может бесплатно воспользоваться любой желающий.\\n\\nМы стремимся сделать проект ещё лучше, учитывая потребности и отзывы наших пользователей. Заходите к нам в GitHub, оставляйте свои PR, пишите комментарии в Figma и делитесь примерами использования.\\n\"\n - type: blog-layout-block\n resetPaddings: true\n fullWidth: false\n children:\n - type: blog-meta-block\n column: left\n resetPaddings: true\n - type: blog-suggest-block\n resetPaddings: true\n",
+ "publishedVersionId": 201,
+ "lastVersionId": 201,
+ "content": "blocks:\n - type: blog-header-block\n resetPaddings: true\n paddingBottom: l\n width: m\n verticalOffset: m\n theme: dark\n background:\n image:\n src: https://storage.yandexcloud.net/yandex-opensource/blog-cover-bg.png\n disableCompress: true\n color: '#CCDAFF'\n fullWidth: false\n - type: blog-layout-block\n resetPaddings: true\n mobileOrder: reverse\n children:\n - type: blog-author-block\n column: right\n resetPaddings: true\n authorId: 1069\n - type: blog-yfm-block\n column: right\n resetPaddings: true\n text: \"\\nIn this article:\\n\\n - [What are the features of Gravity\\_UI](#peculiarities)\\n - [How to work with Gravity\\_UI](#work)\\n - [How to use Gravity\\_UI](#use)\\n\"\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: \"\\nHello everyone, I’m Alexey Sizikov, Head of User Experience at Yandex Cloud. In this article, I’d like to share some news: we’ve open-sourced our design system and component library [Gravity\\_UI](https://github.com/gravity-ui){target=\\\"_blank\\\"}. \\n\\nWith the Gravity\\_UI component library, you can build modern interfaces. It includes:\\n\\n * a set of basic React components;\\n * a landing page builder library;\\n * [detailed guides](https://gravity-ui.com/design){target=\\\"_blank\\\"} on using the components;\\n * a library in [Figma](https://www.figma.com/community/file/1271150067798118027/Gravity-UI-Design-System-(Beta)){target=\\\"_blank\\\"}; \\n * a set of ready-made icons with nearly 600 options;\\n * ChartKit — a data visualization package;\\n * Yagr — high-performance chart rendering based on uPlot;\\n * I18n — a UI localization package\\n * and more than [25 useful libraries](https://gravity-ui.com/libraries){target=\\\"_blank\\\"}.\\n\"\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic0.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: \"\\nBelow the cut is a story about why we created Gravity\\_UI, how we use it, what the features and advantages of our approach are, and how we plan to evolve it further. Also: how to configure different color schemes in your projects and why we have four themes instead of the usual two.\\n\\n{% cut \\\"Why we created Gravity\\_UI\\\" %}\\n\\nInitially, the UIKit library was an internal product to speed up the team’s work. As the number of new services grew, we set a goal: to build a unified UX across our products. It was important to use the same user behavior patterns across services so that users would perceive the entire platform as a single whole.\\n\\nAn additional goal for the design team was to create tools so that developers could build a new service without involving designers.\\n\\nRelatively recently, platforms and services using our design system started going open source: [YTsaurus](https://ytsaurus.tech/){target=\\\"_blank\\\"}, [YDB](https://ydb.tech/){target=\\\"_blank\\\"}, [DataLens](https://datalens.tech/){target=\\\"_blank\\\"}, [Diplodoc](https://diplodoc.com/){target=\\\"_blank\\\"}. Many users spoke positively about them and helped improve the code together with the developers. Inspired by their example, we came up with the idea to release Gravity\\_UI to the public as well, because we saw how useful the library could be for many services — not only inside Yandex.\\n\\n{% endcut %}\\n\"\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: \"\\n## What are the features of Gravity\\_UI{#peculiarities}\\n\\n### Based on real-world experience\\n\\nOne of the distinguishing features of our design system is that it evolves based on the needs of our users — most of whom are developers. Moreover, our designers are closely tied to the products they work on. Each designer has several services with their own usage scenarios. After a solution has been tested in their services, the product designer rolls it out to other services to make sure it works and helps developers. \\n\\nFor example, the side navigation component initially evolved with only a logo and menu items. Later, for convenience, we added an item with all services and a search feature. And when we got a service where there was a need to create a new entity right from the side menu, we added a separate plus button. Next came menu sections with dividers for complex services with lots of menu items, as well as an “Other items” button.\\n\"\n - type: blog-media-block\n column: left\n resetPaddings: true\n paddingBottom: s\n text: >-\n The Navigation component — you can configure it as a simple version or\n as a fully loaded one\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic1.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: \"\\n### Flexible variability\\n\\nMany Gravity\\_UI components can be configured for different scenarios. For example, the [pagination](https://gravity-ui.com/components/uikit/pagination){target=\\\"_blank\\\"} component has several display options: with a total page count, full button labels, the ability to jump to a specific page, and changing the number of results per page — this option is designed for a large number of pages. But if your case has only a few results, you can use a compact mode or even hide the numbers and show only arrows. \\n\"\n - type: blog-media-block\n column: left\n resetPaddings: true\n paddingBottom: s\n text: Example of displaying different pagination variants\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic2.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: \"\\n### Broad range of applications\\n\\nWith Gravity\\_UI, you can build both a simple admin interface and a complex dashboard with charts. Here are a few examples of what you can put together with our design system:\\n\\n * landing pages,\\n * admin panels,\\n * dashboards,\\n * charts,\\n * CRM,\\n * an analytics service.\\n\\nFor example, our colleagues built this dashboard:\\n\"\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: \"An example dashboard you can build with Gravity\\_UI\"\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic3.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: \"\\nYou can also build a simple landing page. For example, the [website](https://opensource.yandex/){target=\\\"_blank\\\"} with our open-source projects is built using Gravity\\_UI components. \\n\"\n - type: blog-media-block\n column: left\n resetPaddings: true\n paddingBottom: s\n text: >-\n And this is an example of a website you can also build with our design\n system\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic4.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n ### More than 150 contributors\n\n\n Our ecosystem is constantly evolving and improving. In addition to\n feedback from our developer community, we receive suggestions from\n more than 100 services that already use our design system. \n\n\n Here’s an example. Initially, we had two themes — dark and light. But\n we started receiving feedback from teams that broadcast the interface\n to TVs for viewing charts or during stand-ups. The issue is that the\n interface is hard to see on a TV. A similar problem also occurs for\n users with old or low-quality monitors.\n\n\n As a result, we developed increased contrast for each theme. It\n increases the brightness of dark and light colors as well as semantic\n colors. This is configured via CSS styles and controlled in user\n settings.\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: \"Example of the Yandex Tracker interface, also built with Gravity\\_UI components, with the option to enable increased contrast\"\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic5.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n By the way, now you can contribute too. Send PRs on GitHub or leave\n comments in Figma.\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: \"\\n## How to work with Gravity\\_UI{#work}\\n\\n### Customizing the interface for your brand\\n\\nNext, I’ll talk about what else you can do with Gravity\\_UI. I’ll start with the ability to customize the design system to match your brand. For example, when YDB went open source, we faced the task of keeping a unified design system while also making it distinctive for different brands. To do this, we created a separate group of CSS variables. It includes brand colors, fonts, and border radii. In code, it looks like a small block:\\n\\n```json \\n.g-root {\\n --g-font-family-sans: 'Inter', sans-serif;\\n\\n --g-text-header-font-weight: 600;\\n --g-text-subheader-font-weight: 600;\\n --g-text-display-font-weight: 600;\\n --g-text-accent-font-weight: 600;\\n\\n --g-color-base-brand: rgb(117, 155, 255);\\n --g-color-base-brand-hover: rgb(99, 143, 255);\\n --g-color-base-selection: rgba(82, 130, 255, 0.05);\\n --g-color-base-selection-hover: rgba(82, 130, 255, 0.1);\\n --g-color-line-brand: rgb(117, 155, 255);\\n --g-color-text-brand: rgb(117, 155, 255);\\n --g-color-text-brand-contrast: rgb(255, 255 ,255);\\n --g-color-text-link: rgb(117, 155, 255);\\n --g-color-text-link-hover: rgb(82, 130, 255);\\n\\n --g-border-radius-xs: 3px;\\n --g-border-radius-s: 5px;\\n --g-border-radius-m: 6px;\\n --g-border-radius-l: 8px;\\n --g-border-radius-xl: 10px;\\n --g-border-radius-2xl: 16px;\\n}\\n```\\n\\nIn this group, you can replace the font, the color of accent buttons, and the rounding radii. This way, you can use a single design system for different brands while preserving each brand’s identity. If this option doesn’t work for you, you can create your own color scheme. There’s a detailed guide in the [documentation](https://preview.gravity-ui.com/uikit/?path=/docs/branding-overview--docs#additional-customization){target=\\\"_blank\\\"}.\\n\"\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: Example interfaces with different brand variables\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic6.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n It’s worth noting that changing brand colors won’t affect the core\n interface. This is especially important for elements that use semantic\n colors: for example, red will still mean an error, and green will\n still mean success.\n\n\n ### Components in Figma\n\n\n For convenience, our design team prepared and uploaded all component\n states to\n [Figma](https://www.figma.com/community/file/1271150067798118027){target=\"_blank\"}.\n If you want, you can make a copy of the library and try building an\n interface directly in the tool.\n\n\n With the latest update, the library no longer duplicates all four\n themes. By default, you work in the light theme, but in the Layer\n section you can switch any element — or the whole page — to another\n theme. \n - type: blog-media-block\n column: left\n resetPaddings: true\n text: How to preview an element in different themes\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic7.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n All library elements are presented on the Overview page. Here you can\n find the component you need and go to the page with all its states. In\n addition, each component has a usage example. \n - type: blog-media-block\n column: left\n resetPaddings: true\n paddingBottom: s\n text: \"A page with all Gravity\\_UI elements\"\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic8.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n ### Nearly 600 icons\n\n Icons are an essential part of design and usability. They help\n organize and structure content, set accents, and improve how\n information is perceived. At first glance, creating an icon pack\n doesn’t seem too hard. But we faced a challenge when creating icons\n for complex metaphors such as virtual machines, databases, and various\n chart types.\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: We currently have 594 icons, but there will be more soon\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic9.png\n fullscreen: true\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: >-\n Developing icons for a WYSIWYG content editor was also a special\n challenge — it’s being integrated in various places for text\n formatting\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic10.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n To make icon search more convenient, we used a special naming system.\n Now you can find the same icon by typing different names. For example,\n to find an arrow-like icon, you can type any of these words: arrow,\n enter, move, login.\n - type: blog-media-block\n column: left\n resetPaddings: true\n paddingBottom: s\n text: >-\n All icons are available on a [separate\n page](https://gravity-ui.com/icons). You can copy the SVG or download\n any icon\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic11.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n ### Guides\n\n\n As I wrote above, our goal was to make it easy for developers to build\n standard interfaces using component descriptions in our guide. We\n aimed to make this process simple, without the need to contact a\n designer for every single element. At the moment, we already have five\n examples of internal services that were fully built by developers\n using only the guides.\n\n\n Of course, you can’t solve this task with developers’ hands alone: in\n any case, there are complex scenarios that require the attention of a\n UX/UI specialist. Nevertheless, we managed to remove a significant\n portion of the load from our designers.\n\n\n In the guides, the design team described the components and provided\n recommendations on how to use them, showing examples of the right and\n wrong approach. You can view them on [this\n page](https://gravity-ui.com/components/uikit/alert){target=\"_blank\"}.\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2025/12/gravity-ui-in-opensource/pic12.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: \"\\n## How to use Gravity\\_UI{#use}\\n\\nAll you need to do is run the command in the terminal:\\n\\n```\\ngit clone git@github.com:gravity-ui/uikit-example-cra.git my-project && cd my-project\\nnpm i \\nnpm run start\\n```\\n\\nMore detailed instructions are available on the repository’s main page on [GitHub](https://github.com/gravity-ui/uikit){target=\\\"_blank\\\"}.\\n\\nYou can browse all Gravity\\_UI components in [UIkit](https://preview.gravity-ui.com/uikit/){target=\\\"_blank\\\"}, and connect the library you need for your use case in [Libraries](https://gravity-ui.com/libraries){target=\\\"_blank\\\"}. \\n\\n--------\\n\\nTo sum it up, I’d like to emphasize once again: Gravity\\_UI is a design system that grew out of the real experience of our users, developers’ needs, and designers’ expertise. This makes it practical and effective. And now anyone can use it for free.\\n\\nWe strive to make the project even better by taking into account our users’ needs and feedback. Visit us on GitHub, submit PRs, leave comments in Figma, and share examples of how you use it.\\n\"\n - type: blog-layout-block\n resetPaddings: true\n fullWidth: false\n children:\n - type: blog-meta-block\n column: left\n resetPaddings: true\n - type: blog-suggest-block\n resetPaddings: true\n",
"title": "",
"noIndex": false,
"shareTitle": null,
"shareDescription": null,
- "shareImage": "https://storage.yandexcloud.net/yandex-opensource/blog-cover-bg.png",
+ "shareImage": null,
"pageLocaleId": null,
- "author": "ngorin",
+ "author": "timofeyevvv",
"metaDescription": null,
"keywords": [],
"shareGenTitle": null,
"canonicalLink": null,
- "sharingType": "semi-full",
- "sharingTheme": "dark",
- "comment": "gravity",
- "shareImageUrl": "https://storage.cloud-preprod.yandex.net/ui-api-ru-preprod-stable-share-generator-screenshots/cache/8c45f347a6e585754d1d6e4949c9c5a20a2d570e.png",
- "pageRegionId": 73,
+ "sharingType": "auto",
+ "sharingTheme": "light",
+ "comment": "translation",
+ "shareImageUrl": "https://storage.cloud-preprod.yandex.net/ui-api-ru-preprod-stable-share-generator-screenshots/cache/6a79bcd295f4b97553c519c462935cc394f84cb8.png",
+ "pageRegionId": 74,
"summary": null,
- "versionId": 194,
+ "versionId": 201,
"service": null,
"solution": null,
"locales": [
@@ -54,20 +54,20 @@
}
],
"pageRegions": [
- {
- "regionCode": "en",
- "publishedVersionId": null
- },
{
"regionCode": "ru-ru",
"publishedVersionId": 194
+ },
+ {
+ "regionCode": "en",
+ "publishedVersionId": 201
}
],
"searchCategory": {
- "id": 7,
- "slug": "blog",
- "title": "Блог",
- "url": "/blog"
+ "id": 7,
+ "slug": "blog",
+ "title": "Blog",
+ "url": "/blog"
},
"voiceovers": []
- }
\ No newline at end of file
+}
diff --git a/src/api/.mocks/en/pages/md-editor-in-gravity-ui.json b/src/api/.mocks/en/pages/md-editor-in-gravity-ui.json
new file mode 100644
index 000000000000..5dfe4c249b2b
--- /dev/null
+++ b/src/api/.mocks/en/pages/md-editor-in-gravity-ui.json
@@ -0,0 +1,74 @@
+{
+ "id": 73,
+ "name": "blog/md-editor-in-gravity-ui",
+ "createdAt": "2026-01-15T12:37:10.557Z",
+ "updatedAt": "2026-01-15T12:37:10.557Z",
+ "type": "default",
+ "isDeleted": false,
+ "versionOnTranslationId": null,
+ "searchCategorySlug": "blog",
+ "regions": [],
+ "pageId": 73,
+ "regionCode": "en",
+ "publishedVersionId": 212,
+ "lastVersionId": 212,
+ "content": "blocks:\n - type: blog-header-block\n resetPaddings: true\n paddingBottom: l\n width: m\n verticalOffset: m\n theme: dark\n background:\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/blog-cover-bg.png\n disableCompress: true\n color: '#2A1A2A'\n fullWidth: false\n - type: blog-layout-block\n resetPaddings: true\n mobileOrder: reverse\n children:\n - type: blog-yfm-block\n resetPaddings: true\n column: right\n text: >\n\n \n\n\n **Sergey Makhnatkin**\n\n Frontend Developer\n - type: blog-yfm-block\n column: right\n resetPaddings: true\n text: \"\\nIn this article:\\n\\n - [Why we need our own Markdown Editor](#why)\\n - [Markdown Editor capabilities in Gravity\\_UI](#capabilities)\\n - [Architecture](#architecture)\\n - [Integration](#integration)\\n - [Integrating custom extensions](#extensions)\\n\"\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic1.png\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: \"\\n{% cut \\\"TL;DR\\\" %}\\n\\n* Lets you work simultaneously in [WYSIWYG](https://ru.wikipedia.org/wiki/WYSIWYG){target=\\\"_blank\\\"} and [markdown](https://en.wikipedia.org/wiki/Markdown){target=\\\"_blank\\\"} markup modes (with preview and split view).\\n* Supports a large number of blocks out of the box.\\n* Lets you extend functionality — there is an extension system in WYSIWYG mode.\\n* Built for use in React applications.\\n* Uses theming and components from [Gravity\\_UI](https://gravity-ui.com/){target=\\\"_blank\\\"}.\\n* Fully built on open-source technologies ([ProseMirror](https://prosemirror.net/){target=\\\"_blank\\\"}, [CodeMirror](https://codemirror.net/){target=\\\"_blank\\\"}, [markdown-it](https://github.com/markdown-it/markdown-it){target=\\\"_blank\\\"}, [Diplodoc](https://diplodoc.com/){target=\\\"_blank\\\"}, [Gravity\\_UI](https://gravity-ui.com/){target=\\\"_blank\\\"}).\\n* Complies with the [CommonMark](https://spec.commonmark.org/){target=\\\"_blank\\\"} standard, supports standard markdown and [Yandex Flavored Markdown (YFM)](https://diplodoc.com/docs/ru/index-yfm){target=\\\"_blank\\\"}.\\n\\n{% endcut %}\\n\\nHi! My name is Sergey Makhnatkin, and I work as a developer in the User Experience team at Yandex\\_Cloud. Last year, we wrote about our [Gravity\\_UI design system and component library](https://habr.com/ru/companies/yandex/articles/773870/){target=\\\"_blank\\\"}. Since then, the system has been updated multiple times and expanded with new features, and today I want to talk about a new tool — Markdown Editor — which significantly simplifies working with documentation.\\n\\nWe’ll talk about the history of building the user interface, architectural features, and technical details of integration and developing custom extensions — and, of course, why all of this is available as open source.\\n\\nBy the way, you can try the tool here:\\n\\n * [Demo](https://gravity-ui.com/libraries/markdown-editor/playground){target=\\\"_blank\\\"} \\n * [GitHub](https://github.com/gravity-ui/markdown-editor/){target=\\\"_blank\\\"} \\n * [Storybook](https://preview.gravity-ui.com/md-editor/){target=\\\"_blank\\\"}\\n\"\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n ## Why we need our own Markdown Editor{#why}\n\n\n To make it convenient to store and structure corporate information, we\n built the [Wiki](https://wiki.yandex.ru/){target=\"_blank\"} platform,\n which allows creating knowledge bases. Alongside the knowledge base,\n we developed documentation approaches such as Docs as Code, where\n documentation and code live side by side in a file repository (.md\n files). This is how the\n [Diplodoc](https://diplodoc.com/){target=\"_blank\"} platform emerged.\n\n\n What Wiki and Diplodoc have in common is that both platforms work with\n a markdown dialect — Yandex Flavored Markdown (YFM) — which is used at\n Nebius, Bitrix, DoubleCloud, Mappable, and Meteum.\n\n\n Over time, we noticed there are two groups of users who think about\n creating and editing text differently. Some prefer to see the final\n result right away, working with text like in MS Word, Confluence, or\n Notion. Others trust only markup and prefer to format pages using\n markdown. We couldn’t find any well-known libraries that work in both\n WYSIWYG and markdown modes at the same time. For example, Notion is\n WYSIWYG only, while code editors usually provide only markdown and\n preview mode.\n\n\n We developed a markdown editor that can work in two modes\n simultaneously: a visual mode (WYSIWYG) and a markup mode (markdown).\n In the first mode, toolbar icons help format the text; in the second,\n users can manually edit the markdown source. In addition, our solution\n stores the document as an .md file regardless of which mode was used\n to create it.\n\n\n This is what the visual editor looks like, where you can format text\n using buttons:\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic2.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n And this is the markup mode, where formatting elements are indicated\n using special characters:\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic3.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: \"\\n## Markdown Editor capabilities in Gravity\\_UI{#capabilities}\\n\\nThe editor complies with the CommonMark standard and supports both standard markdown and YFM. We also added the ability to extend the syntax with other markdown dialects, such as GitHub Flavored Markdown. At the same time, the editor lets you switch from markup mode to WYSIWYG mode, while the document itself is stored as md markup or extended md (for example, in the case of YFM).\\n\\n### Extensions\\n\\nThe editor comes with many built-in extensions and settings. For example, Mermaid diagrams and HTML blocks:\\n\"\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic4.png\n fullscreen: true\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic5.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n We tried to make the editor core easy to extend. Developers can create\n their own extension or add extra functionality to:\n\n * add new entities — blocks or text modifiers;\n * further configure the markdown parser;\n * add actions that allow controlling the editor from the outside;\n * enrich UI functionality — for example, show a list of available commands when typing a slash;\n * modify current behavior — for example, insert images and files and upload them to storage.\n\n Here are some examples of such extensions we built for our Wiki:\n\n * collaborative editing mode;\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic6.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: |\n\n * a [draw.io](http://draw.io/){target=\"_blank\"} diagrams block;\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic7.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: |\n\n * a [YandexGPT](https://ya.ru/ai/gpt-3){target=\"_blank\"} plugin;\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic8.png\n fullscreen: true\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic9.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: |\n\n * includes;\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic10.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: |\n\n * section structure;\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic11.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: |\n\n * sections for creating a convenient grid;\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic12.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: |\n\n * markdown mode with preview;\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic13.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: |\n\n * and many more.\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic14.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n Markup can be transformed automatically. If you prefer working without\n a mouse, the visual editor mode supports special characters that let\n you apply markup directly in the text. For example, `**` turns text\n bold in WYSIWYG mode. With these characters, you can format text and\n create inline and block code.\n\n\n You can also open the extensions menu by typing `/`.\n - type: blog-media-block\n column: left\n resetPaddings: true\n paddingBottom: s\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic15.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n ### Presets\n\n\n The editor lets you configure the toolbar for each project\n individually, but it ships with a set of ready-made configurations —\n presets.\n\n\n The editor without presets:\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic16.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n The [CommonMark\n preset](https://preview.gravity-ui.com/md-editor/?path=/story/markdown-editor-presets--common-mark){target=\"_blank\"}\n provides support for standard markdown elements: bold, italic,\n headings, lists, links, quotes, and code blocks.\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic17.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n In the [default\n preset](https://preview.gravity-ui.com/md-editor/?path=/story/markdown-editor-presets--default){target=\"_blank\"},\n you also get strikethrough text, plus a table where only text can be\n placed in cells. This preset corresponds to standard markdown-it.\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic18.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n As mentioned above, the editor also supports YFM, so it integrates\n great with Diplodoc. In the [YFM\n preset](https://preview.gravity-ui.com/md-editor/?path=/story/markdown-editor-presets--yfm){target=\"_blank\"},\n additional elements appear: advanced tables, file and image insertion,\n checkboxes, cut, tabs, and monospace font.\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic19.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n The [full\n preset](https://preview.gravity-ui.com/md-editor/?path=/story/markdown-editor-presets--full){target=\"_blank\"}\n includes even more elements.\n - type: blog-media-block\n column: left\n resetPaddings: true\n text: ''\n image:\n src: >-\n https://storage.yandexcloud.net/gravity-landing-static/blog/md-editor-in-gravity-ui/pic20.png\n fullscreen: true\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n ## Architecture{#architecture}\n\n\n The editor’s WYSIWYG mode is built on the well-known\n [ProseMirror](http://prosemirror.net/){target=\"_blank\"} library, while\n markup mode uses\n [CodeMirror](https://codemirror.net/){target=\"_blank\"}. ProseMirror\n supports editing with formatting, whereas CodeMirror is better suited\n for situations where you need to work with raw text.\n\n\n We chose these libraries because they were created by the same author,\n are consistent in architecture and implementation approaches, are\n backed by a large community, are used in many editors, and are well\n optimized for working with text. For example, the transaction system\n for applying changes to the document, view decorations, DOM\n virtualization, and support for the syntax of many programming\n languages.\n - type: blog-yfm-block\n column: left\n resetPaddings: true\n text: >\n\n ## Integration{#integration}\n\n\n Our editor is easy to connect as a [React\n hook](https://github.com/gravity-ui/markdown-editor/blob/main/docs/how-to-add-editor-with-create-react-app.md){target=\"_blank\"}:\n\n\n ```javascript\n\n\n import React from 'react';\n\n import {useMarkdownEditor, MarkdownEditorView} from\n '@gravity-ui/markdown-editor';\n\n import {toaster} from '@gravity-ui/uikit/toaster-singleton-react-18';\n\n\n function Editor({onSubmit}) {\n const editor = useMarkdownEditor({allowHTML: false});\n\n React.useEffect(() => {\n function submitHandler() {\n // Serialize current content to markdown markup\n const value = editor.getValue();\n onSubmit(value);\n }\n\n editor.on('submit', submitHandler);\n return () => {\n editor.off('submit', submitHandler);\n };\n }, [onSubmit]);\n\n return